diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2014-11-12 00:19:00 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2014-11-12 00:19:00 +0000 |
commit | d43ba17fe97c37d1f12583049638a95c9da26463 (patch) | |
tree | e430d92c7a5ba7e9df5bb023b421b94c9a084be1 | |
parent | 2429c74b850874023836533bb0f17990961e6d96 (diff) | |
download | poi-d43ba17fe97c37d1f12583049638a95c9da26463.tar.gz poi-d43ba17fe97c37d1f12583049638a95c9da26463.zip |
Picture method to resize with different scales in width and height
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1638623 13f79535-47bb-0310-9956-ffa450edef68
16 files changed, 608 insertions, 262 deletions
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java index 2c4b59f7b0..2d2eaa752e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java @@ -21,7 +21,17 @@ import java.awt.Dimension; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; -import org.apache.poi.ddf.*; +import org.apache.poi.ddf.DefaultEscherRecordFactory; +import org.apache.poi.ddf.EscherBSERecord; +import org.apache.poi.ddf.EscherBlipRecord; +import org.apache.poi.ddf.EscherClientDataRecord; +import org.apache.poi.ddf.EscherComplexProperty; +import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.ddf.EscherOptRecord; +import org.apache.poi.ddf.EscherProperties; +import org.apache.poi.ddf.EscherSimpleProperty; +import org.apache.poi.ddf.EscherTextboxRecord; +import org.apache.poi.hssf.model.InternalWorkbook; import org.apache.poi.hssf.record.CommonObjectDataSubRecord; import org.apache.poi.hssf.record.EscherAggregate; import org.apache.poi.hssf.record.ObjRecord; @@ -29,7 +39,6 @@ import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.util.ImageUtils; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; -import org.apache.poi.hssf.model.InternalWorkbook; /** * Represents a escher picture. Eg. A GIF, JPEG etc... @@ -44,20 +53,6 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { public static final int PICTURE_TYPE_PNG = HSSFWorkbook.PICTURE_TYPE_PNG; // PNG public static final int PICTURE_TYPE_DIB = HSSFWorkbook.PICTURE_TYPE_DIB; // Windows DIB - /** - * width of 1px in columns with default width in units of 1/256 of a character width - */ - private static final float PX_DEFAULT = 32.00f; - /** - * width of 1px in columns with overridden width in units of 1/256 of a character width - */ - private static final float PX_MODIFIED = 36.56f; - - /** - * Height of 1px of a row - */ - private static final int PX_ROW = 15; - public HSSFPicture(EscherContainerRecord spContainer, ObjRecord objRecord) { super(spContainer, objRecord); } @@ -98,49 +93,63 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { } /** + * Reset the image to the dimension of the embedded image + * + * <p> + * Please note, that this method works correctly only for workbooks + * with default font size (Arial 10pt for .xls). + * If the default font is changed the resized image can be streched vertically or horizontally. + * </p> + */ + public void resize(){ + resize(Double.MAX_VALUE); + } + + /** + * Resize the image proportionally. + * + * @see #resize(double, double) + */ + public void resize(double scale) { + resize(scale,scale); + } + + /** * Resize the image * <p> * Please note, that this method works correctly only for workbooks * with default font size (Arial 10pt for .xls). * If the default font is changed the resized image can be streched vertically or horizontally. * </p> + * <p> + * <code>resize(1.0,1.0)</code> keeps the original size,<br/> + * <code>resize(0.5,0.5)</code> resize to 50% of the original,<br/> + * <code>resize(2.0,2.0)</code> resizes to 200% of the original.<br/> + * <code>resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE})</code> resizes to the dimension of the embedded image. + * </p> * - * @param scale the amount by which image dimensions are multiplied relative to the original size. - * <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original, - * <code>resize(2.0)</code> resizes to 200% of the original. + * @param scaleX the amount by which the image width is multiplied relative to the original width. + * @param scaleY the amount by which the image height is multiplied relative to the original height. */ - public void resize(double scale){ - HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor(); + public void resize(double scaleX, double scaleY) { + HSSFClientAnchor anchor = getClientAnchor(); anchor.setAnchorType(2); - HSSFClientAnchor pref = getPreferredSize(scale); + HSSFClientAnchor pref = getPreferredSize(scaleX,scaleY); int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1()); int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1()); anchor.setCol2((short)col2); - anchor.setDx1(0); + // anchor.setDx1(0); anchor.setDx2(pref.getDx2()); anchor.setRow2(row2); - anchor.setDy1(0); + // anchor.setDy1(0); anchor.setDy2(pref.getDy2()); } /** - * Reset the image to the original size. - * - * <p> - * Please note, that this method works correctly only for workbooks - * with default font size (Arial 10pt for .xls). - * If the default font is changed the resized image can be streched vertically or horizontally. - * </p> - */ - public void resize(){ - resize(1.0); - } - - /** * Calculate the preferred size for this picture. * * @return HSSFClientAnchor with the preferred size for this image @@ -158,86 +167,30 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { * @since POI 3.0.2 */ public HSSFClientAnchor getPreferredSize(double scale){ - HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor(); - - Dimension size = getImageDimension(); - double scaledWidth = size.getWidth() * scale; - double scaledHeight = size.getHeight() * scale; - - float w = 0; - - //space in the leftmost cell - w += getColumnWidthInPixels(anchor.getCol1())*(1 - (float)anchor.getDx1()/1024); - short col2 = (short)(anchor.getCol1() + 1); - int dx2 = 0; - - while(w < scaledWidth){ - w += getColumnWidthInPixels(col2++); - } - - if(w > scaledWidth) { - //calculate dx2, offset in the rightmost cell - col2--; - double cw = getColumnWidthInPixels(col2); - double delta = w - scaledWidth; - dx2 = (int)((cw-delta)/cw*1024); - } - anchor.setCol2(col2); - anchor.setDx2(dx2); - - float h = 0; - h += (1 - (float)anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1()); - int row2 = anchor.getRow1() + 1; - int dy2 = 0; - - while(h < scaledHeight){ - h += getRowHeightInPixels(row2++); - } - if(h > scaledHeight) { - row2--; - double ch = getRowHeightInPixels(row2); - double delta = h - scaledHeight; - dy2 = (int)((ch-delta)/ch*256); - } - anchor.setRow2(row2); - anchor.setDy2(dy2); - - return anchor; - } - - private float getColumnWidthInPixels(int column){ - - int cw = getPatriarch().getSheet().getColumnWidth(column); - float px = getPixelWidth(column); - - return cw/px; + return getPreferredSize(scale, scale); } - - private float getRowHeightInPixels(int i){ - - HSSFRow row = getPatriarch().getSheet().getRow(i); - float height; - if(row != null) height = row.getHeight(); - else height = getPatriarch().getSheet().getDefaultRowHeight(); - - return height/PX_ROW; - } - - private float getPixelWidth(int column){ - - int def = getPatriarch().getSheet().getDefaultColumnWidth()*256; - int cw = getPatriarch().getSheet().getColumnWidth(column); - - return cw == def ? PX_DEFAULT : PX_MODIFIED; + + /** + * Calculate the preferred size for this picture. + * + * @param scaleX the amount by which image width is multiplied relative to the original width. + * @param scaleY the amount by which image height is multiplied relative to the original height. + * @return HSSFClientAnchor with the preferred size for this image + * @since POI 3.11 + */ + public HSSFClientAnchor getPreferredSize(double scaleX, double scaleY){ + ImageUtils.setPreferredSize(this, scaleX, scaleY); + return getClientAnchor(); } /** - * Return the dimension of this image + * Return the dimension of the embedded image in pixel * - * @return image dimension + * @return image dimension in pixels */ public Dimension getImageDimension(){ - EscherBSERecord bse = getPatriarch().getSheet()._book.getBSERecord(getPictureIndex()); + InternalWorkbook iwb = getPatriarch().getSheet().getWorkbook().getWorkbook(); + EscherBSERecord bse = iwb.getBSERecord(getPictureIndex()); byte[] data = bse.getBlipRecord().getPicturedata(); int type = bse.getBlipTypeWin32(); return ImageUtils.getImageDimension(new ByteArrayInputStream(data), type); @@ -250,7 +203,8 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { */ public HSSFPictureData getPictureData(){ InternalWorkbook iwb = getPatriarch().getSheet().getWorkbook().getWorkbook(); - EscherBlipRecord blipRecord = iwb.getBSERecord(getPictureIndex()).getBlipRecord(); + EscherBSERecord bse = iwb.getBSERecord(getPictureIndex()); + EscherBlipRecord blipRecord = bse.getBlipRecord(); return new HSSFPictureData(blipRecord); } @@ -301,4 +255,22 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise(); return new HSSFPicture(spContainer, obj); } + + /** + * @return the anchor that is used by this picture. + */ + @Override + public HSSFClientAnchor getClientAnchor() { + HSSFAnchor a = getAnchor(); + return (a instanceof HSSFClientAnchor) ? (HSSFClientAnchor)a : null; + } + + + /** + * @return the sheet which contains the picture shape + */ + @Override + public HSSFSheet getSheet() { + return getPatriarch().getSheet(); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java index 93fa26f5ba..267bd2e1d6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java @@ -22,6 +22,7 @@ import org.apache.poi.ddf.EscherBitmapBlip; import org.apache.poi.ddf.EscherBlipRecord; import org.apache.poi.ddf.EscherMetafileBlip; import org.apache.poi.ss.usermodel.PictureData; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.PngUtils; /** @@ -131,4 +132,33 @@ public class HSSFPictureData implements PictureData return "image/unknown"; } } + + /** + * @return the POI internal image type, -1 if not unknown image type + * + * @see Workbook#PICTURE_TYPE_DIB + * @see Workbook#PICTURE_TYPE_EMF + * @see Workbook#PICTURE_TYPE_JPEG + * @see Workbook#PICTURE_TYPE_PICT + * @see Workbook#PICTURE_TYPE_PNG + * @see Workbook#PICTURE_TYPE_WMF + */ + public int getPictureType() { + switch (blip.getRecordId()) { + case EscherMetafileBlip.RECORD_ID_WMF: + return Workbook.PICTURE_TYPE_WMF; + case EscherMetafileBlip.RECORD_ID_EMF: + return Workbook.PICTURE_TYPE_EMF; + case EscherMetafileBlip.RECORD_ID_PICT: + return Workbook.PICTURE_TYPE_PICT; + case EscherBitmapBlip.RECORD_ID_PNG: + return Workbook.PICTURE_TYPE_PNG; + case EscherBitmapBlip.RECORD_ID_JPEG: + return Workbook.PICTURE_TYPE_JPEG; + case EscherBitmapBlip.RECORD_ID_DIB: + return Workbook.PICTURE_TYPE_DIB; + default: + return -1; + } + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index ce09d8012d..e7ed838ecc 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -77,6 +77,16 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { private static final int DEBUG = POILogger.DEBUG; /** + * width of 1px in columns with default width in units of 1/256 of a character width + */ + private static final float PX_DEFAULT = 32.00f; + /** + * width of 1px in columns with overridden width in units of 1/256 of a character width + */ + private static final float PX_MODIFIED = 36.56f; + + + /** * Used for compile-time optimization. This is the initial size for the collection of * rows. It is currently set to 20. If you generate larger sheets you may benefit * by setting this to a higher number and recompiling a custom edition of HSSFSheet. @@ -555,6 +565,14 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { return _sheet.getColumnWidth(columnIndex); } + public float getColumnWidthInPixels(int column){ + int cw = getColumnWidth(column); + int def = getDefaultColumnWidth()*256; + float px = (cw == def ? PX_DEFAULT : PX_MODIFIED); + + return cw/px; + } + /** * get the default column width for the sheet (if the columns do not define their own width) in * characters diff --git a/src/java/org/apache/poi/ss/usermodel/Picture.java b/src/java/org/apache/poi/ss/usermodel/Picture.java index c79260c6ee..58ad448125 100644 --- a/src/java/org/apache/poi/ss/usermodel/Picture.java +++ b/src/java/org/apache/poi/ss/usermodel/Picture.java @@ -16,6 +16,9 @@ ==================================================================== */ package org.apache.poi.ss.usermodel; +import java.awt.Dimension; + + /** * Repersents a picture in a SpreadsheetML document * @@ -24,38 +27,76 @@ package org.apache.poi.ss.usermodel; public interface Picture { /** - * Reset the image to the original size. + * Reset the image to the dimension of the embedded image * - * <p> - * Please note, that this method works correctly only for workbooks - * with default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). - * If the default font is changed the resized image can be streched vertically or horizontally. - * </p> + * @see #resize(double, double) */ void resize(); /** - * Reset the image to the original size. + * Resize the image proportionally. * + * @see #resize(double, double) + */ + void resize(double scale); + + /** + * Resize the image. * <p> * Please note, that this method works correctly only for workbooks - * with default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). - * If the default font is changed the resize() procedure can be 'off'. + * with the default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). + * If the default font is changed the resized image can be streched vertically or horizontally. + * </p> + * <p> + * <code>resize(1.0,1.0)</code> keeps the original size,<br/> + * <code>resize(0.5,0.5)</code> resize to 50% of the original,<br/> + * <code>resize(2.0,2.0)</code> resizes to 200% of the original.<br/> + * <code>resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE})</code> resizes to the dimension of the embedded image. * </p> * - * @param scale the amount by which image dimensions are multiplied relative to the original size. - * <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original, - * <code>resize(2.0)</code> resizes to 200% of the original. + * @param scaleX the amount by which the image width is multiplied relative to the original width. + * @param scaleY the amount by which the image height is multiplied relative to the original height. */ - void resize(double scale); + void resize(double scaleX, double scaleY); + /** + * Calculate the preferred size for this picture. + * + * @return XSSFClientAnchor with the preferred size for this image + */ ClientAnchor getPreferredSize(); /** + * Calculate the preferred size for this picture. + * + * @param scaleX the amount by which image width is multiplied relative to the original width. + * @param scaleY the amount by which image height is multiplied relative to the original height. + * @return ClientAnchor with the preferred size for this image + */ + ClientAnchor getPreferredSize(double scaleX, double scaleY); + + /** + * Return the dimension of the embedded image in pixel + * + * @return image dimension in pixels + */ + Dimension getImageDimension(); + + /** * Return picture data for this picture * * @return picture data for this picture */ PictureData getPictureData(); + /** + * @return the anchor that is used by this picture + */ + ClientAnchor getClientAnchor(); + + + /** + * @return the sheet which contains the picture + */ + Sheet getSheet(); } diff --git a/src/java/org/apache/poi/ss/usermodel/PictureData.java b/src/java/org/apache/poi/ss/usermodel/PictureData.java index 954337829d..67d3cefcd1 100644 --- a/src/java/org/apache/poi/ss/usermodel/PictureData.java +++ b/src/java/org/apache/poi/ss/usermodel/PictureData.java @@ -37,4 +37,16 @@ public interface PictureData { * Returns the mime type for the image */ String getMimeType(); + + /** + * @return the POI internal image type, 0 if unknown image type + * + * @see Workbook#PICTURE_TYPE_DIB + * @see Workbook#PICTURE_TYPE_EMF + * @see Workbook#PICTURE_TYPE_JPEG + * @see Workbook#PICTURE_TYPE_PICT + * @see Workbook#PICTURE_TYPE_PNG + * @see Workbook#PICTURE_TYPE_WMF + */ + int getPictureType(); }
\ No newline at end of file diff --git a/src/java/org/apache/poi/ss/usermodel/Sheet.java b/src/java/org/apache/poi/ss/usermodel/Sheet.java index 57c8785c6c..d1bd67416a 100644 --- a/src/java/org/apache/poi/ss/usermodel/Sheet.java +++ b/src/java/org/apache/poi/ss/usermodel/Sheet.java @@ -186,12 +186,27 @@ public interface Sheet extends Iterable<Row> { * using the default font (first font in the workbook) * </p> * - * @param columnIndex - the column to set (0-based) + * @param columnIndex - the column to get (0-based) * @return width - the width in units of 1/256th of a character width */ int getColumnWidth(int columnIndex); /** + * get the width in pixel + * + * <p> + * Please note, that this method works correctly only for workbooks + * with the default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). + * If the default font is changed the column width can be streched + * </p> + * + * @param columnIndex - the column to set (0-based) + * @return width in pixels + */ + float getColumnWidthInPixels(int columnIndex); + + + /** * Set the default column width for the sheet (if the columns do not define their own width) * in characters * @@ -214,7 +229,7 @@ public interface Sheet extends Iterable<Row> { * @return default row height measured in twips (1/20 of a point) */ short getDefaultRowHeight(); - + /** * Get the default row height for the sheet (if the rows do not define their own height) in * points. @@ -922,7 +937,7 @@ public interface Sheet extends Iterable<Row> { public DataValidationHelper getDataValidationHelper(); - /** + /** * Returns the list of DataValidation in the sheet. * @return list of DataValidation in the sheet */ diff --git a/src/java/org/apache/poi/ss/util/ImageUtils.java b/src/java/org/apache/poi/ss/util/ImageUtils.java index 76ebc0370c..b470824519 100644 --- a/src/java/org/apache/poi/ss/util/ImageUtils.java +++ b/src/java/org/apache/poi/ss/util/ImageUtils.java @@ -16,21 +16,32 @@ ==================================================================== */
package org.apache.poi.ss.util;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Element;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.POILogFactory;
+import static org.apache.poi.util.Units.EMU_PER_PIXEL;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageIO;
-import javax.imageio.stream.ImageInputStream;
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.awt.*;
-import java.awt.image.BufferedImage;
import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.Picture;
+import org.apache.poi.ss.usermodel.PictureData;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Units;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
/**
* @author Yegor Kozlov
*/
@@ -60,8 +71,8 @@ public class ImageUtils { try {
//read the image using javax.imageio.*
ImageInputStream iis = ImageIO.createImageInputStream( is );
- Iterator i = ImageIO.getImageReaders( iis );
- ImageReader r = (ImageReader) i.next();
+ Iterator<ImageReader> i = ImageIO.getImageReaders( iis );
+ ImageReader r = i.next();
r.setInput( iis );
BufferedImage img = r.read(0);
@@ -113,4 +124,154 @@ public class ImageUtils { return new int[]{hdpi, vdpi};
}
+ /**
+ * Calculate and set the preferred size (anchor) for this picture.
+ *
+ * @param scaleX the amount by which image width is multiplied relative to the original width.
+ * @param scaleY the amount by which image height is multiplied relative to the original height.
+ * @return the new Dimensions of the scaled picture in EMUs
+ */
+ public static Dimension setPreferredSize(Picture picture, double scaleX, double scaleY){
+ ClientAnchor anchor = picture.getClientAnchor();
+ boolean isHSSF = (anchor instanceof HSSFClientAnchor);
+ PictureData data = picture.getPictureData();
+ Sheet sheet = picture.getSheet();
+
+ // in pixel
+ Dimension imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType());
+ // in emus
+ Dimension anchorSize = ImageUtils.getDimensionFromAnchor(picture);
+ final double scaledWidth = (scaleX == Double.MAX_VALUE)
+ ? imgSize.getWidth() : anchorSize.getWidth()/EMU_PER_PIXEL * scaleX;
+ final double scaledHeight = (scaleY == Double.MAX_VALUE)
+ ? imgSize.getHeight() : anchorSize.getHeight()/EMU_PER_PIXEL * scaleY;
+
+ double w = 0;
+ int col2 = anchor.getCol1();
+ int dx2 = 0;
+
+ //space in the leftmost cell
+ w = sheet.getColumnWidthInPixels(col2++);
+ if (isHSSF) {
+ w *= 1 - anchor.getDx1()/1024d;
+ } else {
+ w -= anchor.getDx1()/EMU_PER_PIXEL;
+ }
+
+ while(w < scaledWidth){
+ w += sheet.getColumnWidthInPixels(col2++);
+ }
+
+ if(w > scaledWidth) {
+ //calculate dx2, offset in the rightmost cell
+ double cw = sheet.getColumnWidthInPixels(--col2);
+ double delta = w - scaledWidth;
+ if (isHSSF) {
+ dx2 = (int)((cw-delta)/cw*1024);
+ } else {
+ dx2 = (int)((cw-delta)*EMU_PER_PIXEL);
+ }
+ if (dx2 < 0) dx2 = 0;
+ }
+ anchor.setCol2(col2);
+ anchor.setDx2(dx2);
+
+ double h = 0;
+ int row2 = anchor.getRow1();
+ int dy2 = 0;
+
+ h = getRowHeightInPixels(sheet,row2++);
+ if (isHSSF) {
+ h *= 1 - anchor.getDy1()/256d;
+ } else {
+ h -= anchor.getDy1()/EMU_PER_PIXEL;
+ }
+
+ while(h < scaledHeight){
+ h += getRowHeightInPixels(sheet,row2++);
+ }
+
+ if(h > scaledHeight) {
+ double ch = getRowHeightInPixels(sheet,--row2);
+ double delta = h - scaledHeight;
+ if (isHSSF) {
+ dy2 = (int)((ch-delta)/ch*256);
+ } else {
+ dy2 = (int)((ch-delta)*EMU_PER_PIXEL);
+ }
+ if (dy2 < 0) dy2 = 0;
+ }
+
+ anchor.setRow2(row2);
+ anchor.setDy2(dy2);
+
+ Dimension dim = new Dimension(
+ (int)Math.round(scaledWidth*EMU_PER_PIXEL),
+ (int)Math.round(scaledHeight*EMU_PER_PIXEL)
+ );
+
+ return dim;
+ }
+
+ /**
+ * Calculates the dimensions in EMUs for the anchor of the given picture
+ *
+ * @param picture the picture containing the anchor
+ * @return the dimensions in EMUs
+ */
+ public static Dimension getDimensionFromAnchor(Picture picture) {
+ ClientAnchor anchor = picture.getClientAnchor();
+ boolean isHSSF = (anchor instanceof HSSFClientAnchor);
+ Sheet sheet = picture.getSheet();
+
+ double w = 0;
+ int col2 = anchor.getCol1();
+
+ //space in the leftmost cell
+ w = sheet.getColumnWidthInPixels(col2++);
+ if (isHSSF) {
+ w *= 1 - anchor.getDx1()/1024d;
+ } else {
+ w -= anchor.getDx1()/EMU_PER_PIXEL;
+ }
+
+ while(col2 < anchor.getCol2()){
+ w += sheet.getColumnWidthInPixels(col2++);
+ }
+
+ if (isHSSF) {
+ w += sheet.getColumnWidthInPixels(col2) * anchor.getDx2()/1024d;
+ } else {
+ w += anchor.getDx2()/EMU_PER_PIXEL;
+ }
+
+ double h = 0;
+ int row2 = anchor.getRow1();
+
+ h = getRowHeightInPixels(sheet,row2++);
+ if (isHSSF) {
+ h *= 1 - anchor.getDy1()/256d;
+ } else {
+ h -= anchor.getDy1()/EMU_PER_PIXEL;
+ }
+
+ while(row2 < anchor.getRow2()){
+ h += getRowHeightInPixels(sheet,row2++);
+ }
+
+ if (isHSSF) {
+ h += getRowHeightInPixels(sheet,row2) * anchor.getDy2()/256;
+ } else {
+ h += anchor.getDy2()/EMU_PER_PIXEL;
+ }
+
+ return new Dimension((int)w*EMU_PER_PIXEL, (int)h*EMU_PER_PIXEL);
+ }
+
+
+ private static double getRowHeightInPixels(Sheet sheet, int rowNum) {
+ Row r = sheet.getRow(rowNum);
+ double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
+ return Units.toEMU(points)/EMU_PER_PIXEL;
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/util/Units.java b/src/java/org/apache/poi/util/Units.java index 3a400399c7..91584b2ad5 100644 --- a/src/ooxml/java/org/apache/poi/util/Units.java +++ b/src/java/org/apache/poi/util/Units.java @@ -23,10 +23,20 @@ public class Units { public static final int EMU_PER_PIXEL = 9525;
public static final int EMU_PER_POINT = 12700;
- public static int toEMU(double value){
- return (int)Math.round(EMU_PER_POINT*value);
+ /**
+ * Converts points to EMUs
+ * @param points points
+ * @return emus
+ */
+ public static int toEMU(double points){
+ return (int)Math.round(EMU_PER_POINT*points);
}
+ /**
+ * Converts EMUs to points
+ * @param emu emu
+ * @return points
+ */
public static double toPoints(long emu){
return (double)emu/EMU_PER_POINT;
}
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index d676eb599e..2700e16785 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -265,6 +265,19 @@ public class SXSSFSheet implements Sheet, Cloneable } /** + * Get the actual column width in pixels + * + * <p> + * Please note, that this method works correctly only for workbooks + * with the default font size (Calibri 11pt for .xlsx). + * </p> + */ + @Override + public float getColumnWidthInPixels(int columnIndex) { + return _sh.getColumnWidthInPixels(columnIndex); + } + + /** * Set the default column width for the sheet (if the columns do not define their own width) * in characters * diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java index 47402bdc35..1d87faceee 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java @@ -20,15 +20,14 @@ package org.apache.poi.xssf.usermodel; import java.awt.Dimension; import java.io.IOException; -import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.ImageUtils; +import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; -import org.apache.poi.util.Internal; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualPictureProperties; @@ -40,7 +39,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPictureNonVisual; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; /** * Represents a picture shape in a SpreadsheetML drawing. @@ -57,7 +55,7 @@ public final class XSSFPicture extends XSSFShape implements Picture { * * This value is the same for default font in Office 2007 (Calibry) and Office 2003 and earlier (Arial) */ - private static float DEFAULT_COLUMN_WIDTH = 9.140625f; + // private static float DEFAULT_COLUMN_WIDTH = 9.140625f; /** * A default instance of CTShape used for creating new shapes. @@ -140,44 +138,56 @@ public final class XSSFPicture extends XSSFShape implements Picture { } /** - * Reset the image to the original size. + * Reset the image to the dimension of the embedded image * - * <p> - * Please note, that this method works correctly only for workbooks - * with the default font size (Calibri 11pt for .xlsx). - * If the default font is changed the resized image can be streched vertically or horizontally. - * </p> + * @see #resize(double, double) */ public void resize(){ - resize(1.0); + resize(Double.MAX_VALUE); } /** - * Reset the image to the original size. + * Resize the image proportionally. + * + * @see #resize(double, double) + */ + public void resize(double scale) { + resize(scale, scale); + } + + /** + * Resize the image relatively to its current size. * <p> * Please note, that this method works correctly only for workbooks * with the default font size (Calibri 11pt for .xlsx). * If the default font is changed the resized image can be streched vertically or horizontally. * </p> + * <p> + * <code>resize(1.0,1.0)</code> keeps the original size,<br/> + * <code>resize(0.5,0.5)</code> resize to 50% of the original,<br/> + * <code>resize(2.0,2.0)</code> resizes to 200% of the original.<br/> + * <code>resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE})</code> resizes to the dimension of the embedded image. + * </p> * - * @param scale the amount by which image dimensions are multiplied relative to the original size. - * <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original, - * <code>resize(2.0)</code> resizes to 200% of the original. + * @param scaleX the amount by which the image width is multiplied relative to the original width, + * when set to {@link java.lang.Double#MAX_VALUE} the width of the embedded image is used + * @param scaleY the amount by which the image height is multiplied relative to the original height, + * when set to {@link java.lang.Double#MAX_VALUE} the height of the embedded image is used */ - public void resize(double scale){ - XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor(); + public void resize(double scaleX, double scaleY){ + XSSFClientAnchor anchor = getClientAnchor(); - XSSFClientAnchor pref = getPreferredSize(scale); + XSSFClientAnchor pref = getPreferredSize(scaleX,scaleY); int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1()); int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1()); anchor.setCol2(col2); - anchor.setDx1(0); + // anchor.setDx1(0); anchor.setDx2(pref.getDx2()); anchor.setRow2(row2); - anchor.setDy1(0); + // anchor.setDy1(0); anchor.setDy2(pref.getDy2()); } @@ -197,71 +207,22 @@ public final class XSSFPicture extends XSSFShape implements Picture { * @return XSSFClientAnchor with the preferred size for this image */ public XSSFClientAnchor getPreferredSize(double scale){ - XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor(); - - XSSFPictureData data = getPictureData(); - Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType()); - double scaledWidth = size.getWidth() * scale; - double scaledHeight = size.getHeight() * scale; - - float w = 0; - int col2 = anchor.getCol1(); - int dx2 = 0; - - for (;;) { - w += getColumnWidthInPixels(col2); - if(w > scaledWidth) break; - col2++; - } - - if(w > scaledWidth) { - double cw = getColumnWidthInPixels(col2 ); - double delta = w - scaledWidth; - dx2 = (int)(EMU_PER_PIXEL*(cw-delta)); - } - anchor.setCol2(col2); - anchor.setDx2(dx2); - - double h = 0; - int row2 = anchor.getRow1(); - int dy2 = 0; - - for (;;) { - h += getRowHeightInPixels(row2); - if(h > scaledHeight) break; - row2++; - } - - if(h > scaledHeight) { - double ch = getRowHeightInPixels(row2); - double delta = h - scaledHeight; - dy2 = (int)(EMU_PER_PIXEL*(ch-delta)); - } - anchor.setRow2(row2); - anchor.setDy2(dy2); - - CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt(); - size2d.setCx((long)(scaledWidth*EMU_PER_PIXEL)); - size2d.setCy((long)(scaledHeight*EMU_PER_PIXEL)); - - return anchor; - } - - private float getColumnWidthInPixels(int columnIndex){ - XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); - - CTCol col = sheet.getColumnHelper().getColumn(columnIndex, false); - double numChars = col == null || !col.isSetWidth() ? DEFAULT_COLUMN_WIDTH : col.getWidth(); - - return (float)numChars*XSSFWorkbook.DEFAULT_CHARACTER_WIDTH; + return getPreferredSize(scale, scale); } - - private float getRowHeightInPixels(int rowIndex){ - XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); - - XSSFRow row = sheet.getRow(rowIndex); - float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints(); - return height*PIXEL_DPI/POINT_DPI; + + /** + * Calculate the preferred size for this picture. + * + * @param scaleX the amount by which image width is multiplied relative to the original width. + * @param scaleY the amount by which image height is multiplied relative to the original height. + * @return XSSFClientAnchor with the preferred size for this image + */ + public XSSFClientAnchor getPreferredSize(double scaleX, double scaleY){ + Dimension dim = ImageUtils.setPreferredSize(this, scaleX, scaleY); + CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt(); + size2d.setCx((int)dim.getWidth()); + size2d.setCy((int)dim.getHeight()); + return getClientAnchor(); } /** @@ -284,6 +245,16 @@ public final class XSSFPicture extends XSSFShape implements Picture { } /** + * Return the dimension of the embedded image in pixel + * + * @return image dimension in pixels + */ + public Dimension getImageDimension() { + XSSFPictureData picData = getPictureData(); + return getImageDimension(picData.getPackagePart(), picData.getPictureType()); + } + + /** * Return picture data for this shape * * @return picture data for this shape @@ -297,4 +268,20 @@ public final class XSSFPicture extends XSSFShape implements Picture { return ctPicture.getSpPr(); } + /** + * @return the anchor that is used by this shape. + */ + @Override + public XSSFClientAnchor getClientAnchor() { + XSSFAnchor a = getAnchor(); + return (a instanceof XSSFClientAnchor) ? (XSSFClientAnchor)a : null; + } + + /** + * @return the sheet which contains the picture shape + */ + @Override + public XSSFSheet getSheet() { + return (XSSFSheet)getDrawing().getParent(); + } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index ac72c76803..a5a8b311b6 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -705,6 +705,22 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } /** + * Get the actual column width in pixels + * + * <p> + * Please note, that this method works correctly only for workbooks + * with the default font size (Calibri 11pt for .xlsx). + * </p> + */ + @Override + public float getColumnWidthInPixels(int columnIndex) { + int styleIdx = getColumnHelper().getColDefaultStyle(columnIndex); + CellStyle cs = getWorkbook().getStylesSource().getStyleAt(styleIdx); + float widthIn256 = getColumnWidth(columnIndex); + return (float)(widthIn256/256.0*XSSFWorkbook.DEFAULT_CHARACTER_WIDTH); + } + + /** * Get the default column width for the sheet (if the columns do not define their own width) in * characters. * <p> @@ -730,6 +746,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { return (short)(getDefaultRowHeightInPoints() * 20); } + /** * Get the default row height for the sheet measued in point size (if the rows do not define their own height). * diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java index f6b05586e6..5415502b12 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java @@ -18,13 +18,25 @@ package org.apache.poi.xssf.usermodel; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.List; +import org.apache.poi.hssf.usermodel.HSSFPatriarch; +import org.apache.poi.hssf.usermodel.HSSFPicture; +import org.apache.poi.hssf.usermodel.HSSFShape; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.BaseTestPicture; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; +import org.junit.Ignore; +import org.junit.Test; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs; @@ -37,12 +49,21 @@ public final class TestXSSFPicture extends BaseTestPicture { super(XSSFITestDataProvider.instance); } - public void testResize() { - baseTestResize(new XSSFClientAnchor(0, 0, 504825, 85725, (short)0, 0, (short)1, 8)); + @Test + public void resize() throws Exception { + XSSFWorkbook wb = XSSFITestDataProvider.instance.openSampleWorkbook("resize_compare.xlsx"); + XSSFDrawing dp = wb.getSheetAt(0).createDrawingPatriarch(); + List<XSSFShape> pics = dp.getShapes(); + XSSFPicture inpPic = (XSSFPicture)pics.get(0); + XSSFPicture cmpPic = (XSSFPicture)pics.get(0); + + baseTestResize(inpPic, cmpPic, 2.0, 2.0); + wb.close(); } - public void testCreate(){ + @Test + public void create() throws IOException { XSSFWorkbook wb = new XSSFWorkbook(); XSSFSheet sheet = wb.createSheet(); XSSFDrawing drawing = sheet.createDrawingPatriarch(); @@ -70,6 +91,8 @@ public final class TestXSSFPicture extends BaseTestPicture { CTTwoCellAnchor ctShapeHolder = drawing.getCTDrawing().getTwoCellAnchorArray(0); // STEditAs.ABSOLUTE corresponds to ClientAnchor.DONT_MOVE_AND_RESIZE assertEquals(STEditAs.ABSOLUTE, ctShapeHolder.getEditAs()); + + wb.close(); } /** @@ -77,7 +100,8 @@ public final class TestXSSFPicture extends BaseTestPicture { * * See Bugzilla 50458 */ - public void testShapeId(){ + @Test + public void incrementShapeId() throws IOException { XSSFWorkbook wb = new XSSFWorkbook(); XSSFSheet sheet = wb.createSheet(); XSSFDrawing drawing = sheet.createDrawingPatriarch(); @@ -93,12 +117,15 @@ public final class TestXSSFPicture extends BaseTestPicture { jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); XSSFPicture shape2 = drawing.createPicture(anchor, jpegIdx); assertEquals(2, shape2.getCTPicture().getNvPicPr().getCNvPr().getId()); + wb.close(); } /** * same image refrerred by mulitple sheets */ - public void testMultiRelationShips(){ + @SuppressWarnings("resource") + @Test + public void multiRelationShips() throws IOException { XSSFWorkbook wb = new XSSFWorkbook(); byte[] pic1Data = "test jpeg data".getBytes(); @@ -140,6 +167,7 @@ public final class TestXSSFPicture extends BaseTestPicture { XSSFPicture shape44 = (XSSFPicture)drawing2.getShapes().get(1); assertArrayEquals(shape4.getPictureData().getData(), shape44.getPictureData().getData()); + wb.close(); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java index 132a45af5c..7a1ae1f1b6 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java @@ -18,7 +18,10 @@ package org.apache.poi.hssf.usermodel; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.util.List; @@ -32,6 +35,8 @@ import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.PictureData; import org.apache.poi.ss.usermodel.Workbook; +import org.junit.Test; +import org.junit.Ignore; /** * Test <code>HSSFPicture</code>. @@ -44,14 +49,23 @@ public final class TestHSSFPicture extends BaseTestPicture { super(HSSFITestDataProvider.instance); } - public void testResize() { - baseTestResize(new HSSFClientAnchor(0, 0, 848, 240, (short)0, 0, (short)1, 9)); + @Test + public void resize() throws Exception { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("resize_compare.xls"); + HSSFPatriarch dp = wb.getSheetAt(0).createDrawingPatriarch(); + List<HSSFShape> pics = dp.getChildren(); + HSSFPicture inpPic = (HSSFPicture)pics.get(0); + HSSFPicture cmpPic = (HSSFPicture)pics.get(1); + + baseTestResize(inpPic, cmpPic, 2.0, 2.0); + wb.close(); } - + /** * Bug # 45829 reported ArithmeticException (/ by zero) when resizing png with zero DPI. */ - public void test45829() { + @Test + public void bug45829() throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sh1 = wb.createSheet(); HSSFPatriarch p1 = sh1.createDrawingPatriarch(); @@ -60,10 +74,14 @@ public final class TestHSSFPicture extends BaseTestPicture { int idx1 = wb.addPicture( pictureData, HSSFWorkbook.PICTURE_TYPE_PNG ); HSSFPicture pic = p1.createPicture(new HSSFClientAnchor(), idx1); pic.resize(); + + wb.close(); } - public void testAddPictures(){ + @SuppressWarnings("resource") + @Test + public void addPictures() throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sh = wb.createSheet("Pictures"); @@ -154,9 +172,13 @@ public final class TestHSSFPicture extends BaseTestPicture { assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData()); assertArrayEquals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData()); assertArrayEquals(data4, ((HSSFPicture)dr.getChildren().get(3)).getPictureData().getData()); + + wb.close(); } - public void testBSEPictureRef(){ + @SuppressWarnings("unused") + @Test + public void bsePictureRef() throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sh = wb.createSheet("Pictures"); @@ -180,9 +202,12 @@ public final class TestHSSFPicture extends BaseTestPicture { HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor()); gr.createPicture(new HSSFChildAnchor(), idx1); assertEquals(bse.getRef(), 3); + + wb.close(); } - public void testReadExistingImage(){ + @Test + public void readExistingImage(){ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls"); HSSFSheet sheet = wb.getSheet("picture"); HSSFPatriarch drawing = sheet.getDrawingPatriarch(); @@ -192,7 +217,9 @@ public final class TestHSSFPicture extends BaseTestPicture { assertEquals(picture.getFileName(), "test"); } - public void testSetGetProperties(){ + @SuppressWarnings("resource") + @Test + public void setGetProperties() throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sh = wb.createSheet("Pictures"); @@ -214,9 +241,12 @@ public final class TestHSSFPicture extends BaseTestPicture { p1 = (HSSFPicture) dr.getChildren().get(0); assertEquals(p1.getFileName(), "aaa"); + wb.close(); } - public void test49658() throws IOException { + @SuppressWarnings("resource") + @Test + public void bug49658() throws IOException { // test if inserted EscherMetafileBlip will be read again HSSFWorkbook wb = new HSSFWorkbook(); @@ -262,6 +292,7 @@ public final class TestHSSFPicture extends BaseTestPicture { pictureDataOut = wb.getAllPictures().get(2).getData(); assertArrayEquals(wmfNoHeader, pictureDataOut); + wb.close(); } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestPicture.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestPicture.java index b19513759d..22247ebdf7 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestPicture.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestPicture.java @@ -17,14 +17,19 @@ package org.apache.poi.ss.usermodel; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import java.awt.Dimension; +import java.io.FileOutputStream; import org.apache.poi.ss.ITestDataProvider; +import org.apache.poi.ss.util.ImageUtils; +import org.apache.poi.util.Units; /** * @author Yegor Kozlov */ -public abstract class BaseTestPicture extends TestCase { +public abstract class BaseTestPicture { private final ITestDataProvider _testDataProvider; @@ -32,26 +37,32 @@ public abstract class BaseTestPicture extends TestCase { _testDataProvider = testDataProvider; } - public void baseTestResize(ClientAnchor referenceAnchor) { - Workbook wb = _testDataProvider.createWorkbook(); - Sheet sh1 = wb.createSheet(); - Drawing p1 = sh1.createDrawingPatriarch(); - CreationHelper factory = wb.getCreationHelper(); - - byte[] pictureData = _testDataProvider.getTestDataFileContent("logoKarmokar4.png"); - int idx1 = wb.addPicture( pictureData, Workbook.PICTURE_TYPE_PNG ); - Picture picture = p1.createPicture(factory.createClientAnchor(), idx1); - picture.resize(); - ClientAnchor anchor1 = picture.getPreferredSize(); - - //assert against what would BiffViewer print if we insert the image in xls and dump the file - assertEquals(referenceAnchor.getCol1(), anchor1.getCol1()); - assertEquals(referenceAnchor.getRow1(), anchor1.getRow1()); - assertEquals(referenceAnchor.getCol2(), anchor1.getCol2()); - assertEquals(referenceAnchor.getRow2(), anchor1.getRow2()); - assertEquals(referenceAnchor.getDx1(), anchor1.getDx1()); - assertEquals(referenceAnchor.getDy1(), anchor1.getDy1()); - assertEquals(referenceAnchor.getDx2(), anchor1.getDx2()); - assertEquals(referenceAnchor.getDy2(), anchor1.getDy2()); + public void baseTestResize(Picture input, Picture compare, double scaleX, double scaleY) { + input.resize(scaleX, scaleY); + + ClientAnchor inpCA = input.getClientAnchor(); + ClientAnchor cmpCA = compare.getClientAnchor(); + + Dimension inpDim = ImageUtils.getDimensionFromAnchor(input); + Dimension cmpDim = ImageUtils.getDimensionFromAnchor(compare); + + double emuPX = Units.EMU_PER_PIXEL; + + assertEquals("the image height differs", inpDim.getHeight(), cmpDim.getHeight(), emuPX*6); + assertEquals("the image width differs", inpDim.getWidth(), cmpDim.getWidth(), emuPX*6); + assertEquals("the starting column differs", inpCA.getCol1(), cmpCA.getCol1()); + assertEquals("the column x-offset differs", inpCA.getDx1(), cmpCA.getDx1(), 1); + assertEquals("the column y-offset differs", inpCA.getDy1(), cmpCA.getDy1(), 1); + assertEquals("the ending columns differs", inpCA.getCol2(), cmpCA.getCol2()); + // can't compare row heights because of variable test heights + + input.resize(); + inpDim = ImageUtils.getDimensionFromAnchor(input); + + Dimension imgDim = input.getImageDimension(); + + assertEquals("the image height differs", imgDim.getHeight(), inpDim.getHeight()/emuPX, 1); + assertEquals("the image width differs", imgDim.getWidth(), inpDim.getWidth()/emuPX, 1); } + } diff --git a/test-data/spreadsheet/resize_compare.xls b/test-data/spreadsheet/resize_compare.xls Binary files differnew file mode 100644 index 0000000000..c41cc4b15d --- /dev/null +++ b/test-data/spreadsheet/resize_compare.xls diff --git a/test-data/spreadsheet/resize_compare.xlsx b/test-data/spreadsheet/resize_compare.xlsx Binary files differnew file mode 100644 index 0000000000..7fb4437fe8 --- /dev/null +++ b/test-data/spreadsheet/resize_compare.xlsx |