Of course! Converting a JPG (or any image) to a PDF in Java is a common task. The best approach depends on your specific needs, such as whether you need a simple one-to-one conversion or want to combine multiple images into a single PDF.
Here are the most popular and effective methods, ranging from using a powerful library to a simpler, built-in approach.
Method 1: Using the Apache PDFBox Library (Recommended)
This is the most robust and feature-rich open-source library for working with PDFs in Java. It's perfect for this task and is actively maintained by the Apache Software Foundation.
Step 1: Add the PDFBox Dependency
If you're using a build tool like Maven, add this to your pom.xml:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.2</version> <!-- Check for the latest version -->
</dependency>
If you're using Gradle, add this to your build.gradle:
implementation 'org.apache.pdfbox:pdfbox:3.0.2' // Check for the latest version
Step 2: Write the Java Code
PDFBox makes the conversion straightforward. Here's a complete, runnable example.
A. Converting a Single JPG to PDF
This code takes one image file and creates a new PDF file with that image on a single page.
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import java.io.File;
import java.io.IOException;
public class JpgToPdfConverter {
public static void main(String[] args) {
// --- Configuration ---
String imagePath = "path/to/your/image.jpg"; // Path to your JPG file
String pdfPath = "path/to/your/output.pdf"; // Path for the output PDF file
try {
// 1. Load the image file
File imageFile = new File(imagePath);
if (!imageFile.exists()) {
System.err.println("Error: Image file not found at " + imagePath);
return;
}
// 2. Create a new PDDocument
try (PDDocument document = new PDDocument()) {
// 3. Create a new page in the document
PDPage page = new PDPage();
document.addPage(page);
// 4. Load the image and create a PDImageXObject
// This is the object that can be drawn onto the page.
PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, document);
// 5. Create a content stream to draw the image on the page
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
// Get the image dimensions
float imageWidth = pdImage.getWidth();
float imageHeight = pdImage.getHeight();
// Get the page dimensions
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
// Optional: Scale the image to fit the page while maintaining aspect ratio
// This prevents the image from being cropped if it's too large.
float scale = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
float scaledWidth = imageWidth * scale;
float scaledHeight = imageHeight * scale;
// Calculate position to center the image on the page
float startX = (pageWidth - scaledWidth) / 2;
float startY = (pageHeight - scaledHeight) / 2;
// Draw the image on the page
contentStream.drawImage(pdImage, startX, startY, scaledWidth, scaledHeight);
}
// 6. Save the document to a file
document.save(pdfPath);
System.out.println("PDF created successfully at: " + pdfPath);
}
} catch (IOException e) {
System.err.println("An error occurred during PDF creation: " + e.getMessage());
e.printStackTrace();
}
}
}
B. Combining Multiple JPGs into a Single PDF
This is a very common requirement. The logic is similar, but you loop through your image files and add a page for each one.
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class MultipleImagesToPdfConverter {
public static void main(String[] args) {
// --- Configuration ---
String outputPdfPath = "path/to/your/combined.pdf";
List<String> imagePaths = Arrays.asList(
"path/to/image1.jpg",
"path/to/image2.png", // PDFBox also supports PNG, BMP, etc.
"path/to/image3.jpeg"
);
try (PDDocument document = new PDDocument()) {
for (String imagePath : imagePaths) {
File imageFile = new File(imagePath);
if (!imageFile.exists()) {
System.err.println("Warning: Image file not found at " + imagePath + ". Skipping.");
continue;
}
PDPage page = new PDPage();
document.addPage(page);
PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, document);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
// Center and scale the image to fit the page
float imageWidth = pdImage.getWidth();
float imageHeight = pdImage.getHeight();
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
float scale = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
float scaledWidth = imageWidth * scale;
float scaledHeight = imageHeight * scale;
float startX = (pageWidth - scaledWidth) / 2;
float startY = (pageHeight - scaledHeight) / 2;
contentStream.drawImage(pdImage, startX, startY, scaledWidth, scaledHeight);
}
}
document.save(outputPdfPath);
System.out.println("Combined PDF created successfully at: " + outputPdfPath);
} catch (IOException e) {
System.err.println("An error occurred during PDF creation: " + e.getMessage());
e.printStackTrace();
}
}
}
Method 2: Using iText (Another Powerful Library)
iText is another excellent, feature-rich library for PDF manipulation. It's very popular but has a more complex licensing model (AGPL) for commercial use. For open-source projects, it's a great choice.
Step 1: Add the iText 7 Dependency
Maven (pom.xml):
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version> <!-- iText 5 is simpler for basic tasks -->
</dependency>
Note: iText 7 has a different API. For a quick conversion, iText 5 is often easier.
Step 2: Write the Java Code
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Rectangle;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class JpgToPdfWithiText {
public static void main(String[] args) {
String imagePath = "path/to/your/image.jpg";
String pdfPath = "path/to/your/output_itext.pdf";
try {
// 1. Create a Document object
Document document = new Document();
// 2. Create a PdfWriter instance to write the document to a file
PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
// 3. Open the document
document.open();
// 4. Load the image
Image image = Image.getInstance(imagePath);
// Optional: Scale the image to fit the page
// Get page size
Rectangle pageSize = document.getPageSize();
// Calculate scale
float scale = Math.min(pageSize.getWidth() / image.getPlainWidth(),
pageSize.getHeight() / image.getPlainHeight());
image.scaleAbsolute(image.getPlainWidth() * scale, image.getPlainHeight() * scale);
// Center the image
image.setAbsolutePosition(
(pageSize.getWidth() - image.getScaledWidth()) / 2,
(pageSize.getHeight() - image.getScaledHeight()) / 2
);
// 5. Add the image to the document
document.add(image);
// 6. Close the document
document.close();
System.out.println("PDF created successfully with iText at: " + pdfPath);
} catch (Exception e) {
System.err.println("An error occurred with iText: " + e.getMessage());
e.printStackTrace();
}
}
}
Method 3: Using Java's Built-in AWT/Swing (No External Library)
This method is great if you want to avoid adding a third-party dependency. It uses Java's built-in image and printing capabilities. However, it's less flexible and can be less reliable for complex layouts or high-quality output.
Step 1: No Dependencies Needed!
This code uses only the standard Java Development Kit (JDK).
Step 2: Write the Java Code
This approach uses a PrinterJob to "print" the image to a PDF file, using a virtual PDF printer.
import javax.imageio.ImageIO;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class JpgToPdfWithAWT {
public static void main(String[] args) {
String imagePath = "path/to/your/image.jpg";
String pdfPath = "path/to/your/output_awt.pdf";
try {
// 1. Find a PDF Print Service (e.g., "Microsoft Print to PDF" on Windows)
// Note: This requires a system-level PDF printer to be installed.
PrintService[] services = PrintServiceLookup.lookupPrintServices(
DocFlavor.INPUT_STREAM.JPEG, null);
PrintService pdfService = null;
for (PrintService service : services) {
if (service.getName().toLowerCase().contains("pdf")) {
pdfService = service;
break;
}
}
if (pdfService == null) {
System.err.println("Error: No PDF print service found. Please install a PDF printer (e.g., 'Microsoft Print to PDF').");
return;
}
// 2. Create a PrinterJob
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(pdfService);
// 3. Set up print attributes (e.g., A4 paper)
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
attributes.add(MediaSizeName.ISO_A4);
// 4. Create a SimpleDoc from the image file
File imageFile = new File(imagePath);
FileInputStream fis = new FileInputStream(imageFile);
SimpleDoc doc = new SimpleDoc(fis, DocFlavor.INPUT_STREAM.JPEG, null);
// 5. Print the document to the PDF file
// The output file is specified by the "Print to PDF" dialog or default location.
// This part is OS-dependent and can be tricky to automate perfectly.
job.print(doc, attributes);
fis.close();
System.out.println("Printing job sent to PDF printer. Check your default PDF output location.");
System.out.println("Note: This method is OS-dependent and may require user interaction.");
} catch (IOException | javax.print.PrintException e) {
System.err.println("An error occurred during AWT printing: " + e.getMessage());
e.printStackTrace();
}
}
}
Summary and Recommendation
| Method | Pros | Cons | Best For |
|---|---|---|---|
| Apache PDFBox | Highly recommended. Open-source, powerful, reliable, great for multi-image PDFs, platform-independent. | Requires adding an external library. | Almost all use cases, especially when you need control over the PDF generation process. |
| iText | Very powerful, feature-rich, good documentation. | AGPL license can be restrictive for commercial closed-source projects. | Projects where iText's features are needed, and the license is acceptable. |
| Java AWT/Swing | No external dependencies needed. | Unreliable, OS-dependent, requires a system PDF printer, hard to automate output path, poor quality control. | Quick, simple scripts where you can't add dependencies and are okay with system limitations. |
For any serious application, Apache PDFBox is the clear winner. It's free, open-source, and gives you full control over the resulting PDF file.
