how can I get the bytes from an image generated using itext's barcode39 class ? I have:
Document document = new Document(new Rectangle(340, 842));
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
PdfContentByte cb = writer.getDirectContent();
Barcode39 code39ext = new Barcode39();
code39ext.setCode("Testing Text");
code39ext.setStartStopText(false);
code39ext.setExtended(true);
Image img = code39ext.createImageWithBarcode(cb, null, null);
Now I need help to get the bytes from img in order to send it via email and save it to a file.
Thanks in advance.
Assuming that you actually do not need the PDF file but only the barcode image, then you might try:
Barcode39 code39ext = new Barcode39();
code39ext.setCode("Testing Text");
code39ext.setStartStopText(false);
code39ext.setExtended(true);
java.awt.Image rawImage = code39ext.createAwtImage(Color.BLACK, Color.WHITE);
BufferedImage outImage = new BufferedImage(rawImage.getWidth(null), rawImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
outImage.getGraphics().drawImage(rawImage, 0, 0, null);
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ImageIO.write(outImage, "png", bytesOut);
bytesOut.flush();
byte[] pngImageData = bytesOut.toByteArray();
This should just create the barcode image, render it to memory and save it to a stream / byte[] for further usage.
Related
So as the title says I am looking for a way to turn SVG to PNG with Apache Batik and then attach this image to PDF file using PDFBox without actually creating the svg and png anywhere.
Currently I have a web form that has SVG image with selectable parts of it.
When the form is submitted I take the "html" part of the svg meaning I keep something like <svg bla bla> <path bla bla/></svg> in a string that Spring then uses to create a ".svg" file in a given folder, then Batik creates a PNG file in the same folder and then PDFBox attaches it to the PDF - this works fine(code below).
//Get the svg data from the Form and Create the svg file
String svg = formData.getSvg();
File svgFile = new File("image.svg");
BufferedWriter writer = new BufferedWriter(new FileWriter(svgFile));
writer.write(svg);
writer.close();
// Send to Batik to turn to PNG
PNGTranscoder pngTranscode = new PNGTranscoder();
File svgFile = new File("image.svg");
InputStream in = new FileInputStream(svgFile);
TranscoderInput tIn = new TranscoderInput(in);
OutputStream os = new FileOutputStream("image.png");
TranscoderOutput tOut = new TranscoderOutput(os)
pngTranscode .transcode(tIn , tOut);
os.flush();
os.close();
//Send to PDFBox to attach to pdf
File pngfile = new File("image.png");
String path = pngfile.getAbsolutePath();
PDImageXObject pdImage = PDImageXObject.createFromFile(path, pdf);
PDPageContentStream contents = new PDPageContentStream(pdf, pdf.getPage(1));
contents.drawImage(pdImage, 0, pdf.getPage(1).getMediaBox().getHeight() - pdImage.getHeight());
contents.close();
As you can see there are a lot of files and stuff (need to tidy it up a bit), but is it possible to do this on the run without the creation and constant fetching of the svg and png files?
Given the suggestion in the comments I opted for using ByteArrayOutputStream, ByteArrayInputStream, BufferedImage and LosslessFactory. Its a bit slower than the saving (if you go through it in debug as seems the BufferedImage goes on a holiday first before creating the image).
The sources I found to use are: How to convert SVG into PNG on-the-fly and Print byte[] to pdf using pdfbox
byte[] streamBytes = IOUtils.toByteArray(new ByteArrayInputStream(formData.getSvg().getBytes()));
PNGTranscoder pngTranscoder = new PNGTranscoder();
ByteArrayOutputStream os = new ByteArrayOutputStream();
pngTranscoder.transcode(new TranscoderInput(new ByteArrayInputStream(streamBytes)), new TranscoderOutput(os));
InputStream is = new ByteArrayInputStream(os.toByteArray());
BufferedImage bim = ImageIO.read(is);
PDImageXObject pdImage = LosslessFactory.createFromImage(pdf, bim);
PDPageContentStream contents = new PDPageContentStream(pdf, pdf.getPage(1));
contents.drawImage(pdImage, 0, pdf.getPage(1).getMediaBox().getHeight() - pdImage.getHeight());
contents.close();
Based on the comments and links provided by D.V.D., I also worked through the problem. I just wanted to post the simple but full example, for anyone wanting to review in the future.
public class App {
private static String OUTPUT_PATH = "D:\\so52875145\\output\\PdfWithPngImage.pdf";
public static void main(String[] args) {
try {
// obtain the SVG source (hardcoded here, but the OP would obtain the String from form data)
byte[] svgByteArray = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><polygon points=\"200,10 250,190 160,210\" style=\"fill:lime;stroke:purple;stroke-width:1\" /></svg>".getBytes();
System.out.println("Converted svg to byte array...");
// convert SVG into PNG image
PNGTranscoder pngTranscoder = new PNGTranscoder();
ByteArrayOutputStream os = new ByteArrayOutputStream();
pngTranscoder.transcode(new TranscoderInput(new ByteArrayInputStream(svgByteArray)), new TranscoderOutput(os));
System.out.println("Transcoded svg to png...");
// create PDF, and add page to it
PDDocument pdf = new PDDocument();
pdf.addPage(new PDPage());
// generate in-memory PDF image object, using the transcoded ByteArray stream
BufferedImage bufferedImage = ImageIO.read( new ByteArrayInputStream(os.toByteArray()) );
PDImageXObject pdImage = LosslessFactory.createFromImage(pdf, bufferedImage);
System.out.println("Created PDF image object...");
// write the in-memory PDF image object to the PDF page
PDPageContentStream contents = new PDPageContentStream(pdf, pdf.getPage(0));
contents.drawImage(pdImage, 0, 0);
contents.close();
System.out.println("Wrote PDF image object to PDF...");
pdf.save(OUTPUT_PATH);
pdf.close();
System.out.println("Saved PDF to path=[" + OUTPUT_PATH + "]");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
I am trying to create a preview for PDF files which are created by Ballasamic Mockups. Around 50% of the time, I am not getting a preview and getting xref missing error. What am I doing wrong?
Error log :
com.sun.pdfview.PDFParseException: Expected 'xref' at start of table
at com.sun.pdfview.PDFFile.readTrailer(PDFFile.java:974)
at com.sun.pdfview.PDFFile.parseFile(PDFFile.java:1175)
at com.sun.pdfview.PDFFile.<init>(PDFFile.java:126)
at com.sun.pdfview.PDFFile.<init>(PDFFile.java:102)
Code :
private byte[] onlyCreatePdfPreview(String path, int attachId) {
try {
File file = new File(path);
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new com.sun.pdfview.PDFFile(buf);
PDFPage page = pdffile.getPage(0);
Rectangle rect = new Rectangle(0, 0,
(int) page.getBBox().getWidth(),
(int) page.getBBox().getHeight());
java.awt.Image img = page.getImage(
rect.width, rect.height, //width & height
rect, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true // block until drawing is done
);
BufferedImage buffered = toBufferedImage(img);
buffered = Scalr.resize(buffered, Scalr.Method.ULTRA_QUALITY, 400, 250);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(buffered, "png", baos);
baos.flush();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
}
What am I doing wrong? Thank you.
Final Working code
try {
String pdfPath = zipLocation + String.valueOf(new BigInteger(130, random).toString(32));
PdfReader reader = new PdfReader(path);
PdfStamper pdfStamper = new PdfStamper(reader,new FileOutputStream(pdfPath));
pdfStamper.getWriter().setPdfVersion(PdfWriter.PDF_VERSION_1_4);
pdfStamper.close();
reader.close();
RandomAccessFile raf = new RandomAccessFile(pdfPath, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new com.sun.pdfview.PDFFile(buf);
PDFPage page = pdffile.getPage(0);
Rectangle rect = new Rectangle(0, 0,
(int) page.getBBox().getWidth(),
(int) page.getBBox().getHeight());
java.awt.Image img = page.getImage(
rect.width, rect.height, //width & height
rect, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true // block until drawing is done
);
BufferedImage buffered = toBufferedImage(img);
buffered = Scalr.resize(buffered, Scalr.Method.ULTRA_QUALITY, 400, 250);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(buffered, "png", baos);
baos.flush();
return baos.toByteArray();
}//catch block
(This answer collects information from comments to the question which eventually led to a solution.)
Apparently com.sun.pdfview.PDFFile expects the cross references to start with xref. But this expectation only makes sense for PDFs following a PDF Reference up to revision 3 (version 1.4) published November 2001; PDFs following a later Reference or even the ISO 32000 standard (part 1 or 2) have the choice of using a cross reference stream (starting with an object number) instead of a cross reference table (starting with xref).
Thus, one should switch to using software following newer specifications than some more than 15 years old version or one has to convert one's PDFs to follow the old specifications, at least on the surface.
One can convert manually (e.g. using Adobe Acrobat) or automatized (e.g. using iText). (These examples software products really are only examples, other products can also be used for this task.)
If using a current iText 5 version, the conversion looks like this:
PdfReader reader = new PdfReader(SOURCE);
PdfStamper stamper = new PdfStamper(reader, DEST);
stamper.getWriter().setPdfVersion(PdfWriter.PDF_VERSION_1_4);
stamper.close();
reader.close();
And one has to take care that if SOURCE is a file name or a random access file, DEST must not be a file output stream to the same file. Otherwise the original file is truncated before the PdfStamper had a chance to copy it all to its output.
I am working with a bytearray which contains multiple images. How can I retrieve the images from the bytearray in Java.
PDDocument document = null;
int pageCounter = 0;
BufferedImage bim = null;
document = PDDocument.load(pdfBytes);
PDFRenderer pdfRenderer = new PDFRenderer(document);
bim = pdfRenderer.renderImageWithDPI(pageCounter, 300, ImageType.RGB);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(rotate(bim), imageFormat, bos);
output = bos.toByteArray();
rotate is a method to rotate the image. I want to rotate only one Image. The other I do not want to rotate. Also I want to output it again in Bytes
I'm trying to create remote control application in Java. I'm using robot to capture my screen image, and then I need to send it to the server. However, because the image size may be too big for the sending to be quick as possible, I'm changing the image quality in the code.
The problem is with the code I have, after changing the image it automatically save it as file in my computer but I don't want it to. I want it to the change it without saving it to be able to send it to my server
The code:
Robot robot = null;
Rectangle rectangle = null;
GraphicsEnvironment gEnv=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gDev=gEnv.getDefaultScreenDevice();
//Get screen dimensions
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
rectangle = new Rectangle(dim);
System.out.println(rectangle);
robot = new Robot(gDev);
BufferedImage image = robot.createScreenCapture(rectangle);
// FileInputStream inputStream = new FileInputStream(MyFile);
// BufferedImage originalImage = ImageIO.read(inputStream);
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
float quality = 0.25f; // reduce quality by 50%
iwp.setCompressionQuality(quality);
File file = new File("Tester6.png");
FileImageOutputStream output = new FileImageOutputStream(file);
writer.setOutput(output);
IIOImage image1 = new IIOImage(image, null, null);
writer.write(null, image1, iwp);
writer.dispose();
Instead of creating a file, do:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
writer.setOutput(ios);
You can then use baos.toByteArray() to get the bytes after you have called writer.write().
I have a java.awt.Image that I need to add CCITT T.6 compression and convert to a TIFF byte array. I have seen some examples of using TIFFImageWriteParam and other classes from the javax.imageio package but I can’t find a complete example going all the way from Image to byte array.
Here is what I have so far beginning with a java.awt.Image obtained from scanning. This works just fine to generate a byte array of a TIFF, but I need to find a way, using TIFFImageWriteParam or some other means, to compress the TIFF prior to processing it as a byte array:
thisImage = ... a java.awt.Image from a scanner
if(thisImage!=null){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage bimg = new BufferedImage(thisImage.getWidth(null),thisImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
bimg.createGraphics().drawImage(thisImage, 0, 0, null);
try {
ImageIO.write(bimg, "tiff", baos);
} catch (Exception e) {
e.printStackTrace();
}
thisByteArray = baos.toByteArray();
...
Any help would be appreciated.
I found a solution thanks to: this thread.
Here is what I ended up doing that solved my issue:
thisImage = thisImage = ... a java.awt.Image from a scanner
if(thisImage!=null){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
boolean foundWriter = false;
BufferedImage bimg = new BufferedImage(thisImage.getWidth(null),thisImage.getHeight(null), BufferedImage.TYPE_BYTE_BINARY);
bimg.createGraphics().drawImage(thisImage, 0, 0, null);
for(Iterator<ImageWriter> writerIter = ImageIO.getImageWritersByFormatName("tif"); writerIter.hasNext() && !foundWriter;) {
foundWriter = true;
ImageWriter writer = (ImageWriter)writerIter.next();
writer.setOutput(ios);
TIFFImageWriteParam writeParam = (TIFFImageWriteParam)writer.getDefaultWriteParam();
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionType("CCITT T.6");
writer.prepareWriteSequence(null);
ImageTypeSpecifier spec = ImageTypeSpecifier.createFromRenderedImage(bimg);
javax.imageio.metadata.IIOMetadata metadata = writer.getDefaultImageMetadata(spec, writeParam);
IIOImage iioImage = new IIOImage(bimg, null, metadata);
writer.writeToSequence(iioImage, writeParam);
bimg.flush();
writer.endWriteSequence();
ios.flush();
writer.dispose();
ios.close();
thisByteArray = baos.toByteArray();
baos.close();
}
}