https://bz.apache.org/bugzilla/show_bug.cgi?id=59753
Bug ID: 59753
Summary: The XSSFPicture.getPreferredSize returns incorrect
anchor col2 and row2 due to error in
ImageUtils.setPreferredSize
Product: POI
Version: 3.14-FINAL
Hardware: PC
OS: Linux
Status: NEW
Severity: major
Priority: P2
Component: XSSF
Assignee: [email protected]
Reporter: [email protected]
Created attachment 33986
--> https://bz.apache.org/bugzilla/attachment.cgi?id=33986&action=edit
test.png
If I do the following:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
byte[] imageBytes = org.apache.commons.io.IOUtils.toByteArray(new
FileInputStream(test.png));
Drawing drawing = sheet.createDrawingPatriarch();
int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_PNG);
CreationHelper helper = workbook.getCreationHelper();
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(0); // Not needed, but let's make sure we are in the upper
left
anchor.setRow1(0); // corner of the spreadsheet.
Picture pict = drawing.createPicture(anchor, pictureIdx);
anchor.pict.getPreferredSize(); //This will return 1 and 1 for col2/row2
pict.resize(0.75); //This will return 0 and 0 for col2/row2
int lastColumn = anchor.getCol2();
int lastRow = anchor.getRow2();
The last row and column are useful for placing other data below or beside the
image. The byte array is used to get an image stored in memory and not on the
file system.
ImageUtils.setPreferredSize snippet for col2:
// 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 *= 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);
This is the snippet from XSSFPicture.getPreferredSize in 3.8:
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);
Also please note as you debug that the scaledWidth and scaledHeight in 3.14 end
up being almost identical to the value returned from columnWidthInPixels. The
columnWidthInPixels is ~6 pixels smaller that the 3.8 version. The 3.8 version
increments the columns with a check of w against the number of pixels in the
width of the picture. So you end up with an image that is always squeezed into
a single cell.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]