Docx4j scale image to parent element - java

I want to scale an image in docx4j to match the width of it's parent if it's too large to fit on the page. For example maybe it's inside a table cell which has a width or bigger than the page.
I'm currently playing with the int width = box.getContainingBlock().getWidth(); and int imagewidth = imagePart.getImageInfo().getSize().getWidthMpt(); but the values don't seem to be correct. Is there a better way of doing this?

https://github.com/plutext/docx4j/commit/81fecde856e80602a168cee8d3df70269668a9dc (in 3.3.0) addressed this use case, adding:
public Inline createImageInline(String filenameHint, String altText,
int id1, int id2, boolean link, int maxWidth) throws Exception
but you do need to know the width of the parent.
Example of usage https://github.com/plutext/docx4j/commit/279b5bcc91ff65d4dc5b88f08b8f6e9815b12563

Related

Adding a picture to Word Document using Apache POI

I know it is already possible to add a picture to Word document using the
XWPFRun: addPicture(java.io.InputStream pictureData, int pictureType, java.lang.String filename, int width, int height) throws InvalidFormatException, java.io.IOException
method. However, I don't want my Picture to be resized. The resizing is not scaling the new images: it is always stretching them, making them useless.
Is there a way to insert image with original size, or scale them proportionally???
I had used Apache POI for quite some time and I don't think it's possible to add picture to a WORD doc without specifying height and width.
I always use following code to retrieve the size of a picture and scale them accordingly if needed.
BufferedImage bi = ImageIO.read(new File(filename));
int width = bi.getWidth();
int height = bi.getHeight();
You can use Apache POI ImageUtils as following:
Dimension dimension = ImageUtils.getImageDimension(imageInputStream, XWPFDocument.PICTURE_TYPE_JPEG);
double width = dimension.getWidth();
double height = dimension.getHeight();

How to create Table using Apache PDFBox

We are planning to migrate our pdf generation utilities from iText to PDFBox (Due to licensing issues in iText). With some effort, I was able to write and position text, draw lines etc. But creating Tables with text embedded in Table cells is a challenge, I went through the documentation, examples, Google, Stackoverflow couldn't find a thing. Was wondering if PDFBox provides native support for creating Tables with embedded text. My last resort would be to use this link https://github.com/eduardohl/Paginated-PDFBox-Table-Sample
Since I also needed table drawing functionality for a side project, I implemented a small "table drawer" library myself, which I uploaded to github.
In order to produce such a table – for instance – ...
... you would need this code.
In the same file you find the code for that table as well:
The current "feature list" includes:
set font and font size on table level as well as on cell level
define single cells with bottom-, top-, left- and right-border width separately
define the background color on row or cell level
define padding (top, bottom, left, right) on cell level
define border color (on table, row or cell level)
specify text alignment (vertical and horizontal)
cell spanning and row spanning
text wrapping and line spacing
Also it should not be too hard to add missing stuff like having different border colors for borders on top, bottom, left and right-borders, if needed.
Thanks to the links provided by Tilman. Using the boxable API (https://github.com/dhorions/boxable) I was able to create the table I wanted to. Just an FYI I wanted to create the table with variable number of cells. For example row 1 would have 2 cells, row 2 could have 5 cells and row 3 could have just 3 cells. I was able to do with ease. I followed Example1.java in the link mentioned above.
This example code works for me. I think this would be helpful to you
public static void creteTablePdf() throws IOException {
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
int pageWidth = (int)page.getTrimBox().getWidth(); //get width of the page
int pageHeight = (int)page.getTrimBox().getHeight(); //get height of the page
PDPageContentStream contentStream = new PDPageContentStream(document,page);
contentStream.setStrokingColor(Color.DARK_GRAY);
contentStream.setLineWidth(1);
int initX = 50;
int initY = pageHeight-50;
int cellHeight = 20;
int cellWidth = 100;
int colCount = 3;
int rowCount = 3;
for(int i = 1; i<=rowCount;i++){
for(int j = 1; j<=colCount;j++){
if(j == 2){
contentStream.addRect(initX,initY,cellWidth+30,-cellHeight);
contentStream.beginText();
contentStream.newLineAtOffset(initX+30,initY-cellHeight+10);
contentStream.setFont(PDType1Font.TIMES_ROMAN,10);
contentStream.showText("Dinuka");
contentStream.endText();
initX+=cellWidth+30;
}else{
contentStream.addRect(initX,initY,cellWidth,-cellHeight);
contentStream.beginText();
contentStream.newLineAtOffset(initX+10,initY-cellHeight+10);
contentStream.setFont(PDType1Font.TIMES_ROMAN,10);
contentStream.showText("Dinuka");
contentStream.endText();
initX+=cellWidth;
}
}
initX = 50;
initY -=cellHeight;
}
contentStream.stroke();
contentStream.close();
document.save("C:\\table.pdf");
document.close();
System.out.println("table pdf created");
}

unable to calculate itext PdfPTable/PdfPCell height properly

I'm facing a problem while trying to generate a PdfPTable and calculate its height before adding it to a document. The method calculateHeights of PdfPTable returned the height a lot greater than the height of a page (while the table is about 1/4 of page's height), so I wrote a method to calculate the height:
protected Float getVerticalSize() throws DocumentException, ParseException, IOException {
float overallHeight=0.0f;
for(PdfPRow curRow : this.getPdfObject().getRows()) {
float maxHeight = 0.0f;
for(PdfPCell curCell : curRow.getCells()) {
if(curCell.getHeight()>maxHeight) maxHeight=curCell.getHeight();
}
overallHeight+=maxHeight;
}
return overallHeight;
}
where getPdfObject method returns a PdfPTable object.
Using debugger I've discovered that lly and ury coordinate difference (and thus the height) of cell's rectangle is much bigger than it looks after adding a table to a document (for example, one cell is 20 and the other is 38 height while they look like the same on a page). There is nothing in the cell except a paragraph with a chunk in it:
Font f = getFont();
if (f != null) {
int[] color = getTextColor();
if(color != null) f.setColor(color[0],color[1],color[2]);
ch = new Chunk(celltext, f);
par = new Paragraph(ch);
}
cell = new PdfPCell(par);
cell.setHorizontalAlignment(getHorizontalTextAlignment());
cell.setVerticalAlignment(getVerticalTextAlignment());
A table then has a cell added and setWidthPercentage attribute set to a some float.
What am I doing wrong? Why does cell's proportions are different from those I see after generating PDF? Maybe I'm calculating the height wrong? Isn't it the height of a cell on a PDF page should strictly be the difference between lly and ury coordinates
Sorry I haven't shown the exact code, because the PDF is being generated of XML using lots of intermediate steps and objects and it is not very useful "as is" I guess...
Thanks in advance!
The height of table added to a page where the available width is 400 is different from the height of a table added to a page where the available width is 1000. There is no way you can measure the height correctly until the width is defined.
Defining the width can be done by adding the table to the document. Once the table is rendered, the total height is known.
If you want to know the height in advance, you need to define the width in advance. For instance by using:
table.setTotalWidth(400);
table.setLockedWidth(true);
This is explained in the TableHeight example. In table_height.pdf, you see that iText returns a height of 0 before adding a table and a height of 48 after adding the table. iText initially returns 0 because there is no way to determine the actual height.
We then take the same table and we define a total width of 50 (which is much smaller than the original 80% of the available width on the page). Now when we calculate the height of the table with the same contents, iText returns 192 instead of 48. When you look at the table on the page, the cause of the difference in height is obvious.
Inorder to get dynamic table height we should set and lock width of table.
Here, 595 is A4 size paper width.
table.setTotalWidth(595);
table.setLockedWidth(true);

How to calculate "scanLegth" param from Bitmap.getRGB565(...)

I'm trying get bytes from bitmap in blackberry using the next method in Bitmap:
getRGB565(byte[] rgbData, int offset, int scanLength, int x, int y, int width, int height)
But i have read the params and i don't know how must i calculate scanLength:
scanLength - Width of a scanline (in bytes) within the data array.
Any idea?
Here scanLength is the full width of the original image, while width is the width of the rectangle you are copying from.
If you are copying the whole image it is the same, but if you are copying only a part of the image you'll have scanLength > width.
See also the Bitmap#getRGB565 javadoc
To get byte[] from Bitmap I used this: http://blackberry-digger.blogspot.com/2009/05/code-convert-bitmap-to-png-and-then.html and it worked fine.
Sorry it was too easy . In getARG is another example , it must be used usually with the same int width param

Insert image to excel file using JXL without stretching it

I can insert image to my excel file using jxl usingsheet.addImage(WritableImage obj). My problem is that, it stretches based on the args of WritableImage. I'm wondering if there is a way so that the image that I insert will not stretch like if I insert a 200x200 sized image it will appear to the sheet as 200x200.
As much as this has bugged me about jxl, I've never found a way to insert an image without associating the aspect ratio to cells instead of pixels/inches/any standard unit of measurement, and I've done decent research in the past on doing so.
The best you can do is to adapt the images to the height/width of the cells you are inserting it into, or even better, set the cell width/height for the cells you are putting the image in.
From the JExcel FAQ- http://jexcelapi.sourceforge.net/resources/faq/
private static final double CELL_DEFAULT_HEIGHT = 17;
private static final double CELL_DEFAULT_WIDTH = 64;
File imageFile = new File(GIF_OR_JPG_IMAGE_FILE);
BufferedImage input = ImageIO.read(imageFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(input, "PNG", baos);
sheet.addImage(new WritableImage(1,1,input.getWidth() / CELL_DEFAULT_WIDTH,
input.getHeight() / CELL_DEFAULT_HEIGHT,baos.toByteArray()));
To keep the aspect ratio, you'll also want to set the WritableImage to not re-size if the user changes the row height or column width. Do this with either of the below (your preference based on if you want the image anchor locked or to move with resizing):
WritableImage.MOVE_WITH_CELLS;
WritableImage.NO_MOVE_OR_SIZE_WITH_CELLS;
Actually, this is possible. Assume that the width of the picture that you want to include is 4000. Then you do the following:
CellView cv = excelSheetTemp.getColumnView(0);
//get the width of the column where you want to insert the picture
int width = forLogo.getSize();
//if the width is less than the size you want, set the column width to
//the width. This will ensure that your image does not shrink
if (width < 4000) {
forLogo.setSize(4000);
excelSheetTemp.setColumnView(0, cv);
width = 4000;
}
double c = 4000/width;
WritableImage im = new WritableImage(0, 1, c, 3, the image file);
excelSheetTemp.addImage(im);

Categories

Resources