git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1875266 13f79535-47bb-0310-9956-ffa450edef68tags/before_ooxml_3rd_edition
@@ -24,6 +24,8 @@ import java.io.ByteArrayInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Iterator; | |||
import java.util.function.Consumer; | |||
import java.util.function.Function; | |||
import javax.imageio.ImageIO; | |||
import javax.imageio.ImageReader; | |||
@@ -38,18 +40,26 @@ 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.Removal; | |||
import org.apache.poi.util.Units; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.NodeList; | |||
/** | |||
* @author Yegor Kozlov | |||
*/ | |||
public class ImageUtils { | |||
public final class ImageUtils { | |||
private static final POILogger logger = POILogFactory.getLogger(ImageUtils.class); | |||
/** | |||
* @deprecated use {@link Units#PIXEL_DPI} | |||
*/ | |||
@Deprecated | |||
@Removal(version = "5.0.0") | |||
public static final int PIXEL_DPI = 96; | |||
private static final int WIDTH_UNITS = 1024; | |||
private static final int HEIGHT_UNITS = 256; | |||
private ImageUtils() {} | |||
/** | |||
* Return the dimension of this image | |||
* | |||
@@ -82,11 +92,11 @@ public class ImageUtils { | |||
//if DPI is zero then assume standard 96 DPI | |||
//since cannot divide by zero | |||
if (dpi[0] == 0) dpi[0] = PIXEL_DPI; | |||
if (dpi[1] == 0) dpi[1] = PIXEL_DPI; | |||
if (dpi[0] == 0) dpi[0] = Units.PIXEL_DPI; | |||
if (dpi[1] == 0) dpi[1] = Units.PIXEL_DPI; | |||
size.width = img.getWidth()*PIXEL_DPI/dpi[0]; | |||
size.height = img.getHeight()*PIXEL_DPI/dpi[1]; | |||
size.width = img.getWidth()*Units.PIXEL_DPI/dpi[0]; | |||
size.height = img.getHeight()*Units.PIXEL_DPI/dpi[1]; | |||
} finally { | |||
r.dispose(); | |||
} | |||
@@ -148,76 +158,25 @@ public class ImageUtils { | |||
Sheet sheet = picture.getSheet(); | |||
// in pixel | |||
Dimension imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType()); | |||
final Dimension imgSize = (scaleX == Double.MAX_VALUE || scaleY == Double.MAX_VALUE) | |||
? getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType()) | |||
: new Dimension(); | |||
// in emus | |||
Dimension anchorSize = ImageUtils.getDimensionFromAnchor(picture); | |||
final Dimension anchorSize = (scaleX != Double.MAX_VALUE || scaleY != Double.MAX_VALUE) | |||
? ImageUtils.getDimensionFromAnchor(picture) | |||
: new Dimension(); | |||
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 *= 1d - anchor.getDx1()/1024d; | |||
} else { | |||
w -= anchor.getDx1()/(double)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()/(double)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; | |||
} | |||
} | |||
scaleCell(scaledWidth, anchor.getCol1(), anchor.getDx1(), anchor::setCol2, anchor::setDx2, | |||
isHSSF ? WIDTH_UNITS : 0, sheet::getColumnWidthInPixels); | |||
anchor.setRow2(row2); | |||
anchor.setDy2(dy2); | |||
scaleCell(scaledHeight, anchor.getRow1(), anchor.getDy1(), anchor::setRow2, anchor::setDy2, | |||
isHSSF ? HEIGHT_UNITS : 0, (row) -> getRowHeightInPixels(sheet, row)); | |||
return new Dimension( | |||
(int)Math.round(scaledWidth*EMU_PER_PIXEL), | |||
@@ -236,57 +195,100 @@ public class ImageUtils { | |||
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()/(double)EMU_PER_PIXEL; | |||
// default to image size (in pixel), if the anchor is only specified for Col1/Row1 | |||
Dimension imgSize = null; | |||
if (anchor.getCol2() < anchor.getCol1() || anchor.getRow2() < anchor.getRow1()) { | |||
PictureData data = picture.getPictureData(); | |||
imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType()); | |||
} | |||
while(col2 < anchor.getCol2()){ | |||
w += sheet.getColumnWidthInPixels(col2++); | |||
} | |||
int w = getDimFromCell(imgSize == null ? 0 : imgSize.getWidth(), anchor.getCol1(), anchor.getDx1(), anchor.getCol2(), anchor.getDx2(), | |||
isHSSF ? WIDTH_UNITS : 0, sheet::getColumnWidthInPixels); | |||
if (isHSSF) { | |||
w += anchor.getDx2()/1024d * sheet.getColumnWidthInPixels(col2); | |||
} else { | |||
w += anchor.getDx2()/(double)EMU_PER_PIXEL; | |||
} | |||
int h = getDimFromCell(imgSize == null ? 0 : imgSize.getHeight(), anchor.getRow1(), anchor.getDy1(), anchor.getRow2(), anchor.getDy2(), | |||
isHSSF ? HEIGHT_UNITS : 0, (row) -> getRowHeightInPixels(sheet, row)); | |||
double h = 0; | |||
int row2 = anchor.getRow1(); | |||
return new Dimension(w, h); | |||
} | |||
h = getRowHeightInPixels(sheet,row2++); | |||
if (isHSSF) { | |||
h *= 1 - anchor.getDy1()/256d; | |||
} else { | |||
h -= anchor.getDy1()/(double)EMU_PER_PIXEL; | |||
public static double getRowHeightInPixels(Sheet sheet, int rowNum) { | |||
Row r = sheet.getRow(rowNum); | |||
double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints(); | |||
return Units.toEMU(points)/(double)EMU_PER_PIXEL; | |||
} | |||
private static void scaleCell(final double targetSize, | |||
final int startCell, | |||
final int startD, | |||
Consumer<Integer> endCell, | |||
Consumer<Integer> endD, | |||
final int hssfUnits, | |||
Function<Integer,Number> nextSize) { | |||
if (targetSize < 0) { | |||
throw new IllegalArgumentException("target size < 0"); | |||
} | |||
while(row2 < anchor.getRow2()){ | |||
h += getRowHeightInPixels(sheet,row2++); | |||
int cellIdx = startCell; | |||
double dim, delta; | |||
for (double totalDim = 0, remDim;; cellIdx++, totalDim += remDim) { | |||
dim = nextSize.apply(cellIdx).doubleValue(); | |||
remDim = dim; | |||
if (cellIdx == startCell) { | |||
if (hssfUnits > 0) { | |||
remDim *= 1 - startD/(double)hssfUnits; | |||
} else { | |||
remDim -= startD/(double)EMU_PER_PIXEL; | |||
} | |||
} | |||
delta = targetSize - totalDim; | |||
if (delta < remDim) { | |||
break; | |||
} | |||
} | |||
if (isHSSF) { | |||
h += getRowHeightInPixels(sheet,row2) * anchor.getDy2()/256; | |||
double endDval; | |||
if (hssfUnits > 0) { | |||
endDval = delta/dim * (double)hssfUnits; | |||
} else { | |||
h += anchor.getDy2()/(double)EMU_PER_PIXEL; | |||
endDval = delta * EMU_PER_PIXEL; | |||
} | |||
if (cellIdx == startCell) { | |||
endDval += startD; | |||
} | |||
w *= EMU_PER_PIXEL; | |||
h *= EMU_PER_PIXEL; | |||
return new Dimension((int)Math.rint(w), (int)Math.rint(h)); | |||
endCell.accept(cellIdx); | |||
endD.accept((int)Math.rint(endDval)); | |||
} | |||
private static int getDimFromCell(double imgSize, int startCell, int startD, int endCell, int endD, int hssfUnits, | |||
Function<Integer,Number> nextSize) { | |||
double targetSize; | |||
if (endCell < startCell) { | |||
targetSize = imgSize * EMU_PER_PIXEL; | |||
} else { | |||
targetSize = 0; | |||
for (int cellIdx = startCell; cellIdx<=endCell; cellIdx++) { | |||
final double dim = nextSize.apply(cellIdx).doubleValue() * EMU_PER_PIXEL; | |||
double leadSpace = 0; | |||
if (cellIdx == startCell) { | |||
//space in the leftmost cell | |||
leadSpace = (hssfUnits > 0) | |||
? dim * startD/(double)hssfUnits | |||
: startD; | |||
} | |||
public static double getRowHeightInPixels(Sheet sheet, int rowNum) { | |||
Row r = sheet.getRow(rowNum); | |||
double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints(); | |||
return Units.toEMU(points)/(double)EMU_PER_PIXEL; | |||
double trailSpace = 0; | |||
if (cellIdx == endCell) { | |||
// space after the rightmost cell | |||
trailSpace = (hssfUnits > 0) | |||
? dim * (hssfUnits-endD)/(double)hssfUnits | |||
: dim - endD; | |||
} | |||
targetSize += dim - leadSpace - trailSpace; | |||
} | |||
} | |||
return (int)Math.rint(targetSize); | |||
} | |||
} |
@@ -17,7 +17,9 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import static org.junit.Assert.*; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import java.io.IOException; | |||
import java.util.List; | |||
@@ -31,59 +33,56 @@ import org.junit.Test; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs; | |||
/** | |||
* @author Yegor Kozlov | |||
*/ | |||
public final class TestXSSFPicture extends BaseTestPicture { | |||
public TestXSSFPicture() { | |||
super(XSSFITestDataProvider.instance); | |||
} | |||
@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(); | |||
try (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); | |||
} | |||
} | |||
@Test | |||
public void create() throws IOException { | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
byte[] jpegData = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); | |||
List<XSSFPictureData> pictures = wb.getAllPictures(); | |||
assertEquals(0, pictures.size()); | |||
int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
assertEquals(1, pictures.size()); | |||
assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); | |||
assertArrayEquals(jpegData, pictures.get(jpegIdx).getData()); | |||
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); | |||
assertEquals(AnchorType.MOVE_AND_RESIZE, anchor.getAnchorType()); | |||
anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE); | |||
assertEquals(AnchorType.DONT_MOVE_AND_RESIZE, anchor.getAnchorType()); | |||
XSSFPicture shape = drawing.createPicture(anchor, jpegIdx); | |||
assertEquals(anchor, shape.getAnchor()); | |||
assertNotNull(shape.getPictureData()); | |||
assertArrayEquals(jpegData, shape.getPictureData().getData()); | |||
CTTwoCellAnchor ctShapeHolder = drawing.getCTDrawing().getTwoCellAnchorArray(0); | |||
// STEditAs.ABSOLUTE corresponds to ClientAnchor.DONT_MOVE_AND_RESIZE | |||
assertEquals(STEditAs.ABSOLUTE, ctShapeHolder.getEditAs()); | |||
wb.close(); | |||
try (XSSFWorkbook wb = new XSSFWorkbook()) { | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
byte[] jpegData = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); | |||
List<XSSFPictureData> pictures = wb.getAllPictures(); | |||
assertEquals(0, pictures.size()); | |||
int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
assertEquals(1, pictures.size()); | |||
assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); | |||
assertArrayEquals(jpegData, pictures.get(jpegIdx).getData()); | |||
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); | |||
assertEquals(AnchorType.MOVE_AND_RESIZE, anchor.getAnchorType()); | |||
anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE); | |||
assertEquals(AnchorType.DONT_MOVE_AND_RESIZE, anchor.getAnchorType()); | |||
XSSFPicture shape = drawing.createPicture(anchor, jpegIdx); | |||
assertEquals(anchor, shape.getAnchor()); | |||
assertNotNull(shape.getPictureData()); | |||
assertArrayEquals(jpegData, shape.getPictureData().getData()); | |||
CTTwoCellAnchor ctShapeHolder = drawing.getCTDrawing().getTwoCellAnchorArray(0); | |||
// STEditAs.ABSOLUTE corresponds to ClientAnchor.DONT_MOVE_AND_RESIZE | |||
assertEquals(STEditAs.ABSOLUTE, ctShapeHolder.getEditAs()); | |||
} | |||
} | |||
/** | |||
@@ -93,71 +92,69 @@ public final class TestXSSFPicture extends BaseTestPicture { | |||
*/ | |||
@Test | |||
public void incrementShapeId() throws IOException { | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); | |||
byte[] jpegData = "picture1".getBytes(LocaleUtil.CHARSET_1252); | |||
int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
XSSFPicture shape1 = drawing.createPicture(anchor, jpegIdx); | |||
assertEquals(1, shape1.getCTPicture().getNvPicPr().getCNvPr().getId()); | |||
jpegData = "picture2".getBytes(LocaleUtil.CHARSET_1252); | |||
jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
XSSFPicture shape2 = drawing.createPicture(anchor, jpegIdx); | |||
assertEquals(2, shape2.getCTPicture().getNvPicPr().getCNvPr().getId()); | |||
wb.close(); | |||
try (XSSFWorkbook wb = new XSSFWorkbook()) { | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); | |||
byte[] jpegData = "picture1".getBytes(LocaleUtil.CHARSET_1252); | |||
int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
XSSFPicture shape1 = drawing.createPicture(anchor, jpegIdx); | |||
assertEquals(1, shape1.getCTPicture().getNvPicPr().getCNvPr().getId()); | |||
jpegData = "picture2".getBytes(LocaleUtil.CHARSET_1252); | |||
jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
XSSFPicture shape2 = drawing.createPicture(anchor, jpegIdx); | |||
assertEquals(2, shape2.getCTPicture().getNvPicPr().getCNvPr().getId()); | |||
} | |||
} | |||
/** | |||
* same image refrerred by mulitple sheets | |||
*/ | |||
@SuppressWarnings("resource") | |||
@Test | |||
public void multiRelationShips() throws IOException { | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
byte[] pic1Data = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); | |||
byte[] pic2Data = "test png data".getBytes(LocaleUtil.CHARSET_1252); | |||
List<XSSFPictureData> pictures = wb.getAllPictures(); | |||
assertEquals(0, pictures.size()); | |||
int pic1 = wb.addPicture(pic1Data, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
int pic2 = wb.addPicture(pic2Data, XSSFWorkbook.PICTURE_TYPE_PNG); | |||
XSSFSheet sheet1 = wb.createSheet(); | |||
XSSFDrawing drawing1 = sheet1.createDrawingPatriarch(); | |||
XSSFPicture shape1 = drawing1.createPicture(new XSSFClientAnchor(), pic1); | |||
XSSFPicture shape2 = drawing1.createPicture(new XSSFClientAnchor(), pic2); | |||
XSSFSheet sheet2 = wb.createSheet(); | |||
XSSFDrawing drawing2 = sheet2.createDrawingPatriarch(); | |||
XSSFPicture shape3 = drawing2.createPicture(new XSSFClientAnchor(), pic2); | |||
XSSFPicture shape4 = drawing2.createPicture(new XSSFClientAnchor(), pic1); | |||
assertEquals(2, pictures.size()); | |||
wb = XSSFTestDataSamples.writeOutAndReadBack(wb); | |||
pictures = wb.getAllPictures(); | |||
assertEquals(2, pictures.size()); | |||
sheet1 = wb.getSheetAt(0); | |||
drawing1 = sheet1.createDrawingPatriarch(); | |||
XSSFPicture shape11 = (XSSFPicture)drawing1.getShapes().get(0); | |||
assertArrayEquals(shape1.getPictureData().getData(), shape11.getPictureData().getData()); | |||
XSSFPicture shape22 = (XSSFPicture)drawing1.getShapes().get(1); | |||
assertArrayEquals(shape2.getPictureData().getData(), shape22.getPictureData().getData()); | |||
sheet2 = wb.getSheetAt(1); | |||
drawing2 = sheet2.createDrawingPatriarch(); | |||
XSSFPicture shape33 = (XSSFPicture)drawing2.getShapes().get(0); | |||
assertArrayEquals(shape3.getPictureData().getData(), shape33.getPictureData().getData()); | |||
XSSFPicture shape44 = (XSSFPicture)drawing2.getShapes().get(1); | |||
assertArrayEquals(shape4.getPictureData().getData(), shape44.getPictureData().getData()); | |||
wb.close(); | |||
try (XSSFWorkbook wb1 = new XSSFWorkbook()) { | |||
byte[] pic1Data = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); | |||
byte[] pic2Data = "test png data".getBytes(LocaleUtil.CHARSET_1252); | |||
List<XSSFPictureData> pictures = wb1.getAllPictures(); | |||
assertEquals(0, pictures.size()); | |||
int pic1 = wb1.addPicture(pic1Data, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
int pic2 = wb1.addPicture(pic2Data, XSSFWorkbook.PICTURE_TYPE_PNG); | |||
XSSFSheet sheet1 = wb1.createSheet(); | |||
XSSFDrawing drawing1 = sheet1.createDrawingPatriarch(); | |||
XSSFPicture shape1 = drawing1.createPicture(new XSSFClientAnchor(), pic1); | |||
XSSFPicture shape2 = drawing1.createPicture(new XSSFClientAnchor(), pic2); | |||
XSSFSheet sheet2 = wb1.createSheet(); | |||
XSSFDrawing drawing2 = sheet2.createDrawingPatriarch(); | |||
XSSFPicture shape3 = drawing2.createPicture(new XSSFClientAnchor(), pic2); | |||
XSSFPicture shape4 = drawing2.createPicture(new XSSFClientAnchor(), pic1); | |||
assertEquals(2, pictures.size()); | |||
try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1)) { | |||
pictures = wb2.getAllPictures(); | |||
assertEquals(2, pictures.size()); | |||
sheet1 = wb2.getSheetAt(0); | |||
drawing1 = sheet1.createDrawingPatriarch(); | |||
XSSFPicture shape11 = (XSSFPicture) drawing1.getShapes().get(0); | |||
assertArrayEquals(shape1.getPictureData().getData(), shape11.getPictureData().getData()); | |||
XSSFPicture shape22 = (XSSFPicture) drawing1.getShapes().get(1); | |||
assertArrayEquals(shape2.getPictureData().getData(), shape22.getPictureData().getData()); | |||
sheet2 = wb2.getSheetAt(1); | |||
drawing2 = sheet2.createDrawingPatriarch(); | |||
XSSFPicture shape33 = (XSSFPicture) drawing2.getShapes().get(0); | |||
assertArrayEquals(shape3.getPictureData().getData(), shape33.getPictureData().getData()); | |||
XSSFPicture shape44 = (XSSFPicture) drawing2.getShapes().get(1); | |||
assertArrayEquals(shape4.getPictureData().getData(), shape44.getPictureData().getData()); | |||
} | |||
} | |||
} | |||
} |
@@ -35,11 +35,6 @@ import org.apache.poi.ss.usermodel.PictureData; | |||
import org.apache.poi.ss.usermodel.Workbook; | |||
import org.junit.Test; | |||
/** | |||
* Test <code>HSSFPicture</code>. | |||
* | |||
* @author Yegor Kozlov (yegor at apache.org) | |||
*/ | |||
public final class TestHSSFPicture extends BaseTestPicture { | |||
public TestHSSFPicture() { | |||
@@ -48,248 +43,248 @@ public final class TestHSSFPicture extends BaseTestPicture { | |||
@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(); | |||
try (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); | |||
} | |||
} | |||
/** | |||
* Bug # 45829 reported ArithmeticException (/ by zero) when resizing png with zero DPI. | |||
*/ | |||
@Test | |||
public void bug45829() throws IOException { | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
HSSFSheet sh1 = wb.createSheet(); | |||
HSSFPatriarch p1 = sh1.createDrawingPatriarch(); | |||
byte[] pictureData = HSSFTestDataSamples.getTestDataFileContent("45829.png"); | |||
int idx1 = wb.addPicture( pictureData, HSSFWorkbook.PICTURE_TYPE_PNG ); | |||
HSSFPicture pic = p1.createPicture(new HSSFClientAnchor(), idx1); | |||
pic.resize(); | |||
wb.close(); | |||
try (HSSFWorkbook wb = new HSSFWorkbook()) { | |||
HSSFSheet sh1 = wb.createSheet(); | |||
HSSFPatriarch p1 = sh1.createDrawingPatriarch(); | |||
byte[] pictureData = HSSFTestDataSamples.getTestDataFileContent("45829.png"); | |||
int idx1 = wb.addPicture(pictureData, HSSFWorkbook.PICTURE_TYPE_PNG); | |||
HSSFPicture pic = p1.createPicture(new HSSFClientAnchor(), idx1); | |||
pic.resize(); | |||
} | |||
} | |||
@SuppressWarnings("resource") | |||
@Test | |||
public void addPictures() throws IOException { | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
HSSFSheet sh = wb.createSheet("Pictures"); | |||
HSSFPatriarch dr = sh.createDrawingPatriarch(); | |||
assertEquals(0, dr.getChildren().size()); | |||
HSSFClientAnchor anchor = wb.getCreationHelper().createClientAnchor(); | |||
//register a picture | |||
byte[] data1 = new byte[]{1, 2, 3}; | |||
int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(1, idx1); | |||
HSSFPicture p1 = dr.createPicture(anchor, idx1); | |||
assertArrayEquals(data1, p1.getPictureData().getData()); | |||
// register another one | |||
byte[] data2 = new byte[]{4, 5, 6}; | |||
int idx2 = wb.addPicture(data2, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(2, idx2); | |||
HSSFPicture p2 = dr.createPicture(anchor, idx2); | |||
assertEquals(2, dr.getChildren().size()); | |||
assertArrayEquals(data2, p2.getPictureData().getData()); | |||
// confirm that HSSFPatriarch.getChildren() returns two picture shapes | |||
assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData()); | |||
assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData()); | |||
// write, read back and verify that our pictures are there | |||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
List<? extends PictureData> lst2 = wb.getAllPictures(); | |||
assertEquals(2, lst2.size()); | |||
assertArrayEquals(data1, lst2.get(0).getData()); | |||
assertArrayEquals(data2, lst2.get(1).getData()); | |||
// confirm that the pictures are in the Sheet's drawing | |||
sh = wb.getSheet("Pictures"); | |||
dr = sh.createDrawingPatriarch(); | |||
assertEquals(2, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData()); | |||
assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData()); | |||
// add a third picture | |||
byte[] data3 = new byte[]{7, 8, 9}; | |||
// picture index must increment across write-read | |||
int idx3 = wb.addPicture(data3, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(3, idx3); | |||
HSSFPicture p3 = dr.createPicture(anchor, idx3); | |||
assertArrayEquals(data3, p3.getPictureData().getData()); | |||
assertEquals(3, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData()); | |||
assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData()); | |||
assertArrayEquals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData()); | |||
// write and read again | |||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
List<? extends PictureData> lst3 = wb.getAllPictures(); | |||
// all three should be there | |||
assertEquals(3, lst3.size()); | |||
assertArrayEquals(data1, lst3.get(0).getData()); | |||
assertArrayEquals(data2, lst3.get(1).getData()); | |||
assertArrayEquals(data3, lst3.get(2).getData()); | |||
sh = wb.getSheet("Pictures"); | |||
dr = sh.createDrawingPatriarch(); | |||
assertEquals(3, dr.getChildren().size()); | |||
// forth picture | |||
byte[] data4 = new byte[]{10, 11, 12}; | |||
int idx4 = wb.addPicture(data4, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(4, idx4); | |||
dr.createPicture(anchor, idx4); | |||
assertEquals(4, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData()); | |||
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 = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
List<? extends PictureData> lst4 = wb.getAllPictures(); | |||
assertEquals(4, lst4.size()); | |||
assertArrayEquals(data1, lst4.get(0).getData()); | |||
assertArrayEquals(data2, lst4.get(1).getData()); | |||
assertArrayEquals(data3, lst4.get(2).getData()); | |||
assertArrayEquals(data4, lst4.get(3).getData()); | |||
sh = wb.getSheet("Pictures"); | |||
dr = sh.createDrawingPatriarch(); | |||
assertEquals(4, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData()); | |||
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(); | |||
try (HSSFWorkbook wb1 = new HSSFWorkbook()) { | |||
HSSFSheet sh = wb1.createSheet("Pictures"); | |||
HSSFPatriarch dr = sh.createDrawingPatriarch(); | |||
assertEquals(0, dr.getChildren().size()); | |||
HSSFClientAnchor anchor = wb1.getCreationHelper().createClientAnchor(); | |||
//register a picture | |||
byte[] data1 = {1, 2, 3}; | |||
int idx1 = wb1.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(1, idx1); | |||
HSSFPicture p1 = dr.createPicture(anchor, idx1); | |||
assertArrayEquals(data1, p1.getPictureData().getData()); | |||
// register another one | |||
byte[] data2 = {4, 5, 6}; | |||
int idx2 = wb1.addPicture(data2, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(2, idx2); | |||
HSSFPicture p2 = dr.createPicture(anchor, idx2); | |||
assertEquals(2, dr.getChildren().size()); | |||
assertArrayEquals(data2, p2.getPictureData().getData()); | |||
// confirm that HSSFPatriarch.getChildren() returns two picture shapes | |||
assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData()); | |||
assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData()); | |||
// write, read back and verify that our pictures are there | |||
try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) { | |||
List<? extends PictureData> lst2 = wb2.getAllPictures(); | |||
assertEquals(2, lst2.size()); | |||
assertArrayEquals(data1, lst2.get(0).getData()); | |||
assertArrayEquals(data2, lst2.get(1).getData()); | |||
// confirm that the pictures are in the Sheet's drawing | |||
sh = wb2.getSheet("Pictures"); | |||
dr = sh.createDrawingPatriarch(); | |||
assertEquals(2, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData()); | |||
assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData()); | |||
// add a third picture | |||
byte[] data3 = {7, 8, 9}; | |||
// picture index must increment across write-read | |||
int idx3 = wb2.addPicture(data3, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(3, idx3); | |||
HSSFPicture p3 = dr.createPicture(anchor, idx3); | |||
assertArrayEquals(data3, p3.getPictureData().getData()); | |||
assertEquals(3, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData()); | |||
assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData()); | |||
assertArrayEquals(data3, ((HSSFPicture) dr.getChildren().get(2)).getPictureData().getData()); | |||
// write and read again | |||
try (HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2)) { | |||
List<? extends PictureData> lst3 = wb3.getAllPictures(); | |||
// all three should be there | |||
assertEquals(3, lst3.size()); | |||
assertArrayEquals(data1, lst3.get(0).getData()); | |||
assertArrayEquals(data2, lst3.get(1).getData()); | |||
assertArrayEquals(data3, lst3.get(2).getData()); | |||
sh = wb3.getSheet("Pictures"); | |||
dr = sh.createDrawingPatriarch(); | |||
assertEquals(3, dr.getChildren().size()); | |||
// forth picture | |||
byte[] data4 = {10, 11, 12}; | |||
int idx4 = wb3.addPicture(data4, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(4, idx4); | |||
dr.createPicture(anchor, idx4); | |||
assertEquals(4, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData()); | |||
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()); | |||
try (HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3)) { | |||
List<? extends PictureData> lst4 = wb4.getAllPictures(); | |||
assertEquals(4, lst4.size()); | |||
assertArrayEquals(data1, lst4.get(0).getData()); | |||
assertArrayEquals(data2, lst4.get(1).getData()); | |||
assertArrayEquals(data3, lst4.get(2).getData()); | |||
assertArrayEquals(data4, lst4.get(3).getData()); | |||
sh = wb4.getSheet("Pictures"); | |||
dr = sh.createDrawingPatriarch(); | |||
assertEquals(4, dr.getChildren().size()); | |||
assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData()); | |||
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()); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@SuppressWarnings("unused") | |||
@Test | |||
public void bsePictureRef() throws IOException { | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
HSSFSheet sh = wb.createSheet("Pictures"); | |||
HSSFPatriarch dr = sh.createDrawingPatriarch(); | |||
HSSFClientAnchor anchor = new HSSFClientAnchor(); | |||
try (HSSFWorkbook wb = new HSSFWorkbook()) { | |||
HSSFSheet sh = wb.createSheet("Pictures"); | |||
HSSFPatriarch dr = sh.createDrawingPatriarch(); | |||
HSSFClientAnchor anchor = new HSSFClientAnchor(); | |||
InternalSheet ish = HSSFTestHelper.getSheetForTest(sh); | |||
InternalSheet ish = HSSFTestHelper.getSheetForTest(sh); | |||
//register a picture | |||
byte[] data1 = new byte[]{1, 2, 3}; | |||
int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(1, idx1); | |||
HSSFPicture p1 = dr.createPicture(anchor, idx1); | |||
//register a picture | |||
byte[] data1 = {1, 2, 3}; | |||
int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); | |||
assertEquals(1, idx1); | |||
HSSFPicture p1 = dr.createPicture(anchor, idx1); | |||
EscherBSERecord bse = wb.getWorkbook().getBSERecord(idx1); | |||
EscherBSERecord bse = wb.getWorkbook().getBSERecord(idx1); | |||
assertEquals(bse.getRef(), 1); | |||
dr.createPicture(new HSSFClientAnchor(), idx1); | |||
assertEquals(bse.getRef(), 2); | |||
assertEquals(bse.getRef(), 1); | |||
dr.createPicture(new HSSFClientAnchor(), idx1); | |||
assertEquals(bse.getRef(), 2); | |||
HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor()); | |||
gr.createPicture(new HSSFChildAnchor(), idx1); | |||
assertEquals(bse.getRef(), 3); | |||
wb.close(); | |||
HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor()); | |||
gr.createPicture(new HSSFChildAnchor(), idx1); | |||
assertEquals(bse.getRef(), 3); | |||
} | |||
} | |||
@Test | |||
public void readExistingImage(){ | |||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls"); | |||
HSSFSheet sheet = wb.getSheet("picture"); | |||
HSSFPatriarch drawing = sheet.getDrawingPatriarch(); | |||
assertEquals(1, drawing.getChildren().size()); | |||
HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0); | |||
assertEquals(picture.getFileName(), "test"); | |||
public void readExistingImage() throws IOException { | |||
try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls")) { | |||
HSSFSheet sheet = wb.getSheet("picture"); | |||
HSSFPatriarch drawing = sheet.getDrawingPatriarch(); | |||
assertEquals(1, drawing.getChildren().size()); | |||
HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0); | |||
assertEquals(picture.getFileName(), "test"); | |||
} | |||
} | |||
@SuppressWarnings("resource") | |||
@Test | |||
public void setGetProperties() throws IOException { | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
try (HSSFWorkbook wb1 = new HSSFWorkbook()) { | |||
HSSFSheet sh = wb.createSheet("Pictures"); | |||
HSSFPatriarch dr = sh.createDrawingPatriarch(); | |||
HSSFClientAnchor anchor = new HSSFClientAnchor(); | |||
HSSFSheet sh = wb1.createSheet("Pictures"); | |||
HSSFPatriarch dr = sh.createDrawingPatriarch(); | |||
HSSFClientAnchor anchor = new HSSFClientAnchor(); | |||
//register a picture | |||
byte[] data1 = new byte[]{1, 2, 3}; | |||
int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); | |||
HSSFPicture p1 = dr.createPicture(anchor, idx1); | |||
//register a picture | |||
byte[] data1 = {1, 2, 3}; | |||
int idx1 = wb1.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); | |||
HSSFPicture p1 = dr.createPicture(anchor, idx1); | |||
assertEquals(p1.getFileName(), ""); | |||
p1.setFileName("aaa"); | |||
assertEquals(p1.getFileName(), "aaa"); | |||
assertEquals(p1.getFileName(), ""); | |||
p1.setFileName("aaa"); | |||
assertEquals(p1.getFileName(), "aaa"); | |||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
sh = wb.getSheet("Pictures"); | |||
dr = sh.getDrawingPatriarch(); | |||
try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) { | |||
sh = wb2.getSheet("Pictures"); | |||
dr = sh.getDrawingPatriarch(); | |||
p1 = (HSSFPicture) dr.getChildren().get(0); | |||
assertEquals(p1.getFileName(), "aaa"); | |||
wb.close(); | |||
p1 = (HSSFPicture) dr.getChildren().get(0); | |||
assertEquals(p1.getFileName(), "aaa"); | |||
} | |||
} | |||
} | |||
@SuppressWarnings("resource") | |||
@Test | |||
public void bug49658() throws IOException { | |||
// test if inserted EscherMetafileBlip will be read again | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
byte[] pictureDataEmf = POIDataSamples.getDocumentInstance().readFile("vector_image.emf"); | |||
int indexEmf = wb.addPicture(pictureDataEmf, HSSFWorkbook.PICTURE_TYPE_EMF); | |||
byte[] pictureDataPng = POIDataSamples.getSpreadSheetInstance().readFile("logoKarmokar4.png"); | |||
int indexPng = wb.addPicture(pictureDataPng, HSSFWorkbook.PICTURE_TYPE_PNG); | |||
byte[] pictureDataWmf = POIDataSamples.getSlideShowInstance().readFile("santa.wmf"); | |||
int indexWmf = wb.addPicture(pictureDataWmf, HSSFWorkbook.PICTURE_TYPE_WMF); | |||
HSSFSheet sheet = wb.createSheet(); | |||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); | |||
CreationHelper ch = wb.getCreationHelper(); | |||
ClientAnchor anchor = ch.createClientAnchor(); | |||
anchor.setCol1(2); | |||
anchor.setCol2(5); | |||
anchor.setRow1(1); | |||
anchor.setRow2(6); | |||
patriarch.createPicture(anchor, indexEmf); | |||
anchor = ch.createClientAnchor(); | |||
anchor.setCol1(2); | |||
anchor.setCol2(5); | |||
anchor.setRow1(10); | |||
anchor.setRow2(16); | |||
patriarch.createPicture(anchor, indexPng); | |||
anchor = ch.createClientAnchor(); | |||
anchor.setCol1(6); | |||
anchor.setCol2(9); | |||
anchor.setRow1(1); | |||
anchor.setRow2(6); | |||
patriarch.createPicture(anchor, indexWmf); | |||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
byte[] pictureDataOut = wb.getAllPictures().get(0).getData(); | |||
assertArrayEquals(pictureDataEmf, pictureDataOut); | |||
byte[] wmfNoHeader = new byte[pictureDataWmf.length - 22]; | |||
System.arraycopy(pictureDataWmf, 22, wmfNoHeader, 0, pictureDataWmf.length-22); | |||
pictureDataOut = wb.getAllPictures().get(2).getData(); | |||
assertArrayEquals(wmfNoHeader, pictureDataOut); | |||
wb.close(); | |||
try (HSSFWorkbook wb1 = new HSSFWorkbook()) { | |||
byte[] pictureDataEmf = POIDataSamples.getDocumentInstance().readFile("vector_image.emf"); | |||
int indexEmf = wb1.addPicture(pictureDataEmf, HSSFWorkbook.PICTURE_TYPE_EMF); | |||
byte[] pictureDataPng = POIDataSamples.getSpreadSheetInstance().readFile("logoKarmokar4.png"); | |||
int indexPng = wb1.addPicture(pictureDataPng, HSSFWorkbook.PICTURE_TYPE_PNG); | |||
byte[] pictureDataWmf = POIDataSamples.getSlideShowInstance().readFile("santa.wmf"); | |||
int indexWmf = wb1.addPicture(pictureDataWmf, HSSFWorkbook.PICTURE_TYPE_WMF); | |||
HSSFSheet sheet = wb1.createSheet(); | |||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); | |||
CreationHelper ch = wb1.getCreationHelper(); | |||
ClientAnchor anchor = ch.createClientAnchor(); | |||
anchor.setCol1(2); | |||
anchor.setCol2(5); | |||
anchor.setRow1(1); | |||
anchor.setRow2(6); | |||
patriarch.createPicture(anchor, indexEmf); | |||
anchor = ch.createClientAnchor(); | |||
anchor.setCol1(2); | |||
anchor.setCol2(5); | |||
anchor.setRow1(10); | |||
anchor.setRow2(16); | |||
patriarch.createPicture(anchor, indexPng); | |||
anchor = ch.createClientAnchor(); | |||
anchor.setCol1(6); | |||
anchor.setCol2(9); | |||
anchor.setRow1(1); | |||
anchor.setRow2(6); | |||
patriarch.createPicture(anchor, indexWmf); | |||
try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) { | |||
byte[] pictureDataOut = wb2.getAllPictures().get(0).getData(); | |||
assertArrayEquals(pictureDataEmf, pictureDataOut); | |||
byte[] wmfNoHeader = new byte[pictureDataWmf.length - 22]; | |||
System.arraycopy(pictureDataWmf, 22, wmfNoHeader, 0, pictureDataWmf.length - 22); | |||
pictureDataOut = wb2.getAllPictures().get(2).getData(); | |||
assertArrayEquals(wmfNoHeader, pictureDataOut); | |||
} | |||
} | |||
} | |||
} |
@@ -17,26 +17,34 @@ | |||
package org.apache.poi.ss.usermodel; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import java.awt.BasicStroke; | |||
import java.awt.Color; | |||
import java.awt.Dimension; | |||
import java.awt.Graphics2D; | |||
import java.awt.Point; | |||
import java.awt.RenderingHints; | |||
import java.awt.geom.Area; | |||
import java.awt.geom.Ellipse2D; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import javax.imageio.ImageIO; | |||
import org.apache.poi.hssf.HSSFITestDataProvider; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import org.apache.poi.ss.ITestDataProvider; | |||
import org.apache.poi.ss.util.ImageUtils; | |||
import org.apache.poi.util.Units; | |||
import org.junit.Test; | |||
/** | |||
* @author Yegor Kozlov | |||
*/ | |||
public abstract class BaseTestPicture { | |||
private final ITestDataProvider _testDataProvider; | |||
@@ -47,15 +55,15 @@ public abstract class BaseTestPicture { | |||
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()); | |||
@@ -63,10 +71,10 @@ public abstract class BaseTestPicture { | |||
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); | |||
@@ -103,29 +111,148 @@ public abstract class BaseTestPicture { | |||
CreationHelper createHelper = wb.getCreationHelper(); | |||
final byte[] bytes = HSSFITestDataProvider.instance.getTestDataFileContent("logoKarmokar4.png"); | |||
row.setHeightInPoints(getImageSize(bytes).y); | |||
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); | |||
//add a picture shape | |||
ClientAnchor anchor = createHelper.createClientAnchor(); | |||
//set top-left corner of the picture, | |||
//subsequent call of Picture#resize() will operate relative to it | |||
anchor.setCol1(0); | |||
anchor.setRow1(0); | |||
Picture pict = drawing.createPicture(anchor, pictureIdx); | |||
//auto-size picture relative to its top-left corner | |||
pict.resize(); | |||
} | |||
private static Point getImageSize( byte [] image) throws IOException { | |||
BufferedImage img = ImageIO.read(new ByteArrayInputStream(image)); | |||
assertNotNull(img); | |||
return new Point(img.getWidth(), img.getHeight()); | |||
} | |||
@Test | |||
public void bug64213() throws IOException { | |||
int[] input = { | |||
200, 50 * 256, -1, | |||
400, 50 * 256, -1, | |||
200, 50 * 256, 200, | |||
400, 50 * 256, 200, | |||
400, 50 * 256, 400, | |||
}; | |||
int[] expXSSF = { | |||
2, 952500, 2, 0, 2, 1905000, 7, 0, | |||
2, 952500, 2, 0, 2, 2857500, 12, 0, | |||
2, 952500, 2, 0, 2, 1905000, 2, 952500, | |||
2, 952500, 2, 0, 2, 2857500, 3, 0, | |||
2, 952500, 2, 0, 2, 2857500, 2, 1905000 | |||
}; | |||
int[] expHSSF = { | |||
2, 292, 2, 0, 2, 584, 7, 226, | |||
2, 292, 2, 0, 2, 877, 13, 196, | |||
2, 292, 2, 0, 2, 584, 2, 128, | |||
2, 292, 2, 0, 2, 877, 3, 0, | |||
2, 292, 2, 0, 2, 877, 2, 128 | |||
}; | |||
int[] expected = "xls".equals(_testDataProvider.getStandardFileNameExtension()) ? expHSSF : expXSSF; | |||
for (int i=0; i<5; i++) { | |||
int[] inp = Arrays.copyOfRange(input, i*3, (i+1)*3); | |||
int[] exp = Arrays.copyOfRange(expected, i*8, (i+1)*8); | |||
int[] act = bug64213Helper(inp[0], inp[1], inp[2]); | |||
assertArrayEquals(exp, act); | |||
} | |||
} | |||
private int[] bug64213Helper(int imgDim, int colWidth, int rowHeight) throws IOException { | |||
final int col1 = 2; | |||
final int dx1Pixel = 100; | |||
final int row1 = 2; | |||
final float scale = 0.5f; | |||
try (Workbook wb = _testDataProvider.createWorkbook()) { | |||
Sheet sheet = wb.createSheet("Sheet1"); | |||
final byte[] bytes = createTestImage(imgDim, imgDim); | |||
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); | |||
sheet.setColumnWidth(col1, colWidth); | |||
float col1px = sheet.getColumnWidthInPixels(col1); | |||
if (rowHeight > -1) { | |||
sheet.createRow(row1).setHeightInPoints((float) Units.pixelToPoints(rowHeight)); | |||
} | |||
//create an anchor with upper left cell column/startRow, only one cell anchor since bottom right depends on resizing | |||
CreationHelper helper = wb.getCreationHelper(); | |||
ClientAnchor anchor = helper.createClientAnchor(); | |||
anchor.setCol1(col1); | |||
if (wb instanceof HSSFWorkbook) { | |||
anchor.setDx1((int)(dx1Pixel * 1024 / col1px)); | |||
} else { | |||
anchor.setDx1(dx1Pixel * Units.EMU_PER_PIXEL); | |||
} | |||
anchor.setRow1(row1); | |||
//create a picture anchored to Col1 and Row1 | |||
Drawing<?> drawing = sheet.createDrawingPatriarch(); | |||
Picture pict = drawing.createPicture(anchor, pictureIdx); | |||
//resize the picture to it's native size | |||
pict.resize(); | |||
//resize the picture scaled proportional | |||
pict.resize(scale); | |||
ClientAnchor anc = (ClientAnchor)pict.getAnchor(); | |||
return new int[]{ | |||
anc.getCol1(), anc.getDx1(), | |||
anc.getRow1(), anc.getDy1(), | |||
anc.getCol2(), anc.getDx2(), | |||
anc.getRow2(), anc.getDy2() | |||
}; | |||
} | |||
} | |||
private static byte[] createTestImage(double width, double height) throws IOException { | |||
BufferedImage bi = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_ARGB); | |||
Graphics2D g = bi.createGraphics(); | |||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); | |||
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); | |||
g.scale((width-1)/width, (height-1)/height); | |||
g.setStroke(new BasicStroke(1)); | |||
double ellSize = 5/6d; | |||
Ellipse2D ell = new Ellipse2D.Double(width * (1-ellSize)/2d, height * (1-ellSize)/2d, width * ellSize, height * ellSize); | |||
Color[] colors = { Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW }; | |||
Rectangle2D rect = new Rectangle2D.Double(); | |||
for (int i=0; i<4; i++) { | |||
rect.setRect(width/2 * (i&1),height/2 * (i>>1&1), width/2, height/2); | |||
Area a = new Area(rect); | |||
a.subtract(new Area(ell)); | |||
g.setPaint(colors[i]); | |||
g.fill(a); | |||
g.setColor(java.awt.Color.BLACK); | |||
g.draw(rect); | |||
} | |||
g.draw(ell); | |||
g.dispose(); | |||
ByteArrayOutputStream bos = new ByteArrayOutputStream(2000); | |||
ImageIO.write(bi, "PNG", bos); | |||
return bos.toByteArray(); | |||
} | |||
} |