Browse Source

#62365 - SVG image support in XSLF

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849030 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_4_1_0
Andreas Beeker 5 years ago
parent
commit
d45ec541cd

+ 6
- 1
build.gradle View File

@@ -91,7 +91,7 @@ subprojects {
// See https://github.com/melix/japicmp-gradle-plugin
apply plugin: 'me.champeau.gradle.japicmp'
version = '4.0.1-SNAPSHOT'
version = '4.0.2-SNAPSHOT'
ext {
japicmpversion = '4.0.0'
}
@@ -233,6 +233,11 @@ project('ooxml') {
compile 'org.bouncycastle:bcpkix-jdk15on:1.60'
compile 'com.github.virtuald:curvesapi:1.05'

// compile only, don't add it to our dist as it blows up the size
compile 'org.apache.xmlgraphics:batik-all:1.10'
compile 'xml-apis:xml-apis-ext:1.3.04'
compile 'org.apache.xmlgraphics:xmlgraphics-commons:2.3'

// for ooxml-lite, should we move this somewhere else?
compile 'junit:junit:4.12'


+ 24
- 1
build.xml View File

@@ -217,6 +217,14 @@ under the License.
<property name="dsig.sl4j-api.jar" location="${compile.lib}/slf4j-api-1.7.25.jar"/>
<property name="dsig.sl4j-api.url" value="${repository.m2}/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar"/>

<!-- svg/batik libs - not part of the distribution -->
<property name="svg.batik-all.url" value="${repository.m2}/maven2/org/apache/xmlgraphics/batik-all/1.10/batik-all-1.10.jar"/>
<property name="svg.batik-all.jar" value="${compile.lib}/batik-all-1.10.jar"/>
<property name="svg.xml-apis-ext.url" value="${repository.m2}/maven2/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04.jar"/>
<property name="svg.xml-apis-ext.jar" value="${compile.lib}/xml-apis-ext-1.3.04.jar"/>
<property name="svg.xmlgraphics-commons.url" value="${repository.m2}/maven2/org/apache/xmlgraphics/xmlgraphics-commons/2.3/xmlgraphics-commons-2.3.jar"/>
<property name="svg.xmlgraphics-commons.jar" value="${compile.lib}/xmlgraphics-commons-2.3.jar"/>

<!-- jars in the ooxml-lib directory, see the fetch-ooxml-jars target-->
<property name="ooxml.curvesapi.jar" location="${ooxml.lib}/curvesapi-1.05.jar"/>
<property name="ooxml.curvesapi.url"
@@ -395,6 +403,12 @@ under the License.
<pathelement location="${scratchpad.output.dir}" unless:true="${scratchpad.ignore}"/>
</path>

<path id="batik.classpath">
<pathelement location="${svg.batik-all.jar}"/>
<pathelement location="${svg.xml-apis-ext.jar}"/>
<pathelement location="${svg.xmlgraphics-commons.jar}"/>
</path>

<path id="ooxml-lite.classpath">
<path refid="ooxml.base.classpath"/>
<!-- instead of ooxml-xsds.jar use the filtered classes-->
@@ -402,11 +416,13 @@ under the License.
<pathelement location="${ooxml.output.dir}"/>
<pathelement location="${ooxml.output.test.dir}"/>
<pathelement location="${main.output.test.dir}"/>
<path refid="batik.classpath"/>
</path>

<path id="ooxml.classpath">
<pathelement location="${ooxml.xsds.jar}"/>
<path refid="ooxml.base.classpath"/>
<path refid="batik.classpath"/>
</path>

<path id="ooxml.lite.verify.classpath">
@@ -777,6 +793,9 @@ under the License.
<available file="${ooxml.test.reflections.jar}"/>
<available file="${ooxml.test.guava.jar}"/>
<available file="${ooxml.test.javassist.jar}"/>
<available file="${svg.xml-apis-ext.jar}"/>
<available file="${svg.batik-all.jar}"/>
<available file="${svg.xmlgraphics-commons.jar}"/>
</and>
<isset property="disconnected"/>
</or>
@@ -791,6 +810,9 @@ under the License.
<downloadfile src="${ooxml.test.reflections.url}" dest="${ooxml.test.reflections.jar}"/>
<downloadfile src="${ooxml.test.guava.url}" dest="${ooxml.test.guava.jar}"/>
<downloadfile src="${ooxml.test.javassist.url}" dest="${ooxml.test.javassist.jar}"/>
<downloadfile src="${svg.batik-all.url}" dest="${svg.batik-all.jar}"/>
<downloadfile src="${svg.xml-apis-ext.url}" dest="${svg.xml-apis-ext.jar}"/>
<downloadfile src="${svg.xmlgraphics-commons.url}" dest="${svg.xmlgraphics-commons.jar}"/>
</target>
<target name="check-svn-jars">
<condition property="svn.jars.present">
@@ -932,6 +954,7 @@ under the License.
</xmlbean>

<local name="loaderMethod"/>
<!-- the space between "public static" is on purpose to prevent double execution -->
<property name="loaderMethod"><![CDATA[
private static java.lang.ref.SoftReference<org.apache.xmlbeans.SchemaTypeLoader> typeLoader;

@@ -944,7 +967,7 @@ under the License.
return stl;
}

public static \2 newInstance\(\) \{]]></property>
public static \2 newInstance\(\) \{]]></property>

<replaceregexp byline="true" match="(\s*)public static ([^ ]+) newInstance\(\) \{" replace="${loaderMethod}">
<fileset dir="${xmlbean.sources.dir}" includes="**/*.java" excludes="**/impl/**"/>

+ 7
- 0
sonar/ooxml/pom.xml View File

@@ -185,5 +185,12 @@
<version>1.19</version>
<scope>test</scope>
</dependency>

<dependency>
<!-- don't add it to the distribution -->
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>1.10</version>
</dependency>
</dependencies>
</project>

+ 9
- 10
sonar/pom.xml View File

@@ -268,9 +268,7 @@
</goals>
<configuration>
<target>
<property name="xmlbean.sources.dir"
location="${basedir}/target/generated-sources/xmlbeans"/>

<!-- the space between "public static" is on purpose to prevent double execution -->
<property name="loaderMethod"><![CDATA[
private static java.lang.ref.SoftReference<org.apache.xmlbeans.SchemaTypeLoader> typeLoader;

@@ -283,25 +281,26 @@
return stl;
}

public static \2 newInstance\(\) \{]]></property>
public static \2 newInstance\(\) \{]]></property>

<fileset id="xsrc" dir="${basedir}/target/generated-sources/xmlbeans" includes="**/*.java" excludes="**/impl/**"/>

<replaceregexp byline="true"
match="(\s*)public static ([^ ]+) newInstance\(\) \{"
replace="${loaderMethod}">
<fileset dir="${xmlbean.sources.dir}" includes="**/*.java"
excludes="**/impl/**"/>
<fileset refid="xsrc"/>
</replaceregexp>

<replace dir="${xmlbean.sources.dir}" includes="**/*.java"
excludes="**/impl/**">
<replace>
<fileset refid="xsrc"/>
<replacetoken>org.apache.xmlbeans.XmlBeans.getContextTypeLoader
</replacetoken>
<replacevalue>getTypeLoader</replacevalue>
</replace>

<!-- remove deprecated warnings, as we prefer the array methods - see #56854 -->
<replace dir="${xmlbean.sources.dir}" includes="**/*.java"
excludes="**/impl/**">
<replace>
<fileset refid="xsrc"/>
<replacetoken><![CDATA[ * @deprecated
]]></replacetoken>
</replace>

+ 4
- 1
src/java/org/apache/poi/sl/usermodel/PictureData.java View File

@@ -46,7 +46,10 @@ public interface PictureData {
/** WordPerfect graphics (.wpg) */
WPG(-1,12,"image/x-wpg",".wpg"),
/** Microsoft Windows Media Photo image (.wdp) */
WDP(-1,13,"image/vnd.ms-photo",".wdp");
WDP(-1,13,"image/vnd.ms-photo",".wdp"),
/** Scalable vector graphics (.svg) - supported by Office 2016 and higher */
SVG(-1, -1, "image/svg+xml", ".svg")
;
public final int nativeId, ooxmlId;
public final String contentType,extension;

+ 136
- 0
src/ooxml/java/org/apache/poi/xslf/draw/SVGImageRenderer.java View File

@@ -0,0 +1,136 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */

package org.apache.poi.xslf.draw;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.ext.awt.RenderingHintsKeyExt;
import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.util.XMLResourceDescriptor;
import org.apache.poi.sl.draw.ImageRenderer;
import org.w3c.dom.Document;

public class SVGImageRenderer implements ImageRenderer {
private final GVTBuilder builder = new GVTBuilder();
private final BridgeContext context;
private final SAXSVGDocumentFactory svgFact;
private GraphicsNode svgRoot;
private double alpha = 1.0;

public SVGImageRenderer() {
String parser = XMLResourceDescriptor.getXMLParserClassName();
// TOOO: tell the batik guys to use secure parsing feature
svgFact = new SAXSVGDocumentFactory(parser);

UserAgent agent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(agent);
context = new BridgeContext(agent, loader);
context.setDynamic(true);
}


@Override
public void loadImage(InputStream data, String contentType) throws IOException {
Document document = svgFact.createDocument("", data);
svgRoot = builder.build(context, document);
}

@Override
public void loadImage(byte[] data, String contentType) throws IOException {
loadImage(new ByteArrayInputStream(data), contentType);
}

@Override
public Dimension getDimension() {
Rectangle2D r = svgRoot.getPrimitiveBounds();
return new Dimension((int)Math.ceil(r.getWidth()), (int)Math.ceil(r.getHeight()));
}

@Override
public void setAlpha(double alpha) {
this.alpha = alpha;
}

@Override
public BufferedImage getImage() {
return getImage(getDimension());
}

@Override
public BufferedImage getImage(Dimension dim) {
BufferedImage bi = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) bi.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHintsKeyExt.KEY_BUFFERED_IMAGE, new WeakReference(bi));
Dimension dimSVG = getDimension();

double scaleX = dim.getWidth() / dimSVG.getWidth();
double scaleY = dim.getHeight() / dimSVG.getHeight();
g2d.scale(scaleX, scaleY);

svgRoot.paint(g2d);
g2d.dispose();

return bi;
}

@Override
public boolean drawImage(Graphics2D graphics, Rectangle2D anchor) {
return drawImage(graphics, anchor, null);
}

@Override
public boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip) {
if (clip == null) {
svgRoot.setClip(null);
} else {
Rectangle2D clippedRect = new Rectangle2D.Double(
anchor.getX()+clip.left,
anchor.getY()+clip.top,
anchor.getWidth()-(clip.left+clip.right),
anchor.getHeight()-(clip.top+clip.bottom)
);
svgRoot.setClip(new ClipRable8Bit(null, clippedRect));
}

svgRoot.paint(graphics);

return true;
}
}

+ 3
- 0
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java View File

@@ -218,6 +218,8 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
return PictureType.WDP;
} else if (XSLFRelation.IMAGE_TIFF.getContentType().equals(ct)) {
return PictureType.TIFF;
} else if (XSLFRelation.IMAGE_SVG.getContentType().equals(ct)) {
return PictureType.SVG;
} else {
return null;
}
@@ -237,6 +239,7 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
case WPG: return XSLFRelation.IMAGE_WPG;
case WDP: return XSLFRelation.IMAGE_WDP;
case TIFF: return XSLFRelation.IMAGE_TIFF;
case SVG: return XSLFRelation.IMAGE_SVG;
default: return null;
}
}

+ 111
- 3
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java View File

@@ -19,18 +19,31 @@

package org.apache.poi.xslf.usermodel;

import static org.apache.poi.openxml4j.opc.PackageRelationshipTypes.CORE_PROPERTIES_ECMA376_NS;

import java.awt.Dimension;
import java.awt.Insets;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;

import javax.imageio.ImageIO;
import javax.xml.namespace.QName;

import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.PictureShape;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
import org.apache.poi.xslf.draw.SVGImageRenderer;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
@@ -55,6 +68,11 @@ public class XSLFPictureShape extends XSLFSimpleShape
implements PictureShape<XSLFShape,XSLFTextParagraph> {
private static final POILogger LOG = POILogFactory.getLogger(XSLFPictureShape.class);

private static final String DML_NS = "http://schemas.microsoft.com/office/drawing/2010/main";
private static final String SVG_NS = "http://schemas.microsoft.com/office/drawing/2016/SVG/main";
private static final String BITMAP_URI = "{28A0092B-C50C-407E-A947-70E740481C1C}";
private static final String SVG_URI = "{96DAC541-7B7A-43D3-8B79-37D633B846F1}";

private XSLFPictureData _data;

/*package*/ XSLFPictureShape(CTPicture shape, XSLFSheet sheet) {
@@ -196,6 +214,97 @@ public class XSLFPictureShape extends XSLFSimpleShape
return (r == null) ? null : new Insets(r.getT(), r.getL(), r.getB(), r.getR());
}

/**
* Add a SVG image reference
* @param svgPic a previously imported svg image
*/
public void setSvgImage(XSLFPictureData svgPic) {
CTBlip blip = getBlip();
CTOfficeArtExtensionList extLst = blip.isSetExtLst() ? blip.getExtLst() : blip.addNewExtLst();

final int bitmapId = getExt(extLst, BITMAP_URI);
CTOfficeArtExtension extBitmap;
if (bitmapId == -1) {
extBitmap = extLst.addNewExt();
extBitmap.setUri(BITMAP_URI);
XmlCursor cur = extBitmap.newCursor();
cur.toEndToken();
cur.beginElement(new QName(DML_NS, "useLocalDpi", "a14"));
cur.insertNamespace("a14", DML_NS);
cur.insertAttributeWithValue("val", "0");
cur.dispose();
}

final int svgId = getExt(extLst, SVG_URI);;
if (svgId != -1) {
extLst.removeExt(svgId);
}

String svgRelId = getSheet().getRelationId(svgPic);
if (svgRelId == null) {
svgRelId = getSheet().addRelation(null, XSLFRelation.IMAGE_SVG, svgPic).getRelationship().getId();
}

CTOfficeArtExtension svgBitmap = extLst.addNewExt();
svgBitmap.setUri(SVG_URI);
XmlCursor cur = svgBitmap.newCursor();
cur.toEndToken();
cur.beginElement(new QName(SVG_NS, "svgBlip", "asvg"));
cur.insertNamespace("asvg", SVG_NS);
cur.insertAttributeWithValue(new QName(CORE_PROPERTIES_ECMA376_NS, "embed", "rel"), svgRelId);
cur.dispose();
}

/**
* Convienence method for adding SVG images, which generates the preview image
* @param sheet the sheet to add
* @param svgPic the svg picture to add
* @param previewType the preview picture type or null (defaults to PNG) - currently only JPEG,GIF,PNG are allowed
* @param anchor the image anchor (for calculating the preview image size) or
* null (the preview size is taken from the svg picture bounds)
*/
public static XSLFPictureShape addSvgImage(XSLFSheet sheet, XSLFPictureData svgPic, PictureType previewType, Rectangle2D anchor) throws IOException {

SVGImageRenderer renderer = new SVGImageRenderer();
try (InputStream is = svgPic.getInputStream()) {
renderer.loadImage(is, svgPic.getType().contentType);
}

Dimension dim = renderer.getDimension();
Rectangle2D anc = (anchor != null) ? anchor
: new Rectangle2D.Double(0,0, Units.pixelToPoints((int)dim.getWidth()), Units.pixelToPoints((int)dim.getHeight()));

PictureType pt = (previewType != null) ? previewType : PictureType.PNG;
if (pt != PictureType.JPEG || pt != PictureType.GIF || pt != PictureType.PNG) {
pt = PictureType.PNG;
}

BufferedImage thmBI = renderer.getImage(dim);
ByteArrayOutputStream bos = new ByteArrayOutputStream(100000);
// use extension instead of enum name, because of "jpeg"
ImageIO.write(thmBI, pt.extension.substring(1), bos);

XSLFPictureData pngPic = sheet.getSlideShow().addPicture(new ByteArrayInputStream(bos.toByteArray()), pt);

XSLFPictureShape shape = sheet.createPicture(pngPic);
shape.setAnchor(anc);
shape.setSvgImage(svgPic);
return shape;
}


private int getExt(CTOfficeArtExtensionList extLst, String uri) {
final int size = extLst.sizeOfExtArray();
for (int i=0; i<size; i++) {
CTOfficeArtExtension ext = extLst.getExtArray(i);
if (uri.equals(ext.getUri())) {
return i;
}
}
return -1;
}


@Override
void copy(XSLFShape sh){
super.copy(sh);
@@ -219,11 +328,11 @@ public class XSLFPictureShape extends XSLFSimpleShape
nvPr.unsetCustDataLst();
}
if(blip.isSetExtLst()) {
// TODO: check for SVG copying
CTOfficeArtExtensionList extLst = blip.getExtLst();
//noinspection deprecation
for(CTOfficeArtExtension ext : extLst.getExtArray()){
String xpath = "declare namespace a14='http://schemas.microsoft.com/office/drawing/2010/main' $this//a14:imgProps/a14:imgLayer";
String xpath = "declare namespace a14='"+ DML_NS +"' $this//a14:imgProps/a14:imgLayer";
XmlObject[] obj = ext.selectPath(xpath);
if(obj != null && obj.length == 1){
XmlCursor c = obj[0].newCursor();
@@ -234,6 +343,5 @@ public class XSLFPictureShape extends XSLFSimpleShape
}
}
}

}
}

+ 22
- 13
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java View File

@@ -16,6 +16,8 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;

import static org.apache.poi.openxml4j.opc.PackageRelationshipTypes.IMAGE_PART;

import java.util.HashMap;
import java.util.Map;

@@ -159,80 +161,87 @@ public final class XSLFRelation extends POIXMLRelation {

public static final XSLFRelation IMAGE_EMF = new XSLFRelation(
PictureType.EMF.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.emf",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_WMF = new XSLFRelation(
PictureType.WMF.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.wmf",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_PICT = new XSLFRelation(
PictureType.PICT.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.pict",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_JPEG = new XSLFRelation(
PictureType.JPEG.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.jpeg",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_PNG = new XSLFRelation(
PictureType.PNG.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.png",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_DIB = new XSLFRelation(
PictureType.DIB.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.dib",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_GIF = new XSLFRelation(
PictureType.GIF.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.gif",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_TIFF = new XSLFRelation(
PictureType.TIFF.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.tiff",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_EPS = new XSLFRelation(
PictureType.EPS.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.eps",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_BMP = new XSLFRelation(
PictureType.BMP.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.bmp",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_WPG = new XSLFRelation(
PictureType.WPG.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.wpg",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_WDP = new XSLFRelation(
PictureType.WDP.contentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
"/ppt/media/image#.wdp",
XSLFPictureData.class
);

public static final XSLFRelation IMAGE_SVG = new XSLFRelation(
PictureType.SVG.contentType,
IMAGE_PART,
"/ppt/media/image#.svg",
XSLFPictureData.class
);

public static final XSLFRelation IMAGES = new XSLFRelation(
null,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
IMAGE_PART,
null,
XSLFPictureData.class
);

+ 23
- 0
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java View File

@@ -16,14 +16,17 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;

import static org.apache.poi.POIDataSamples.TEST_PROPERTY;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.awt.geom.Rectangle2D;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@@ -247,4 +250,24 @@ public class TestXSLFPictureShape {
slideShow.close();
}


@Test
public void renderSvgImage() throws Exception {
String dataDirName = System.getProperty(TEST_PROPERTY);
final String SVG_FILE = (dataDirName != null ? "../" : "") + "src/documentation/resources/images/project-header.svg";
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();

XSLFPictureData svgPic = ppt.addPicture(new File(dataDirName, SVG_FILE), PictureType.SVG);
XSLFPictureShape shape = XSLFPictureShape.addSvgImage(slide, svgPic, PictureType.JPEG, null);

Rectangle2D anchor = shape.getAnchor();
anchor.setRect(100, 100, anchor.getWidth(), anchor.getHeight());
shape.setAnchor(anchor);

// try (FileOutputStream fos = new FileOutputStream("svgtest.pptx")) {
// ppt.write(fos);
// }
}
}

Loading…
Cancel
Save