Looking for a way to compress images in a pdf and to output a pdf for archiving. I cannot compress the images before creation as it would compromise the quality of the print.
The size of each pdf is around 8MB with the bulk of this being made up of 2 images. Images are in png format and are brought into pdf during generation(3rd party generator used)
Is there a way to compress these in java without using a 3rd party tool. I have tried with pdfbox, itext and a 3rd party exe(neevia), the 3rd party tool the only one that has given me any results so far(Down to around half a MB) but I do not want to relinquish control to an exe.
Sample code is below.
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDStream;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
public class compressPDF {
public static void main (String[] args) throws IOException, DocumentException, COSVisitorException {
/*
* Using PDF Box
*/
PDDocument doc; // = new PDDocument();
doc = PDDocument.load("C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF");
PDStream stream= new PDStream(doc);
stream.addCompression();
doc.save("C:/_dev_env_/TEMP/compressPDF/compressed_pdfBox.pdf");
doc.close();
/*
* Using itext
*/
PdfReader reader = new PdfReader("C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("C:/_dev_env_/TEMP/compressPDF/compressed_Itext.pdf"), PdfWriter.VERSION_1_5);
stamper.setFullCompression();
stamper.getWriter().setCompressionLevel(50);
int total = reader.getNumberOfPages() + 1;
for (int i = 1; i < total; i++) {
reader.setPageContent(i, reader.getPageContent(i));
}
stamper.close();
reader.close();
/*
* Using 3rd party - Neevia
*/
try {
Process process = new ProcessBuilder("C:/Program Files (x86)/neeviaPDF.com/PDFcompress/cmdLine/CLcompr.exe","C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF", "C:/_dev_env_/TEMP/compressPDF/compressed_Neevia.pdf").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:", Arrays.toString(args));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
System.out.println(e);
} finally {
System.out.println("Created!!");
}
}
}
I used code below for a proof of concept... Works a treat :) Thanks to Bruno for setting me on the right path :)
package compressPDF;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.parser.PdfImageObject;
public class ResizeImage {
/** The resulting PDF file. */
//public static String RESULT = "results/part4/chapter16/resized_image.pdf";
/** The multiplication factor for the image. */
public static float FACTOR = 0.5f;
/**
* Manipulates a PDF file src with the file dest as result
* #param src the original PDF
* #param dest the resulting PDF
* #throws IOException
* #throws DocumentException
*/
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfName key = new PdfName("ITXT_SpecialId");
PdfName value = new PdfName("123456789");
// Read the file
PdfReader reader = new PdfReader(src);
int n = reader.getXrefSize();
PdfObject object;
PRStream stream;
// Look for image and manipulate image stream
for (int i = 0; i < n; i++) {
object = reader.getPdfObject(i);
if (object == null || !object.isStream())
continue;
stream = (PRStream)object;
// if (value.equals(stream.get(key))) {
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
System.out.println(stream.type());
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {
PdfImageObject image = new PdfImageObject(stream);
BufferedImage bi = image.getBufferedImage();
if (bi == null) continue;
int width = (int)(bi.getWidth() * FACTOR);
int height = (int)(bi.getHeight() * FACTOR);
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
AffineTransform at = AffineTransform.getScaleInstance(FACTOR, FACTOR);
Graphics2D g = img.createGraphics();
g.drawRenderedImage(bi, at);
ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
ImageIO.write(img, "JPG", imgBytes);
stream.clear();
stream.setData(imgBytes.toByteArray(), false, PRStream.BEST_COMPRESSION);
stream.put(PdfName.TYPE, PdfName.XOBJECT);
stream.put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.put(key, value);
stream.put(PdfName.FILTER, PdfName.DCTDECODE);
stream.put(PdfName.WIDTH, new PdfNumber(width));
stream.put(PdfName.HEIGHT, new PdfNumber(height));
stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);
}
}
// Save altered PDF
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
}
/**
* Main method.
*
* #param args no arguments needed
* #throws DocumentException
* #throws IOException
*/
public static void main(String[] args) throws IOException, DocumentException {
//createPdf(RESULT);
new ResizeImage().manipulatePdf("C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF", "C:/_dev_env_/TEMP/compressPDF/compressTest.pdf");
}
}
Just to update the excellent answer from #Daniel, I update his code to be compatible with iText7.
package opencde.builder.compresspdf;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.pdf.PdfDictionary;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfStream;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.xobject.PdfImageXObject;
import com.itextpdf.layout.element.Image;
public class ResizeImageV7 {
// Logging
private static Logger logger = LoggerFactory.getLogger(ResizeImageV7.class);
/**
* Manipulates a PDF file src with the file dest as result
*
* #param src the original PDF
* #param dest the resulting PDF
* #param resizeFactor factor to multiplicate to resize image
* #throws IOException
*/
public void manipulatePdf(String src, String dest,Float resizeFactor) throws IOException {
//Get source pdf
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
// Iterate over all pages to get all images.
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++)
{
PdfPage page = pdfDoc.getPage(i);
PdfDictionary pageDict = page.getPdfObject();
PdfDictionary resources = pageDict.getAsDictionary(PdfName.Resources);
// Get images
PdfDictionary xObjects = resources.getAsDictionary(PdfName.XObject);
for (Iterator<PdfName> iter = xObjects.keySet().iterator() ; iter.hasNext(); ) {
// Get image
PdfName imgRef = iter.next();
PdfStream stream = xObjects.getAsStream(imgRef);
PdfImageXObject image = new PdfImageXObject(stream);
BufferedImage bi = image.getBufferedImage();
if (bi == null)
continue;
// Create new image
int width = (int) (bi.getWidth() * resizeFactor);
int height = (int) (bi.getHeight() * resizeFactor);
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
AffineTransform at = AffineTransform.getScaleInstance(resizeFactor, resizeFactor);
Graphics2D g = img.createGraphics();
g.drawRenderedImage(bi, at);
ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
// Write new image
ImageIO.write(img, "JPG", imgBytes);
Image imgNew =new Image(ImageDataFactory.create(imgBytes.toByteArray()));
// Replace the original image with the resized image
xObjects.put(imgRef, imgNew.getXObject().getPdfObject());
}
}
pdfDoc.close();
}
/**
* Main method.
*
* #param src the original PDF
* #param dest the resulting PDF
* #param resizeFactor factor to multiplicate to resize image
* #throws IOException
*/
public static void main(String[] args) throws IOException {
//Get input parametres
if (args.length<3 ) {
System.out.println("Source PDF, Destination PDF and Resize Factor must be provided as parametres");
} else {
String sourcePDF=args[0];
String destPDF=args[1];
Float resizeFactor=Float.valueOf(new String(args[2]));
logger.info("Inovking Resize with args, source:" + sourcePDF
+ " destination:" + destPDF
+ " factor:" + resizeFactor);
//Call method to resize images
new ResizeImageV7().manipulatePdf(sourcePDF,destPDF,resizeFactor);
logger.info("PDF resized");
}
}
}
Related
I am trying to read image objects from a PDF document. The image comes out as black background and white text. How can I reverse that. the image in the pdf, is white foreground and black background.
Here is the code, main piece for loading the image component
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
public class MyImageRenderListener implements RenderListener {
/**
* The new document to which we've added a border rectangle.
*/
protected String path = "";
/**
* Creates a RenderListener that will look for images.
*/
public MyImageRenderListener(String path) {
this.path = path;
}
/**
* #see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
*/
public void beginTextBlock() {
}
/**
* #see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
*/
public void endTextBlock() {
}
/**
* #see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
*com.itextpdf.text.pdf.parser.ImageRenderInfo)
*/
public void renderImage(final ImageRenderInfo renderInfo) {
try {
String filename;
FileOutputStream os;
PdfImageObject image = renderInfo.getImage();
PdfImageObject tmp = null;
PdfName filter = (PdfName) image.get(PdfName.FILTER);
///
PdfDictionary imageDictionary = image.getDictionary();
// Try SMASK, SMASKINDATA
PRStream maskStream = (PRStream) imageDictionary.getAsStream(PdfName.SMASK);
// todo - required - black white - fix
PdfImageObject maskImage = new PdfImageObject(maskStream);
image = maskImage;
if (PdfName.DCTDECODE.equals(filter)) {
filename = String.format(path, renderInfo.getRef().getNumber(), "jpg");
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} else if (PdfName.JPXDECODE.equals(filter)) {
filename = String.format(path, renderInfo.getRef().getNumber(), "jp2");
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} else if (PdfName.JBIG2DECODE.equals(filter)) {
// ignore: filter not supported.
} else {
BufferedImage awtimage = renderInfo.getImage().getBufferedImage();
if (awtimage != null) {
filename = String.format(path, renderInfo.getRef().getNumber(), "png");
ImageIO.write(awtimage, "png", new FileOutputStream(filename));
}
}
try {
final String newfile = String.format(path, renderInfo.getRef().getNumber(), ".x.", "png");
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ImageIO.write(newBi, "png", new FileOutputStream(newfile));
} catch(final Exception e) {
e.printStackTrace();;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static Image makeBlackAndWhitePng(PdfImageObject image) throws IOException, DocumentException {
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(newBi, "png", baos);
return Image.getInstance(baos.toByteArray());
}
/**
* #see com.itextpdf.text.pdf.parser.RenderListener#renderText(
*com.itextpdf.text.pdf.parser.TextRenderInfo)
*/
public void renderText(TextRenderInfo renderInfo) {
}
}
And code around loading the pages
public static void readImages(final PdfReader reader, final File filex) throws IOException {
for (int i = 0; i < reader.getXrefSize(); i++) {
PdfObject pdfobj = reader.getPdfObject(i);
if (pdfobj == null || !pdfobj.isStream()) {
continue;
}
PdfStream stream = (PdfStream) pdfobj;
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {
byte[] img = PdfReader.getStreamBytesRaw((PRStream) stream);
FileOutputStream out = new FileOutputStream(new File(filex.getParentFile(), String.format("%1$05d", i) + ".jpg"));
out.write(img);
out.flush();
out.close();
}
}
}
To combine my comments:
What you see, merely is the soft mask of the image which contains transparency information, white = opaque, black = transparent. The base image actually is all black but only where the mask indicates opaque, that image black is drawn. Thus it looks like reversed.
You can use image manipulation libraries to invert a bitmap. Simply googl'ing for "imageio invert image" returns this, this, and numerous other interesting matches.
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.imageio.ImageIO;
import org.apache.commons.codec.binary.Base64;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
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;
public class One {
/**
* #param args
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Scanner s=new Scanner(System.in);
System.out.println("Enter base64 string to be converted to image");
String base64=s.nextLine();
byte[] base64Val=convertToImg(base64);
writeByteToImageFile(base64Val, "image.png");
System.out.println("Saved the base64 as image in current directory with name image.png");
addImageToPDF();
}
public static byte[] convertToImg(String base64) throws IOException
{
return Base64.decodeBase64(base64);
}
public static void writeByteToImageFile(byte[] imgBytes, String imgFileName) throws IOException
{
File imgFile = new File(imgFileName);
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgBytes));
ImageIO.write(img, "png", imgFile);
}
public static void addImageToPDF() throws IOException {
File file = new File("C:\\Users\\user\\Downloads\\Risk Template(RiskTemplate).pdf");
PDDocument doc = PDDocument.load(file);
PDPage page = doc.getPage(0);
PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\Development\\Workspace\\1\\image.png", doc);
PDPageContentStream contents = new PDPageContentStream(doc, page);
contents.drawImage(pdImage, 5, 5);
System.out.println("Image inserted");
contents.close();
doc.save("D:\\Development\\Workspace\\1\\InsertImage_OP.pdf");
doc.close();
}
}
I am creating an image from base64 string and then trying to attach that image to a pdf. The image is creating successfully and the image is being added to the pdf as well but the pdf (output) contains just the image at a corner and the content of the original pdf is now blank.
As MKL & Tilman have written in their comment you have to use
PDPageContentStream(document, page, AppendMode.APPEND, true, true);
public static void addImageToPDF() throws IOException {
File file = new File("C:\\Users\\user\\Downloads\\Risk Template(RiskTemplate).pdf");
PDDocument doc = PDDocument.load(file);
PDPage page = doc.getPage(0);
PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\Development\\Workspace\\1\\image.png", doc);
PDPageContentStream contents = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true);
contents.drawImage(pdImage, 5, 5);
System.out.println("Image inserted");
contents.close();
doc.save("D:\\Development\\Workspace\\1\\InsertImage_OP.pdf");
doc.close();
}
Disclaimer: This answer was given by MKL/Tilman but for further reference an answer is more "visible" than a comment.
I'm trying to have my program print a few "funny" images whenever it detects motion. Everything works by itself but when I put the if(detection == true) statement into the program, the variable doesn't update. How could I get it to update inside of the motionDetected function?
I've tried using boolean and int for the variable but I think it could be with the way I've structured it.
package printstuff;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.function.Function;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
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.Copies;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamMotionDetector;
import com.github.sarxos.webcam.WebcamMotionEvent;
import com.github.sarxos.webcam.WebcamMotionListener;
/**
* Detect motion.
*
* #author Bartosz Firyn (SarXos)
*/
public class DetectMotion implements WebcamMotionListener {
public static boolean detection = false;
public DetectMotion() {
//creates a webcam motion detector
WebcamMotionDetector detector = new WebcamMotionDetector(Webcam.getDefault());
detector.setInterval(100); // one check per 100 ms
detector.addMotionListener(this);
detector.start();
}
#Override
public void motionDetected(WebcamMotionEvent wme) {
//detects motion and should change the detection variable
System.out.println("Detected motion");
detection = true;
}
public static void main(String[] args) throws IOException, Exception {
new DetectMotion();
System.in.read(); // keep program open
final String[] catImages = new String[4];
//all the images
catImages[0] = "https://i.ytimg.com/vi/3v79CLLhoyE/maxresdefault.jpg";
catImages[1] = "https://i.imgur.com/RFS6RUv.jpg";
catImages[2] = "https://kiwifarms.net/attachments/dozgry5w4ae3cut-jpg.618924/";
catImages[3] = "https://www.foodiecrush.com/wp-content/uploads/2017/10/Instant-Pot-Macaroni-and-Cheese-foodiecrush.com-019.jpg";
//statement does not work..
if(detection == true)
{
for(int i=0; i<4; i++)
{
//saves the picture inside of the array to image.jpg
String imageUrl = catImages[i];
String destinationFile = "image.jpg";
saveImage(imageUrl, destinationFile);
//sends print job to printer
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(new Copies(1));
PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.GIF, pras);
if (pss.length == 0)
throw new RuntimeException("No printer services available.");
PrintService ps = pss[0];
System.out.println("Printing to " + ps);
DocPrintJob job = ps.createPrintJob();
FileInputStream fin = new FileInputStream("image.jpg");
Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.GIF, null);
job.print(doc, pras);
fin.close();
java.util.concurrent.TimeUnit.SECONDS.sleep(15);
}
}
}
public static void saveImage(String imageUrl, String destinationFile) throws IOException {
//converts url into image
URL url = new URL(imageUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
}
}
I am trying to convert the input byte[] image to com.itextpdf.text.Image because I need to put this 2 image in a pdf.
Here my code:
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PushbuttonField;
public class Tryit {
public static void main (String[] args) throws Exception
{
byte[] front = extractBytes("C:/Users/Desktop/Front.png");
byte[] back = extractBytes("C:/Users/Desktop/Back.png");
addImageToPdf(front,back);
}
public static byte[] extractBytes (String ImageName) throws IOException {
// open image
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage .getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
return ( data.getData() );
}
public static void addImageToPdf(byte[] frontByte, byte[] backByte) throws IOException, DocumentException
{
ByteArrayInputStream bais = new ByteArrayInputStream(frontByte);
BufferedImage a = ImageIO.read(bais);
InputStream frontIn = new ByteArrayInputStream(frontByte);
BufferedImage bImageFromFront = ImageIO.read(frontIn);
InputStream backIn = new ByteArrayInputStream(backByte);
BufferedImage bImageFromBack = ImageIO.read(backIn);
ByteArrayOutputStream baosF = new ByteArrayOutputStream();
ImageIO.write(bImageFromFront, "png", baosF);
Image front = Image.getInstance(baosF.toByteArray());
ByteArrayOutputStream baosB = new ByteArrayOutputStream();
ImageIO.write(bImageFromBack, "png", baosB);
Image back = Image.getInstance(baosB.toByteArray());
PdfReader reader = new PdfReader("C:/Users/Desktop/Template.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("C:/Users/Desktop/P1.pdf"));
AcroFields form = stamper.getAcroFields();
PushbuttonField ad = form.getNewPushbuttonFromField("Front");
ad.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
ad.setProportionalIcon(true);
ad.setImage(front);
form.replacePushbuttonField("Front", ad.getField());
PushbuttonField ad1 = form.getNewPushbuttonFromField("Back");
ad1.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
ad1.setProportionalIcon(true);
ad1.setImage(back);
form.replacePushbuttonField("Back", ad1.getField());
stamper.setFormFlattening(true);
stamper.close();
reader.close();
}}
The error is here : BufferedImage bImageFromFront = ImageIO.read(frontIn); infact my bImageFromFront return null, so I have the error here
ImageIO.write(bImageFromFront, "png", baosF);
because my bImageFromFront is null. I don't understand why I have this error and why the conversion from bufferedImage to ImageIO returns null
The following program converts a TIF file to PDF file using itext-library (Version 2.1.7).
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;
import com.lowagie.text.pdf.codec.TiffImage;
import java.io.File;
import java.io.FileOutputStream;
public class Tiff2Pdf {
public static File convert(String tifPath, String pdfPath) {
File pdfFile = null;
String imgeFilename = tifPath;
Document document = new Document();
try {
PdfWriter writer = PdfWriter.getInstance(
document,
new FileOutputStream(pdfPath));
writer.setStrictImageSequence(true);
Image image;
document.open();
RandomAccessFileOrArray ra = new RandomAccessFileOrArray(imgeFilename);
int pagesTif = TiffImage.getNumberOfPages(ra);
for (int i = 1; i <= pagesTif; i++) {
image = TiffImage.getTiffImage(ra, i);
image.scaleAbsolute(PageSize.A4.getWidth(), PageSize.A4.getHeight());
Rectangle pageSize = new Rectangle(633, 842);
document.setPageSize(pageSize);
document.newPage();
document.add(image);
}
pdfFile = new File(pdfPath);
document.close();
PdfReader read = new PdfReader(pdfPath);
} catch (Exception ex) {
//do nothing
}
return pdfFile;
}
}
But the PDF file is not aligned centered.
How can the converted TIF file be aligned centrally in PDF file?
The solution is:
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;
import com.lowagie.text.pdf.codec.TiffImage;
import java.io.File;
import java.io.FileOutputStream;
/**
*
* #author Rahman
*/
public class Tiff2Pdf {
public static File convert(String tif, String pdf) {
File pdfFile = null;
String imgeFilename = tif;
Document document = new Document();
try {
PdfWriter writer = PdfWriter.getInstance(
document,
new FileOutputStream(pdf));
writer.setStrictImageSequence(true);
Image image;
document.open();
RandomAccessFileOrArray ra = new RandomAccessFileOrArray(imgeFilename);
int pagesTif = TiffImage.getNumberOfPages(ra);
for (int i = 1; i <= pagesTif; i++) {
image = TiffImage.getTiffImage(ra, i);
image.scaleAbsolute(PageSize.A4.getWidth(), PageSize.A4.getHeight());
document.setMargins(0, 0, 0, 0);
document.newPage();
document.add(image);
}
pdfFile = new File(pdf);
document.close();
} catch (Exception ex) {
//do nothing
}
return pdfFile;
}
}