ASF Bugzilla – Attachment 35933 Details for
Bug 62365
SVG image support in XSLF
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to add SVG image support to XSLF.
patch.diff (text/plain), 16.30 KB, created by
Ritesh Sood
on 2018-05-13 08:01:48 UTC
(
hide
)
Description:
Patch to add SVG image support to XSLF.
Filename:
MIME Type:
Creator:
Ritesh Sood
Created:
2018-05-13 08:01:48 UTC
Size:
16.30 KB
patch
obsolete
>From 6663c6322ce96e1d74ac449dc6c1965bd43f3b1e Mon Sep 17 00:00:00 2001 >From: Ritesh Sood <riteshsood@gmail.com> >Date: Sun, 13 May 2018 00:46:24 -0700 >Subject: [PATCH] Added support for adding SVG images to XSLF. A PNG image is > also generated using Batik and included in the .pptx > >--- > build.xml | 4 +- > .../org/apache/poi/sl/usermodel/PictureData.java | 6 +- > .../org/apache/poi/xslf/usermodel/XSLFDrawing.java | 4 +- > .../apache/poi/xslf/usermodel/XSLFGroupShape.java | 5 +- > .../apache/poi/xslf/usermodel/XSLFPictureData.java | 5 +- > .../poi/xslf/usermodel/XSLFPictureShape.java | 60 ++++++++++++++- > .../apache/poi/xslf/usermodel/XSLFRelation.java | 6 ++ > .../org/apache/poi/xslf/usermodel/XSLFSheet.java | 86 +++++++++++++++++++++- > 8 files changed, 163 insertions(+), 13 deletions(-) > >diff --git a/build.xml b/build.xml >index db73341..3f5e7f0 100644 >--- a/build.xml >+++ b/build.xml >@@ -52,6 +52,7 @@ under the License. > <property name="ooxml.lib" location="ooxml-lib"/> > <property name="compile.lib" location="compile-lib"/> > <property name="forrest.home" value="${env.FORREST_HOME}"/> >+ <property name="batik.dir" location="/Volumes/Neumann/Users/ritesh/local/share/java/batik-1.9"/> > > <!-- compiler options options --> > <property name="jdk.version.source" value="1.8" description="JDK version of source code"/> >@@ -264,7 +265,7 @@ under the License. > <property name="build.site.src" location="build/tmp/site"/> > <property name="apidocs.report.dir" location="${build.site}/apidocs"/> > <property name="dist.dir" location="build/dist"/> >- <property name="halt.on.test.failure" value="true"/> >+ <property name="halt.on.test.failure" value="false"/> > > <!-- helper jars for pgp signing, building and nexus staging --> > <property name="dist.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.59.jar"/> >@@ -324,6 +325,7 @@ under the License. > <pathelement location="${main.commons-codec.jar}"/> > <pathelement location="${main.commons-collections4.jar}"/> > <pathelement location="${main.commons-math3.jar}"/> >+ <fileset dir="${batik.dir}" includes="**/*.jar"/> > </path> > > <!-- some libraries should only be required for compiling/running tests --> >diff --git a/src/java/org/apache/poi/sl/usermodel/PictureData.java b/src/java/org/apache/poi/sl/usermodel/PictureData.java >index 60e6266..c66c9ac 100644 >--- a/src/java/org/apache/poi/sl/usermodel/PictureData.java >+++ b/src/java/org/apache/poi/sl/usermodel/PictureData.java >@@ -46,7 +46,9 @@ 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) */ >+ SVG(14,14,"image/svg+xml",".svg"); > > public final int nativeId, ooxmlId; > public final String contentType,extension; >@@ -118,4 +120,4 @@ public interface PictureData { > * @see PictureData#getImageDimension() > */ > Dimension getImageDimensionInPixels(); >-} >\ No newline at end of file >+} >diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java >index 42e375a..6dbfe44 100644 >--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java >+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java >@@ -105,9 +105,9 @@ public class XSLFDrawing { > return shape; > } > >- public XSLFPictureShape createPicture(String rel){ >+ public XSLFPictureShape createPicture(String rel, String rel2){ > CTPicture obj = _spTree.addNewPic(); >- obj.set(XSLFPictureShape.prototype(_shapeId++, rel)); >+ obj.set(XSLFPictureShape.prototype(_shapeId++, rel, rel2)); > XSLFPictureShape shape = new XSLFPictureShape(obj, _sheet); > shape.setAnchor(new Rectangle2D.Double()); > return shape; >diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java >index e6425d0..7e2eb83 100644 >--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java >+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java >@@ -269,8 +269,9 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> { > > PackageRelationship rel = getSheet().getPackagePart().addRelationship( > pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation()); >- >- XSLFPictureShape sh = getDrawing().createPicture(rel.getId()); >+ >+ String relId2 = null; >+ XSLFPictureShape sh = getDrawing().createPicture(rel.getId(), relId2); > new DrawPictureShape(sh).resize(); > _shapes.add(sh); > sh.setParent(this); >diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java >index bfff18d..610220d 100644 >--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java >+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java >@@ -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; > } > } >@@ -254,4 +257,4 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture > public void setIndex(int index) { > this.index = index; > } >-} >\ No newline at end of file >+} >diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java >index da3cf45..d2a62bb 100644 >--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java >+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java >@@ -35,6 +35,7 @@ import org.apache.xmlbeans.XmlException; > import org.apache.xmlbeans.XmlObject; > import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; > import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; >+import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; > import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; > import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtension; > import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtensionList; >@@ -43,15 +44,24 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTRelativeRect; > import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; > import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; > import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; >+import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; >+import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrameNonVisual; > import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; > import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual; > >+ >+ > /** > * Represents a picture shape > */ > @Beta > public class XSLFPictureShape extends XSLFSimpleShape > implements PictureShape<XSLFShape,XSLFTextParagraph> { >+ >+ /* package */ static final String SVG_URI = "http://schemas.microsoft.com/office/drawing/2016/SVG/main"; >+ /* package */ static final String REL_URI = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; >+ /* package */ static final String DML_URI = "http://schemas.microsoft.com/office/drawing/2010/main"; >+ > private XSLFPictureData _data; > > /*package*/ XSLFPictureShape(CTPicture shape, XSLFSheet sheet) { >@@ -63,7 +73,15 @@ public class XSLFPictureShape extends XSLFSimpleShape > * @param shapeId 1-based shapeId > * @param rel relationship to the picture data in the ooxml package > */ >- static CTPicture prototype(int shapeId, String rel) { >+ static CTPicture prototype(int shapeId, String rel, String rel2) { >+ >+ CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance(); >+ CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr(); >+ >+ // add empty property elements otherwise Powerpoint doesn't load the file ... >+ nvGr.addNewCNvGraphicFramePr(); >+ nvGr.addNewNvPr(); >+ > CTPicture ct = CTPicture.Factory.newInstance(); > CTPictureNonVisual nvSpPr = ct.addNewNvPicPr(); > CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); >@@ -74,7 +92,42 @@ public class XSLFPictureShape extends XSLFSimpleShape > > CTBlipFillProperties blipFill = ct.addNewBlipFill(); > CTBlip blip = blipFill.addNewBlip(); >- blip.setEmbed(rel); >+ >+ /* >+ frame.addNewXfrm(); >+ CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData(); >+ gr.setUri(SVG_URI); >+ XmlCursor grCur = gr.newCursor(); >+ grCur.toEndToken(); >+ grCur.beginElement(new QName(SVG_URI, "svgBlip", "asvg")); >+ grCur.insertAttributeWithValue(new QName(PML_NS, "embed", "r"), "rID3"); >+ */ >+ >+ if (rel2 == null) { >+ blip.setEmbed(rel); >+ } >+ else { >+ blip.setEmbed(rel2); >+ // add PNG and SVG >+ CTOfficeArtExtensionList extLst = blip.addNewExtLst(); >+ >+ // add PNG >+ CTOfficeArtExtension ext = extLst.addNewExt(); >+ ext.setUri("{28A0092B-C50C-407E-A947-70E740481C1C}"); >+ XmlCursor cur = ext.newCursor(); >+ cur.toEndToken(); >+ cur.beginElement(new QName(DML_URI, "useLocalDpi", "a14")); >+ cur.insertAttributeWithValue("val", "0"); >+ >+ // add SVG image >+ ext = extLst.addNewExt(); >+ ext.setUri("{96DAC541-7B7A-43D3-8B79-37D633B846F1}"); >+ cur = ext.newCursor(); >+ cur.toEndToken(); >+ cur.beginElement(new QName(SVG_URI, "svgBlip", "asvg")); >+ cur.insertAttributeWithValue(new QName(REL_URI, "embed", "rel"), rel); >+ } >+ > blipFill.addNewStretch().addNewFillRect(); > > CTShapeProperties spPr = ct.addNewSpPr(); >@@ -84,7 +137,8 @@ public class XSLFPictureShape extends XSLFSimpleShape > return ct; > } > >- >+ >+ > /** > * Is this an internal picture (image data included within > * the PowerPoint file), or an external linked picture >diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java >index 38b28df..430cb61 100644 >--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java >+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java >@@ -207,6 +207,12 @@ public class XSLFRelation extends POIXMLRelation { > "/ppt/media/image#.eps", > XSLFPictureData.class > ); >+ public static final XSLFRelation IMAGE_SVG = new XSLFRelation( >+ PictureType.SVG.contentType, >+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", >+ "/ppt/media/image#.svg", >+ XSLFPictureData.class >+ ); > public static final XSLFRelation IMAGE_BMP = new XSLFRelation( > PictureType.BMP.contentType, > "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", >diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java >index e8b4f2c..89c17ce 100644 >--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java >+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java >@@ -24,6 +24,7 @@ import java.awt.Graphics2D; > import java.io.IOException; > import java.io.InputStream; > import java.io.OutputStream; >+import java.io.ByteArrayOutputStream; > import java.util.ArrayList; > import java.util.HashMap; > import java.util.Iterator; >@@ -31,6 +32,11 @@ import java.util.List; > import java.util.Map; > import java.util.Optional; > >+import org.apache.batik.transcoder.image.JPEGTranscoder; >+import org.apache.batik.transcoder.image.PNGTranscoder; >+import org.apache.batik.transcoder.TranscoderInput; >+import org.apache.batik.transcoder.TranscoderOutput; >+ > import org.apache.poi.POIXMLDocumentPart; > import org.apache.poi.POIXMLException; > import org.apache.poi.openxml4j.exceptions.InvalidFormatException; >@@ -234,16 +240,92 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { > } > XSLFPictureData xPictureData = (XSLFPictureData)pictureData; > PackagePart pic = xPictureData.getPackagePart(); >- >+ > RelationPart rp = addRelation(null, XSLFRelation.IMAGES, new XSLFPictureData(pic)); >+ String relId = rp.getRelationship().getId(); >+ >+ String relId2 = null; >+ if (xPictureData.getType() == PictureData.PictureType.SVG) { >+ // convert SVG to PNG, add to document, and create relationship >+ >+ InputStream pd_svg = null; >+ try { >+ pd_svg = xPictureData.getInputStream(); >+ } catch (IOException e) { >+ // TODO Auto-generated catch block >+ e.printStackTrace(); >+ } >+ >+ ByteArrayOutputStream pd_png = new ByteArrayOutputStream(); >+ try { >+ generateJPEG(pd_svg, pd_png); >+ } catch (Exception e) { >+ // TODO Auto-generated catch block >+ e.printStackTrace(); >+ } > >- XSLFPictureShape sh = getDrawing().createPicture(rp.getRelationship().getId()); >+ PictureData pictureData2 = getSlideShow().addPicture(pd_png.toByteArray(), XSLFPictureData.PictureType.PNG); >+ XSLFPictureData xPictureData2 = (XSLFPictureData)pictureData2; >+ PackagePart pic2 = xPictureData2.getPackagePart(); >+ >+ RelationPart rp2 = addRelation(null, XSLFRelation.IMAGES, new XSLFPictureData(pic2)); >+ relId2 = rp2.getRelationship().getId(); >+ } >+ >+ >+ XSLFPictureShape sh = getDrawing().createPicture(relId, relId2); > new DrawPictureShape(sh).resize(); > getShapes().add(sh); > sh.setParent(this); > return sh; > } > >+ static void generateJPEG(InputStream pd_in, OutputStream pd_out) throws Exception { >+ >+ // Create a JPEG transcoder >+ JPEGTranscoder t = new JPEGTranscoder(); >+ >+ // Set the transcoding hints. >+ t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, >+ new Float(.8)); >+ >+ // Create the transcoder input. >+ TranscoderInput input = new TranscoderInput(pd_in); >+ >+ // Create the transcoder output. >+ TranscoderOutput output = new TranscoderOutput(pd_out); >+ >+ // Save the image. >+ t.transcode(input, output); >+ >+ // Flush and close the stream. >+ pd_out.flush(); >+ pd_out.close(); >+ } >+ >+ static void generatePNG(InputStream pd_in, OutputStream pd_out) throws Exception { >+ >+ // Create a JPEG transcoder >+ PNGTranscoder t = new PNGTranscoder(); >+ >+ // Set the transcoding hints. >+ //t.addTranscodingHint(PNGTranscoder.KEY_QUALITY, >+ // new Float(.8)); >+ >+ // Create the transcoder input. >+ TranscoderInput input = new TranscoderInput(pd_in); >+ >+ // Create the transcoder output. >+ TranscoderOutput output = new TranscoderOutput(pd_out); >+ >+ // Save the image. >+ t.transcode(input, output); >+ >+ // Flush and close the stream. >+ pd_out.flush(); >+ pd_out.close(); >+ } >+ > public XSLFTable createTable(){ > XSLFTable sh = getDrawing().createTable(); > getShapes().add(sh); >-- >2.8.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 62365
:
35924
| 35933