diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java b/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java new file mode 100755 index 000000000..ab6d645d6 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java @@ -0,0 +1,51 @@ +package org.apache.poi.hslf.blip; + +import org.apache.poi.hslf.usermodel.PictureData; +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.util.POILogger; +import org.apache.poi.util.POILogFactory; + +/* ==================================================================== + 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. +==================================================================== */ +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; + +/** + * Creates BufferedImage using javax.imageio.ImageIO and draws it in the specified graphics. + * + * @author Yegor Kozlov. + */ +public class BitmapPainter implements ImagePainter { + protected POILogger logger = POILogFactory.getLogger(this.getClass()); + + public void paint(Graphics2D graphics, PictureData pict, Picture parent) { + BufferedImage img; + try { + img = ImageIO.read(new ByteArrayInputStream(pict.getData())); + } + catch (Exception e){ + logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType()); + return; + } + Rectangle anchor = parent.getAnchor(); + Image scaledImg = img.getScaledInstance(anchor.width, anchor.height, Image.SCALE_SMOOTH); + graphics.drawImage(scaledImg, anchor.x, anchor.y, null); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java b/src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java new file mode 100755 index 000000000..75dda947d --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java @@ -0,0 +1,71 @@ +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.hslf.usermodel.PictureData; + +import java.awt.*; + +/** + * A common interface for objects that can render ppt picture data. + *

+ * Subclasses can redefine it and use third-party libraries for actual rendering, + * for example, Bitmaps can be rendered using javax.imageio.* , WMF can be rendered using Apache Batik, + * PICT can be rendered using Apple QuickTime API for Java, etc. + *

+ * + * A typical usage is as follows: + * + * public WMFPaiter implements ImagePainter{ + * public void paint(Graphics2D graphics, PictureData pict, Picture parent){ + * DataInputStream is = new DataInputStream(new ByteArrayInputStream(pict.getData())); + * org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore wmfStore = + * new org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore(); + * try { + * wmfStore.read(is); + * } catch (IOException e){ + * return; + * } + * + * Rectangle anchor = parent.getAnchor(); + * float scale = (float)anchor.width/wmfStore.getWidthPixels(); + * + * org.apache.batik.transcoder.wmf.tosvg.WMFPainter painter = + * new org.apache.batik.transcoder.wmf.tosvg.WMFPainter(wmfStore, 0, 0, scale); + * graphics.translate(anchor.x, anchor.y); + * painter.paint(graphics); + * } + * } + * PictureData.setImagePainter(Picture.WMF, new WMFPaiter()); + * ... + * + * Subsequenet calls of Slide.draw(Graphics gr) will use WMFPaiter for WMF images. + * + * @author Yegor Kozlov. + */ +public interface ImagePainter { + + /** + * Paints the specified picture data + * + * @param graphics the graphics to paintb into + * @param pict the data to paint + * @param parent the shapes that owns the picture data + */ + public void paint(Graphics2D graphics, PictureData pict, Picture parent); +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java index 02ff1d9ad..d21d098c3 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java @@ -17,6 +17,8 @@ package org.apache.poi.hslf.usermodel; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogger; +import org.apache.poi.util.POILogFactory; import org.apache.poi.hslf.model.Picture; import org.apache.poi.hslf.blip.*; import org.apache.poi.hslf.exceptions.HSLFException; @@ -25,6 +27,7 @@ import java.io.OutputStream; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.awt.*; /** * A class that represents image data contained in a slide show. @@ -33,19 +36,21 @@ import java.security.NoSuchAlgorithmException; */ public abstract class PictureData { + protected POILogger logger = POILogFactory.getLogger(this.getClass()); + /** * Size of the image checksum calculated using MD5 algorithm. */ protected static final int CHECKSUM_SIZE = 16; - /** - * Binary data of the picture - */ + /** + * Binary data of the picture + */ private byte[] rawdata; - /** - * The offset to the picture in the stream - */ - protected int offset; + /** + * The offset to the picture in the stream + */ + protected int offset; /** * Returns type of this picture. @@ -71,6 +76,13 @@ public abstract class PictureData { */ protected abstract int getSignature(); + protected static ImagePainter[] painters = new ImagePainter[8]; + static { + PictureData.setImagePainter(Picture.PNG, new BitmapPainter()); + PictureData.setImagePainter(Picture.JPEG, new BitmapPainter()); + PictureData.setImagePainter(Picture.DIB, new BitmapPainter()); + } + /** * Returns the raw binary data of this Picture excluding the first 8 bytes * which hold image signature and size of the image data. @@ -212,4 +224,30 @@ public abstract class PictureData { return getData().length; } + public void draw(Graphics2D graphics, Picture parent){ + ImagePainter painter = painters[getType()]; + if(painter != null) painter.paint(graphics, this, parent); + else logger.log(POILogger.WARN, "Rendering is not supported: " + getClass().getName()); + } + + /** + * Register ImagePainter for the specified image type + * + * @param type image type, must be one of the static constants defined in the Picture class. + * @param painter + */ + public static void setImagePainter(int type, ImagePainter painter){ + painters[type] = painter; + } + + /** + * Return ImagePainter for the specified image type + * + * @param type blip type, must be one of the static constants defined in the Picture class. + * @return ImagePainter for the specified image type + */ + public static ImagePainter getImagePainter(int type){ + return painters[type]; + } + } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java new file mode 100755 index 000000000..d10dd1353 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java @@ -0,0 +1,57 @@ +/* ==================================================================== + 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.hslf.model; + +import junit.framework.*; + +import java.io.FileOutputStream; +import java.io.File; +import java.awt.*; + +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.usermodel.PictureData; +import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.blip.ImagePainter; +import org.apache.poi.hslf.blip.BitmapPainter; +import org.apache.poi.ddf.EscherBSERecord; + +/** + * Test Picture shape. + * + * @author Yegor Kozlov + */ +public class TestImagePainter extends TestCase { + + private static class CustomImagePainer implements ImagePainter{ + public void paint(Graphics2D graphics, PictureData pict, Picture parent){ + //do noting + } + + } + + public void testImagePainter() throws Exception { + + ImagePainter pntr = PictureData.getImagePainter(Picture.PNG); + assertTrue(PictureData.getImagePainter(Picture.PNG) instanceof BitmapPainter); + assertTrue(PictureData.getImagePainter(Picture.JPEG) instanceof BitmapPainter); + assertTrue(PictureData.getImagePainter(Picture.DIB) instanceof BitmapPainter); + + PictureData.setImagePainter(Picture.WMF, new CustomImagePainer()); + assertTrue(PictureData.getImagePainter(Picture.WMF) instanceof CustomImagePainer); + } + +}