git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1638623 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_11_FINAL
@@ -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); | |||
} | |||
@@ -97,6 +92,28 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { | |||
return spContainer; | |||
} | |||
/** | |||
* 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> | |||
@@ -104,42 +121,34 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture { | |||
* 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. | |||
* | |||
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -76,6 +76,16 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { | |||
private static final POILogger log = POILogFactory.getLogger(HSSFSheet.class); | |||
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 | |||
@@ -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 |
@@ -16,6 +16,9 @@ | |||
==================================================================== */ | |||
package org.apache.poi.ss.usermodel; | |||
import java.awt.Dimension; | |||
/** | |||
* Repersents a picture in a SpreadsheetML document | |||
* | |||
@@ -24,33 +27,61 @@ 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 | |||
* | |||
@@ -58,4 +89,14 @@ public interface Picture { | |||
*/ | |||
PictureData getPictureData(); | |||
/** | |||
* @return the anchor that is used by this picture | |||
*/ | |||
ClientAnchor getClientAnchor(); | |||
/** | |||
* @return the sheet which contains the picture | |||
*/ | |||
Sheet getSheet(); | |||
} |
@@ -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(); | |||
} |
@@ -186,11 +186,26 @@ 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 | |||
*/ |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} |
@@ -264,6 +264,19 @@ public class SXSSFSheet implements Sheet, Cloneable | |||
return _sh.getColumnWidth(columnIndex); | |||
} | |||
/** | |||
* 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 |
@@ -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(); | |||
} | |||
/** | |||
@@ -283,6 +244,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 | |||
* | |||
@@ -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(); | |||
} | |||
} |
@@ -704,6 +704,22 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
return (int)(width*256); | |||
} | |||
/** | |||
* 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. | |||
@@ -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). | |||
* |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |