mirror of https://github.com/apache/poi.git
#62365 - SVG image support in XSLF
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849030 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2a84c1fa16
commit
d45ec541cd
|
@ -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'
|
||||
|
||||
|
|
25
build.xml
25
build.xml
|
@ -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/**"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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…
Reference in New Issue