I'm using the itext PDF library to build a very image-intensive PDF document in Java. Each page has a dozen images on it. The original source images are very high resolution, and I'm using scaleToFit to render the image to the size I need.
The problem I have is that the PDF document is still very large. My understanding is that the entire original high resolution image is being included, and the scaling I'm using only affects the actual rendering, not the size of the image that's included in the file.
I've verified this by removing the scaling — the pages were rendered with the high resolution images overlapping each other and the edge of pages, and the PDF was the same size as when the scaling was in place.
So, here's the question — how can I reduce the size of the PDF file by scaling down each image? If I lose a little bit of image quality that's ok. Rescaling the source images manually will be difficult.
So I've found a way to do it. I now load the image into a BufferedImage, and then scale that using the hints found here: how do I scale a BufferedImage.
This gives me a BufferedImage — I then convert this into an iText image using
Image returnedImage = Image.getInstance ( pcb, bufferedImage, quality );
Where quality is currently 0.6. That's acceptable for the work I'm doing.
Related
I have a PDF file to save, but first I have to compress it with the best possible quality and I must use open source library (like Apache PDFBox®).
So, until now what I do is get all the image type resources, compress them and put them back in the PDF, but the compression ratio is to low. This is just a fragment of the code where I assign the compression parameters:
PDImageXObject imageXObject = (PDImageXObject) pdxObject;
ImageWriter imageWriter = ImageIO
.getImageWritersByFormatName(FileType.JPEG.name().toLowerCase()).next();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(COMPRESSION_FACTOR);
There is some other mechanism to optimize a PDF, so far only compress the images shows a slightly poor result.
On compression. Indeed, images probably are the largest culprits.
Images: The image size, width and height, contribute to the file size too, not only the lossy image quality (your COMPRESSION_FACTOR). In general I would start with compressing a JPEG file outside the PDF. Then you can find the best compression, that still shows and prints (!) adequately. Photos JPEG, vector graphics (like diagrams) can best be done with Encapsulated PostScript.
Repeated images like page logos should not be stored repeatedly. The optimisation here is internet streaming.
Fonts: The default fonts need no space, the full fonts need the most space (for PDFs with forms for instance). Embedded fonts are a third possibility, only loading the symbols one needs.
PDFs own binary data: Text and other parts can be uncompressed, compressed using only 7bits ASCII, and further compressed using all bytes. The ASCII option is a bit outdated.
At the moment I am not using pdfbox, hence I leave that to you.
I have a PDF file to save, but first I have to compress it with the best possible quality and I must use open source library (like Apache PDFBox®).
So, until now what I do is get all the image type resources, compress them and put them back in the PDF, but the compression ratio is to low. This is just a fragment of the code where I assign the compression parameters:
PDImageXObject imageXObject = (PDImageXObject) pdxObject;
ImageWriter imageWriter = ImageIO
.getImageWritersByFormatName(FileType.JPEG.name().toLowerCase()).next();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(COMPRESSION_FACTOR);
There is some other mechanism to optimize a PDF, so far only compress the images shows a slightly poor result.
On compression. Indeed, images probably are the largest culprits.
Images: The image size, width and height, contribute to the file size too, not only the lossy image quality (your COMPRESSION_FACTOR). In general I would start with compressing a JPEG file outside the PDF. Then you can find the best compression, that still shows and prints (!) adequately. Photos JPEG, vector graphics (like diagrams) can best be done with Encapsulated PostScript.
Repeated images like page logos should not be stored repeatedly. The optimisation here is internet streaming.
Fonts: The default fonts need no space, the full fonts need the most space (for PDFs with forms for instance). Embedded fonts are a third possibility, only loading the symbols one needs.
PDFs own binary data: Text and other parts can be uncompressed, compressed using only 7bits ASCII, and further compressed using all bytes. The ASCII option is a bit outdated.
At the moment I am not using pdfbox, hence I leave that to you.
There are about 100 jpeg & png color images used in our JavaFX-built desktop app which, when the window is resized, become stretched and blurry so I'd like to have all the graphics remade in a format that will allow them to be dynamically resized without losing quality. What image format or procedure should be used to do this?
Currently, each image is simply in an ImageView and resized as follows, but I'm open to other suggestions:
if(isSmall){
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
double sh = visualBounds.getHeight();
Scale scale = new Scale(sh, sh, 0, 0);
root.getTransforms().setAll(scale);
}
As has already been mentioned SVG is probably the way to go for you. JavaFX does not support SVG directly but you can find support here
javafxsvg and here svg-to-fxml-converter for example.
You can't resize an image to be bigger than it is without it getting blurry for most common formats. Instead make sure your images are big enough so you only need to downscale them.
The only format I ever heard of that could upscale further was using fractal compression, but AFAIK it is not in common use.
I have a base64 string that it contains an image which scanned by 300DPI and it size is around 500kb . I need to reduce file size to 300kb (+/- %20) without changing DPI in java. Resolution MUST be 300 DPI. I can't change it.
Hovewer, I don't care about dimensions (pixels). I could not figure out how can I do it. I hope, you can help me ?
Thanks:)
Since the size of the photographed object does not change (inches), and the resolution you mandate to be fixed at 300DPI (Dots/pixels per inch), the number of pixels in the image also cannot change.
The only thing you can do in order to reduce the file size is to compress it.
Depending on the image contents, you can, for example, use JPEG compression and set its quality level to a setting that will yield a 300Kb output. Other compression methods may be more applicable, depending on the contents on the image. For example CCITT G4 compression for scanned black & white text.
Regarding how to compress, Google is your friend:
https://www.google.com/search?q=compress+image+jpeg+java
I'm creating PDFs with iText (LGPL) which include some Text and self-drawn (Graphics2D) images.
My current solution is to draw the images on a BufferedImage and then include it in the PDF, which has several drawbacks:
If printed, the images just look ugly, a way to circumvent this is to use larger images, and with 3000*3000 it looks ok. But this leads to the next problem: time. It takes several seconds to compress one image (I haven’t found a way to disable it, and files would be huge without compression).
PdfGraphics2d from iText looks good, but has one major drawback: it’s only able to draw to the background of the PDF, and there seems to be no way to wrap it in some kind of element.
Is there a way to draw on a PDF without having to use absolute positions? I’m using Graphics2d because it’s used also to provide a preview in the UI.
You can wrap a PdfTemplate inside an Image object without losing any of the vector image's quality. In most cases, you'll use the Image object to add raster images to a PDF document as an Image XObject. However, in this case, the PdfTemplate will be added as a Form XObject using its original vector data. Another situation when this happens, is when you add a WMF file; such as file is converted into PDF syntax automatically.