I have created a web service that has a method which takes in a parameter of DataHandler. The purpose of this method is to read in what is sent over DataHandler and write it to a file(.tiff). When I pass in a .tiff file i can easily make a conversion but how should I make a conversion from a pdf file to a .tiff file using Java.
So if a user passes in a pdf file using DataHandler, how can I convert that to a .tiff file?
PDDocument doc = PDDocument.loadNonSeq(new File(filename), null);
boolean b;
List<PDPage> pages = doc.getDocumentCatalog().getAllPages();
for (int p = 0; p < pages.size(); ++p)
{
// RGB image with 300 dpi
BufferedImage bim = pages.get(p).convertToImage(BufferedImage.TYPE_INT_RGB, 300);
// alternatively: B/W image with 300 dpi
bim = pages.get(p).convertToImage(BufferedImage.TYPE_BYTE_BINARY, 300);
// save as TIF with dpi in the metadata
// PDFBox will choose the best compression for you
// you need to add jai_imageio to your classpath for this to work
b = ImageIOUtil.writeImage(bim, "page-" + (p+1) + ".tif", 300);
if (!b)
{
// error handling
}
}
If your question is about converting to a multipage TIFF, please say so, I have a solution for this too.
Related
Please let me know what method can be used to convert pdf to image in iText7.
In Itexsharp, there was an option to convert pdf file to images. Following is the link. PDF to Image Using iTextSharp
http://www.c-sharpcorner.com/UploadFile/a0927b/create-pdf-document-and-convert-to-image-programmatically/
Below is the sample code created using the following refernce link.
itext7 pdf to image
this is not working as expected. It is not converting the pdf to image. It is creating a 1kb blank image.
string fileName = System.IO.Path.GetFileNameWithoutExtension(inputFilePath);
var pdfReader = new PdfReader(inputFilePath);
var pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfReader);
int pagesLength = pdfDoc.GetNumberOfPages()+1;
for (int i = 1; i < pagesLength; i++)
{
if (!File.Exists(System.IO.Path.Combine(imageFileDir, fileName + "_" +
`enter code here`(startIndex + i) + ".png")) && i < pagesLength)
{
PdfPage pdfPages = pdfDoc.GetPage(i);
PdfWriter writer = new PdfWriter(System.IO.Path.Combine(imageFileDir, fileName + "_" + (startIndex + i) + ".png"), new WriterProperties().SetFullCompressionMode(true));
PdfDocument pdf = new PdfDocument(writer);
PdfFormXObject pageCopy = pdfPages.CopyAsFormXObject(pdf);
iText.Layout.Element.Image image = new iText.Layout.Element.Image(pageCopy);
}
}
Quoting Bruno:
iText does not convert PDFs to raster images (such as .jpg, .png,...). You are misinterpreting the examples that create an Image instance based on an existing page. Those examples create an XObject that can be reused in a new PDF as if it were a vector image; they don't convert a PDF page to a raster image.
What you can use for this (which is what we at iText internally use for testing) is GhostScript. It takes a pdf as input and converts it to a series of images (one image per page).
I need to generate barcode in 128A format with data: 900000588548001100001305000000000207201512345.6|12345.7
I'm using ZXing library and Here is my method:
private void barcodeGenerator(String data)
{
try
{
com.google.zxing.MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix bm = writer.encode(data, BarcodeFormat.CODE_128, 700, 200);
Bitmap ImageBitmap = Bitmap.createBitmap(700, 200, Config.ARGB_8888);
for (int i = 0; i < 700; i++)
{//width
for (int j = 0; j < 200; j++)
{//height
ImageBitmap.setPixel(i, j, bm.get(i, j) ? Color.BLACK : Color.WHITE);
}
}
File f = new File(Environment.getExternalStorageDirectory() + "/barcode1.png");
FileOutputStream fos = new FileOutputStream(f);
ImageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
}
catch(Exception e)
{
e.printStackTrace();
}
}
This method generates and stores the barcode image in SDCard which m scanning using ZXing Barcode Scanner.
Barcode is successfully scanned when data is small. eg: 123.4|456.7
But if data is large, eg: 900000588548001100001305000000000207201512345.6|12345.7
It looks like some wrong barcode is generated and Scanner is not able to scan the generated barcode.
Thanks in advance for help.
Edit: Have added generated barcode images
You can upload the barcode image you produced to the ZXing Decoder Online to confirm if it is valid:
http://zxing.org/w/decode.jspx
There is no intrinsic limit to the length of a Code 128 barcode, and all the characters you have are valid.
Having said that, with Code 128A barcodes, having more than 20 characters encoded makes the resultant barcode very wide and hard to scan.
It is likely that the barcode is valid but the scanners camera is not able to get a clear enough picture of such a large barcode.
Take a look at this question for more information: Unable to scan Code 128
If possible, it would be recommended to use an alternative barcode format, such as QR code, which can store more data without increasing the barcode size.
https://play.google.com/store/apps/details?id=com.srowen.bs.android
android app scans perfectly. But while generating barcode make sure it's less width and height as possible, to easily fit to mobile camera to scan.
I regenerated barcode of CODE-128 for 900000588548001100001305000000000207201512345.6|12345.7 with just 300 and 150 it's able to scan, if it's not working for you then can scale up width and height.
Barcode generated: https://i.stack.imgur.com/UF0qJ.png
Screenshot after scanning
How can I convert one WMF file to PNG/BMP/JPG format with custom output resolution?
Example: Take WMF file and outputs PNG file with 2000x2000 px.
Thanks in advance.
You can use the excelent Batik ( http://xmlgraphics.apache.org/batik/ ) lib to achieve this. But you will need to follow this steps:
Convert the WMF file to SVG using the WMFTranscoder
Convert the SVG to JGP using the JPGTranscoder
WMF >> SVG >> JPG
Here is a discussion on coderanch about it: http://www.coderanch.com/t/422868/java/java/converting-WMF-Windows-Meta-File
WMF, EMF and EMF+ are integral parts of slideshows, therefore I've developed a renderer for those as part of Apache POI. As for the upcoming POI-4.1.2 this is still work in progress - if you have any rendering issues, please upload your file in a new bug report in our bugzilla.
The main description can be found in the POI documentation.
Here is an excerpt:
#1 - Use PPTX2PNG via file or stdin
For file system access, you need to save your slideshow/WMF/EMF/EMF+ first to disc and then call PPTX2PNG.main() with the corresponding parameters.
for stdin access, you need to redirect System.in before:
/* the file content */
InputStream is = ...;
/* Save and set System.in */
InputStream oldIn = System.in;
try {
System.setIn(is);
String[] args = {
"-format", "png", // png,gif,jpg,svg or null for test
"-outdir", new File("out/").getCanonicalPath(),
"-outfile", "export.png",
"-fixside", "long",
"-scale", "800",
"-ignoreParse",
"stdin"
};
PPTX2PNG.main(args);
} finally {
System.setIn(oldIn);
}
#2 - Render WMF / EMF / EMF+ via the *Picture classes
File f = samples.getFile("santa.wmf");
try (FileInputStream fis = new FileInputStream(f)) {
// for WMF
HwmfPicture wmf = new HwmfPicture(fis);
// for EMF / EMF+
HemfPicture emf = new HemfPicture(fis);
Dimension dim = wmf.getSize();
int width = Units.pointsToPixel(dim.getWidth());
// keep aspect ratio for height
int height = Units.pointsToPixel(dim.getHeight());
double max = Math.max(width, height);
if (max > 1500) {
width *= 1500/max;
height *= 1500/max;
}
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
wmf.draw(g, new Rectangle2D.Double(0,0,width,height));
g.dispose();
ImageIO.write(bufImg, "PNG", new File("bla.png"));
}
You can use different tools for this format. You can choose for example GIMP. In Java you have a library for converting WMF files.
I wrote a walkaround here, for Java I learned that I can run shell command following answers in this question. For WMF, convert it to EMF first following this answer.
I am using the imgscalr Java library to resize an image .
The result of a resize() method call is a BufferedImage object. I now want to save this as a file (usually .jpg).
How can I do that? I want to go from BufferedImage -> File but perhaps this is not the correct approach?
File outputfile = new File("image.jpg");
ImageIO.write(bufferedImage, "jpg", outputfile);
The answer lies within the Java Documentation's Tutorial for Writing/Saving an Image.
The Image I/O class provides the following method for saving an image:
static boolean ImageIO.write(RenderedImage im, String formatName, File output) throws IOException
The tutorial explains that
The BufferedImage class implements the RenderedImage interface.
so it's able to be used in the method.
For example,
try {
BufferedImage bi = getMyImage(); // retrieve image
File outputfile = new File("saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
// handle exception
}
It's important to surround the write call with a try block because, as per the API, the method throws an IOException "if an error occurs during writing"
Also explained are the method's objective, parameters, returns, and throws, in more detail:
Writes an image using an arbitrary ImageWriter that supports the given format to a File. If there is already a File present, its contents are discarded.
Parameters:
im - a RenderedImage to be written.
formatName - a String containg the informal name of the format.
output - a File to be written to.
Returns:
false if no appropriate writer is found.
Throws:
IllegalArgumentException - if any parameter is null.
IOException - if an error occurs during writing.
However, formatName may still seem rather vague and ambiguous; the tutorial clears it up a bit:
The ImageIO.write method calls the code that implements PNG writing a “PNG writer plug-in”. The term plug-in is used since Image I/O is extensible and can support a wide range of formats.
But the following standard image format plugins : JPEG, PNG, GIF, BMP and WBMP are always be present.
For most applications it is sufficient to use one of these standard plugins. They have the advantage of being readily available.
There are, however, additional formats you can use:
The Image I/O class provides a way to plug in support for additional formats which can be used, and many such plug-ins exist. If you are interested in what file formats are available to load or save in your system, you may use the getReaderFormatNames and getWriterFormatNames methods of the ImageIO class. These methods return an array of strings listing all of the formats supported in this JRE.
String writerNames[] = ImageIO.getWriterFormatNames();
The returned array of names will include any additional plug-ins that are installed and any of these names may be used as a format name to select an image writer.
For a full and practical example, one can refer to Oracle's SaveImage.java example.
You can save a BufferedImage object using write method of the javax.imageio.ImageIO class. The signature of the method is like this:
public static boolean write(RenderedImage im, String formatName, File output) throws IOException
Here im is the RenderedImage to be written, formatName is the String containing the informal name of the format (e.g. png) and output is the file object to be written to. An example usage of the method for PNG file format is shown below:
ImageIO.write(image, "png", file);
Create and save a java.awt.image.bufferedImage to file:
import java.io.*;
import java.awt.image.*;
import javax.imageio.*;
public class Main{
public static void main(String args[]){
try{
BufferedImage img = new BufferedImage(
500, 500, BufferedImage.TYPE_INT_RGB );
File f = new File("MyFile.png");
int r = 5;
int g = 25;
int b = 255;
int col = (r << 16) | (g << 8) | b;
for(int x = 0; x < 500; x++){
for(int y = 20; y < 300; y++){
img.setRGB(x, y, col);
}
}
ImageIO.write(img, "PNG", f);
}
catch(Exception e){
e.printStackTrace();
}
}
}
Notes:
Creates a file called MyFile.png.
Image is 500 by 500 pixels.
Overwrites the existing file.
The color of the image is black with a blue stripe across the top.
Download and add imgscalr-lib-x.x.jar and imgscalr-lib-x.x-javadoc.jar to your Projects Libraries.
In your code:
import static org.imgscalr.Scalr.*;
public static BufferedImage resizeBufferedImage(BufferedImage image, Scalr.Method scalrMethod, Scalr.Mode scalrMode, int width, int height) {
BufferedImage bi = image;
bi = resize( image, scalrMethod, scalrMode, width, height);
return bi;
}
// Save image:
ImageIO.write(Scalr.resize(etotBImage, 150), "jpg", new File(myDir));
As a one liner:
ImageIO.write(Scalr.resize(ImageIO.read(...), 150));
I have a pdf document containing several images.
I want to retrieve names of these images.
How to achieve this using either iText or pdfbox?
I know that ExtractImages extracts images from PDF. I feel that this will somewhere have the functionality to fetch name of the image. However, I don't know the usage of ExtractImages.
The actual problem to fetch names of PDF is to use it to compress these images to reduce the size of the pdf. Is my approach correct?
What you can get with pdfbox is the key of the image and its suffix (type). You can also save that image.
String prefix = new File(pdfFilename).getName();
prefix = prefix.substring(0, prefix.indexOf(".pdf"));
PDDocument document = null;
try
{
document = PDDocument.loadNonSeq(new(pdfFilename), null); // use non-seq parser is better
List<PDPage> pages = document.getDocumentCatalog().getAllPages();
System.out.println(pdfFilename + ": Total pages: " + pages.size());
int p = 0;
for (PDPage page : pages)
{
++p;
PDResources resources = page.getResources();
Map<String, PDXObjectImage> imageResources = resources.getImages();
for (String key : imageResources.keySet())
{
PDXObjectImage objectImage = imageResources.get(key);
System.out.printf("image key '%s': %d x %d, type %s%n", key, objectImage.getHeight(), objectImage.getWidth(), objectImage.getSuffix());
// write that image
String fname = String.format("%s-%04d-%s", prefix, p, key);
objectImage.write2file(fname);
}
}
}
// put catch here
document.close();
However this won't help you unless you are sure that all these images were converted directly to PDF, i.e. without rotation, translation or scaling. If you need this, then you might want to have a look at the PrintImageLocations.java example in the PDFBOX src download.