Hi,
I noticed that during the “Word to PDF” conversion the DPI of the image is reduced by 1 point. This happens for PNG images when the compression is set to JPEG format (PdfSaveOptions.setImageCompression(PdfImageCompression.JPEG)
). I prepared a code snippet that creates a PDF file of the image and then extracts it into a separate file:
package com.example;
import com.aspose.pdf.ImageType;
import com.aspose.pdf.facades.PdfExtractor;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.PdfImageCompression;
import com.aspose.words.PdfSaveOptions;
import java.nio.file.Files;
import java.nio.file.Path;
public class PdfExample {
public static void addImageToPdf(Path pdf, Path image, int width, int height) {
try {
DocumentBuilder builder = new DocumentBuilder();
builder.insertImage(loadImage(image), width, height);
builder.getDocument().save(pdf.toString(), pdfSaveOptions());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static byte[] loadImage(Path image) {
try {
return Files.readAllBytes(image);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static PdfSaveOptions pdfSaveOptions() {
PdfSaveOptions options = new PdfSaveOptions();
options.setImageCompression(PdfImageCompression.JPEG);
options.setJpegQuality(100);
options.getDownsampleOptions().setDownsampleImages(false);
return options;
}
public static void extractImagesFromPdf(Path pdf, ImageType format) {
try (PdfExtractor pdfExtractor = new PdfExtractor()) {
pdfExtractor.bindPdf(pdf.toString());
pdfExtractor.extractImage();
int imageIndex = 1;
while (pdfExtractor.hasNextImage()) {
pdfExtractor.getNextImage(resolveImageFilename(pdf.getParent(), format, imageIndex++));
}
}
}
private static String resolveImageFilename(Path folder, ImageType format, int imageIndex) {
return folder.resolve("extracted-img-%s.%s".formatted(imageIndex, format.toString().toLowerCase())).toString();
}
}
Execution for the attached (example.png) PNG image (600x360 - 300 DPI):
Image file: example.png (13.9 KB)
Execution example:
class PdfExampleTest {
public static final Path IMAGE = image("example.png");
@Test
void sameSize() {
Path pdf = pdfFile("same-size.pdf");
PdfExample.addImageToPdf(pdf, IMAGE, 600, 360);
PdfExample.extractImagesFromPdf(pdf, ImageType.getJpeg());
}
}
gives us a PDF file with an image of decreased DPI:
Extracted image details: dpi-decreased.jpg (52.2 KB)
However, manual conversion from PNG to JPEG image seems to solve the issue:
package com.example;
import com.aspose.imaging.Image;
import com.aspose.imaging.imageoptions.JpegOptions;
import com.aspose.pdf.ImageType;
import com.aspose.pdf.facades.PdfExtractor;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.PdfImageCompression;
import com.aspose.words.PdfSaveOptions;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
public class PdfExample {
public static void addImageToPdf(Path pdf, Path image, int width, int height) {
try {
DocumentBuilder builder = new DocumentBuilder();
builder.insertImage(loadImage(image), width, height);
builder.getDocument().save(pdf.toString(), pdfSaveOptions());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static byte[] loadImage(Path image) {
try {
return isPng(image) ? toJpeg(Files.newInputStream(image)) : Files.readAllBytes(image);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static byte[] toJpeg(InputStream pngImage) {
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
Image.load(pngImage)
.save(output, jpgSaveOptions());
return output.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static boolean isPng(Path image) {
return image.toString().matches(".+\\.%s".formatted(ImageType.getPng().toString().toLowerCase()));
}
private static JpegOptions jpgSaveOptions() {
JpegOptions options = new JpegOptions();
options.setQuality(100);
return options;
}
private static PdfSaveOptions pdfSaveOptions() {
PdfSaveOptions options = new PdfSaveOptions();
options.setImageCompression(PdfImageCompression.JPEG);
options.setJpegQuality(100);
options.getDownsampleOptions().setDownsampleImages(false);
return options;
}
public static void extractImagesFromPdf(Path pdf, ImageType format) {
try (PdfExtractor pdfExtractor = new PdfExtractor()) {
pdfExtractor.bindPdf(pdf.toString());
pdfExtractor.extractImage();
int imageIndex = 1;
while (pdfExtractor.hasNextImage()) {
pdfExtractor.getNextImage(resolveImageFilename(pdf.getParent(), format, imageIndex++));
}
}
}
private static String resolveImageFilename(Path folder, ImageType format, int imageIndex) {
return folder.resolve("extracted-img-%s.%s".formatted(imageIndex, format.toString().toLowerCase())).toString();
}
}
Extracted image details: dpi-same.png (62.4 KB)
Is there a way to achieve the same results without manual conversion?