Browse Source

Bug 54541 - Add support for cropped images in Slide.draw()

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1648335 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_12_BETA1
Andreas Beeker 9 years ago
parent
commit
f27ced46fb

+ 30
- 4
src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java View File

import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;





/* ==================================================================== /* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
import javax.imageio.ImageIO; import javax.imageio.ImageIO;

import java.awt.*; import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;


public void paint(Graphics2D graphics, PictureData pict, Picture parent) { public void paint(Graphics2D graphics, PictureData pict, Picture parent) {
BufferedImage img; BufferedImage img;
try { try {
img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
}
catch (Exception e){
img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
} catch (Exception e) {
logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType()); logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType());
return; return;
} }


boolean isClipped = true;
Insets clip = parent.getBlipClip();
if (clip == null) {
isClipped = false;
clip = new Insets(0,0,0,0);
}
int iw = img.getWidth();
int ih = img.getHeight();

Rectangle anchor = parent.getLogicalAnchor2D().getBounds(); Rectangle anchor = parent.getLogicalAnchor2D().getBounds();
graphics.drawImage(img, anchor.x, anchor.y, anchor.width, anchor.height, null);

double cw = (100000-clip.left-clip.right) / 100000.0;
double ch = (100000-clip.top-clip.bottom) / 100000.0;
double sx = anchor.getWidth()/(iw*cw);
double sy = anchor.getHeight()/(ih*ch);
double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;

Shape clipOld = graphics.getClip();
if (isClipped) graphics.clip(anchor.getBounds2D());
graphics.drawRenderedImage(img, at);
graphics.setClip(clipOld);
} }


} }

+ 38
- 1
src/scratchpad/src/org/apache/poi/hslf/model/Picture.java View File

package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;


import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;


graphics.setTransform(at); graphics.setTransform(at);
} }
}

/**
* Returns the clipping values as percent ratio relatively to the image size.
* The anchor specified by {@link #getLogicalAnchor2D()} is the displayed size,
* i.e. the size of the already clipped image
*
* @return the clipping as insets converted/scaled to 100000 (=100%)
*/
public Insets getBlipClip() {
EscherOptRecord opt = getEscherOptRecord();
double top = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP);
double bottom = getFractProp(opt, EscherProperties.BLIP__CROPFROMBOTTOM);
double left = getFractProp(opt, EscherProperties.BLIP__CROPFROMLEFT);
double right = getFractProp(opt, EscherProperties.BLIP__CROPFROMRIGHT);
// if all crop values are zero (the default) then no crop rectangle is set, return null
return (top==0 && bottom==0 && left==0 && right==0)
? null
: new Insets((int)(top*100000), (int)(left*100000), (int)(bottom*100000), (int)(right*100000));
}
/**
* @return the fractional property or 0 if not defined
*
* @see <a href="http://msdn.microsoft.com/en-us/library/dd910765(v=office.12).aspx">2.2.1.6 FixedPoint</a>
*/
private static double getFractProp(EscherOptRecord opt, short propertyId) {
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, propertyId);
if (prop == null) return 0;
int fixedPoint = prop.getPropertyValue();
int i = (fixedPoint >> 16);
int f = (fixedPoint >> 0) & 0xFFFF;
double fp = i + f/65536.0;
return fp;
}
}

+ 26
- 30
src/scratchpad/testcases/org/apache/poi/hslf/model/AllHSLFModelTests.java View File



package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;


import junit.framework.Test;
import junit.framework.TestSuite;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;


/** /**
* Collects all tests from the package <tt>org.apache.poi.hslf.model</tt>. * Collects all tests from the package <tt>org.apache.poi.hslf.model</tt>.
*
* @author Josh Micich
*/ */
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestBackground.class,
TestFreeform.class,
TestHeadersFooters.class,
TestHyperlink.class,
TestImagePainter.class,
TestLine.class,
TestMovieShape.class,
TestOleEmbedding.class,
TestPPFont.class,
TestPPGraphics2D.class,
TestPicture.class,
TestSetBoldItalic.class,
TestShapes.class,
TestSheet.class,
TestSlideChangeNotes.class,
TestSlideMaster.class,
TestSlides.class,
TestTable.class,
TestTextRun.class,
TestTextRunReWrite.class,
TestTextShape.class
})
public class AllHSLFModelTests { public class AllHSLFModelTests {
public static Test suite() {
TestSuite result = new TestSuite(AllHSLFModelTests.class.getName());
result.addTestSuite(TestBackground.class);
result.addTestSuite(TestFreeform.class);
result.addTestSuite(TestHeadersFooters.class);
result.addTestSuite(TestHyperlink.class);
result.addTestSuite(TestImagePainter.class);
result.addTestSuite(TestLine.class);
result.addTestSuite(TestMovieShape.class);
result.addTestSuite(TestOleEmbedding.class);
result.addTestSuite(TestPPFont.class);
result.addTestSuite(TestPPGraphics2D.class);
result.addTestSuite(TestPicture.class);
result.addTestSuite(TestSetBoldItalic.class);
result.addTestSuite(TestShapes.class);
result.addTestSuite(TestSheet.class);
result.addTestSuite(TestSlideChangeNotes.class);
result.addTestSuite(TestSlideMaster.class);
result.addTestSuite(TestSlides.class);
result.addTestSuite(TestTable.class);
result.addTestSuite(TestTextRun.class);
result.addTestSuite(TestTextRunReWrite.class);
result.addTestSuite(TestTextShape.class);
return result;
}
} }

+ 65
- 7
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPicture.java View File



package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;


import junit.framework.TestCase;
import javax.imageio.ImageIO;


import org.apache.poi.POIDataSamples;
import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.hslf.HSLFSlideShow; import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.PictureData; import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow; import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.POIDataSamples;
import org.apache.poi.util.JvmBugs;
import org.junit.Ignore;
import org.junit.Test;


/** /**
* Test Picture shape. * Test Picture shape.
* *
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public final class TestPicture extends TestCase {
public final class TestPicture {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();


/** /**
* This is important when the same image appears multiple times in a slide show. * This is important when the same image appears multiple times in a slide show.
* *
*/ */
public void testMultiplePictures() throws Exception {
@Test
public void multiplePictures() throws Exception {
SlideShow ppt = new SlideShow(); SlideShow ppt = new SlideShow();


Slide s = ppt.createSlide(); Slide s = ppt.createSlide();
* Picture#getEscherBSERecord threw NullPointerException if EscherContainerRecord.BSTORE_CONTAINER * Picture#getEscherBSERecord threw NullPointerException if EscherContainerRecord.BSTORE_CONTAINER
* was not found. The correct behaviour is to return null. * was not found. The correct behaviour is to return null.
*/ */
public void test46122() {
@Test
public void bug46122() {
SlideShow ppt = new SlideShow(); SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide(); Slide slide = ppt.createSlide();


pict.draw(graphics); pict.draw(graphics);
} }


public void testMacImages() throws Exception {
@Test
public void macImages() throws Exception {
HSLFSlideShow hss = new HSLFSlideShow(_slTests.openResourceAsStream("53446.ppt")); HSLFSlideShow hss = new HSLFSlideShow(_slTests.openResourceAsStream("53446.ppt"));


PictureData[] pictures = hss.getPictures(); PictureData[] pictures = hss.getPictures();
} }
} }
} }

@Test
@Ignore("Just for visual validation - antialiasing is different on various systems")
public void bug54541() throws Exception {
// InputStream xis = _slTests.openResourceAsStream("54542_cropped_bitmap.pptx");
// XMLSlideShow xss = new XMLSlideShow(xis);
// xis.close();
//
// Dimension xpg = xss.getPageSize();
// for(XSLFSlide slide : xss.getSlides()) {
// BufferedImage img = new BufferedImage(xpg.width, xpg.height, BufferedImage.TYPE_INT_RGB);
// Graphics2D graphics = img.createGraphics();
// fixFonts(graphics);
// slide.draw(graphics);
// ImageIO.write(img, "PNG", new File("testx.png"));
// }
//
// System.out.println("########################");
InputStream is = _slTests.openResourceAsStream("54541_cropped_bitmap.ppt");
SlideShow ss = new SlideShow(is);
is.close();
Dimension pg = ss.getPageSize();
int i=1;
for(Slide slide : ss.getSlides()) {
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
fixFonts(graphics);
slide.draw(graphics);
ImageIO.write(img, "PNG", new File("test"+(i++)+".png"));
}
}
@SuppressWarnings("unchecked")
private void fixFonts(Graphics2D graphics) {
if (!JvmBugs.hasLineBreakMeasurerBug()) return;
Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);
if (fontMap == null) fontMap = new HashMap<String,String>();
fontMap.put("Calibri", "Lucida Sans");
fontMap.put("Cambria", "Lucida Bright");
graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap);
}
} }

BIN
test-data/slideshow/54541_cropped_bitmap.ppt View File


Loading…
Cancel
Save