applied fix suggested in bug#46197: missing cast to float resulted in incorect calculation of picture size.Also added Picture.resize(scale)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@718023 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-11-16 13:24:42 +00:00
parent d32368be4a
commit 0ad2331f88
4 changed files with 98 additions and 34 deletions

View File

@ -17,6 +17,9 @@
package org.apache.poi.xssf.usermodel.examples; package org.apache.poi.xssf.usermodel.examples;
import org.apache.poi.xssf.usermodel.*; import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -32,27 +35,34 @@ public class WorkingWithPictures {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
//create a new workbook //create a new workbook
XSSFWorkbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
CreationHelper helper = wb.getCreationHelper();
//add a picture in this workbook. //add a picture in this workbook.
InputStream is = new FileInputStream("lilies.jpg"); InputStream is = new FileInputStream(args[0]);
int pictureIdx = wb.addPicture(is, XSSFWorkbook.PICTURE_TYPE_JPEG); byte[] bytes = IOUtils.toByteArray(is);
is.close(); is.close();
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
//create sheet //create sheet
XSSFSheet sheet = wb.createSheet(); Sheet sheet = wb.createSheet();
//create drawing //create drawing
XSSFDrawing drawing = sheet.createDrawingPatriarch(); Drawing drawing = sheet.createDrawingPatriarch();
//add a picture shape //add a picture shape
XSSFPicture pict = drawing.createPicture(new XSSFClientAnchor(), pictureIdx); ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(1);
anchor.setRow1(1);
Picture pict = drawing.createPicture(anchor, pictureIdx);
//auto-size picture //auto-size picture
pict.resize(); pict.resize(2);
//save workbook //save workbook
FileOutputStream fileOut = new FileOutputStream("xssf-picture.xlsx"); String file = "picture.xls";
if(wb instanceof XSSFWorkbook) file += "x";
FileOutputStream fileOut = new FileOutputStream(file);
wb.write(fileOut); wb.write(fileOut);
fileOut.close(); fileOut.close();

View File

@ -87,15 +87,17 @@ public class HSSFPicture
} }
/** /**
* Reset the image to the original size. * Resize the image
* *
* @since POI 3.0.2 * @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.
*/ */
public void resize(){ public void resize(double scale){
HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor(); HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor();
anchor.setAnchorType(2); anchor.setAnchorType(2);
HSSFClientAnchor pref = getPreferredSize(); HSSFClientAnchor pref = getPreferredSize(scale);
int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1()); int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1()); int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());
@ -109,6 +111,13 @@ public class HSSFPicture
anchor.setDy2(pref.getDy2()); anchor.setDy2(pref.getDy2());
} }
/**
* Reset the image to the original size.
*/
public void resize(){
resize(1.0);
}
/** /**
* Calculate the preferred size for this picture. * Calculate the preferred size for this picture.
* *
@ -116,43 +125,56 @@ public class HSSFPicture
* @since POI 3.0.2 * @since POI 3.0.2
*/ */
public HSSFClientAnchor getPreferredSize(){ public HSSFClientAnchor getPreferredSize(){
return getPreferredSize(1.0);
}
/**
* Calculate the preferred size for this picture.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* @return HSSFClientAnchor with the preferred size for this image
* @since POI 3.0.2
*/
public HSSFClientAnchor getPreferredSize(double scale){
HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor(); HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor();
Dimension size = getImageDimension(); Dimension size = getImageDimension();
double scaledWidth = size.getWidth() * scale;
double scaledHeight = size.getHeight() * scale;
float w = 0; float w = 0;
//space in the leftmost cell //space in the leftmost cell
w += getColumnWidthInPixels(anchor.col1)*(1 - anchor.dx1/1024); w += getColumnWidthInPixels(anchor.col1)*(1 - (float)anchor.dx1/1024);
short col2 = (short)(anchor.col1 + 1); short col2 = (short)(anchor.col1 + 1);
int dx2 = 0; int dx2 = 0;
while(w < size.width){ while(w < scaledWidth){
w += getColumnWidthInPixels(col2++); w += getColumnWidthInPixels(col2++);
} }
if(w > size.width) { if(w > scaledWidth) {
//calculate dx2, offset in the rightmost cell //calculate dx2, offset in the rightmost cell
col2--; col2--;
float cw = getColumnWidthInPixels(col2); double cw = getColumnWidthInPixels(col2);
float delta = w - size.width; double delta = w - scaledWidth;
dx2 = (int)((cw-delta)/cw*1024); dx2 = (int)((cw-delta)/cw*1024);
} }
anchor.col2 = col2; anchor.col2 = col2;
anchor.dx2 = dx2; anchor.dx2 = dx2;
float h = 0; float h = 0;
h += (1 - anchor.dy1/256)* getRowHeightInPixels(anchor.row1); h += (1 - (float)anchor.dy1/256)* getRowHeightInPixels(anchor.row1);
int row2 = anchor.row1 + 1; int row2 = anchor.row1 + 1;
int dy2 = 0; int dy2 = 0;
while(h < size.height){ while(h < scaledHeight){
h += getRowHeightInPixels(row2++); h += getRowHeightInPixels(row2++);
} }
if(h > size.height) { if(h > scaledHeight) {
row2--; row2--;
float ch = getRowHeightInPixels(row2); double ch = getRowHeightInPixels(row2);
float delta = h - size.height; double delta = h - scaledHeight;
dy2 = (int)((ch-delta)/ch*256); dy2 = (int)((ch-delta)/ch*256);
} }
anchor.row2 = row2; anchor.row2 = row2;

View File

@ -27,4 +27,13 @@ public interface Picture {
* Reset the image to the original size. * Reset the image to the original size.
*/ */
void resize(); void resize();
/**
* Reset the image to the original size.
*
* @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.
*/
void resize(double scale);
} }

View File

@ -126,9 +126,20 @@ public class XSSFPicture extends XSSFShape implements Picture {
* Reset the image to the original size. * Reset the image to the original size.
*/ */
public void resize(){ public void resize(){
resize(1.0);
}
/**
* Reset the image to the original size.
*
* @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.
*/
public void resize(double scale){
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor(); XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();
XSSFClientAnchor pref = getPreferredSize(); XSSFClientAnchor pref = getPreferredSize(scale);
int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1()); int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1()); int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());
@ -148,10 +159,22 @@ public class XSSFPicture extends XSSFShape implements Picture {
* @return XSSFClientAnchor with the preferred size for this image * @return XSSFClientAnchor with the preferred size for this image
*/ */
public XSSFClientAnchor getPreferredSize(){ public XSSFClientAnchor getPreferredSize(){
return getPreferredSize(1);
}
/**
* Calculate the preferred size for this picture.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* @return XSSFClientAnchor with the preferred size for this image
*/
public XSSFClientAnchor getPreferredSize(double scale){
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor(); XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();
XSSFPictureData data = getPictureData(); XSSFPictureData data = getPictureData();
Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType()); Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType());
double scaledWidth = size.getWidth() * scale;
double scaledHeight = size.getHeight() * scale;
float w = 0; float w = 0;
int col2 = anchor.getCol1(); int col2 = anchor.getCol1();
@ -163,19 +186,19 @@ public class XSSFPicture extends XSSFShape implements Picture {
for (;;) { for (;;) {
w += getColumnWidthInPixels(col2); w += getColumnWidthInPixels(col2);
if(w > size.width) break; if(w > scaledWidth) break;
col2++; col2++;
} }
if(w > size.width) { if(w > scaledWidth) {
float cw = getColumnWidthInPixels(col2 + 1); double cw = getColumnWidthInPixels(col2 + 1);
float delta = w - size.width; double delta = w - scaledWidth;
dx2 = (int)(EMU_PER_PIXEL*(cw-delta)); dx2 = (int)(EMU_PER_PIXEL*(cw-delta));
} }
anchor.setCol2(col2); anchor.setCol2(col2);
anchor.setDx2(dx2); anchor.setDx2(dx2);
float h = 0; double h = 0;
int row2 = anchor.getRow1(); int row2 = anchor.getRow1();
int dy2 = 0; int dy2 = 0;
@ -186,21 +209,21 @@ public class XSSFPicture extends XSSFShape implements Picture {
for (;;) { for (;;) {
h += getRowHeightInPixels(row2); h += getRowHeightInPixels(row2);
if(h > size.height) break; if(h > scaledHeight) break;
row2++; row2++;
} }
if(h > size.height) { if(h > scaledHeight) {
float ch = getRowHeightInPixels(row2 + 1); double ch = getRowHeightInPixels(row2 + 1);
float delta = h - size.height; double delta = h - scaledHeight;
dy2 = (int)(EMU_PER_PIXEL*(ch-delta)); dy2 = (int)(EMU_PER_PIXEL*(ch-delta));
} }
anchor.setRow2(row2); anchor.setRow2(row2);
anchor.setDy2(dy2); anchor.setDy2(dy2);
CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt(); CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt();
size2d.setCx(size.width*EMU_PER_PIXEL); size2d.setCx((long)(scaledWidth*EMU_PER_PIXEL));
size2d.setCy(size.height*EMU_PER_PIXEL); size2d.setCy((long)(scaledHeight*EMU_PER_PIXEL));
return anchor; return anchor;
} }