Retrieve multiple images from a bytearray in Java - java

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

Related

Java : PDF page preview error, expected xref

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.

8 bit gray scale image byte array to jpg

I am trying to convert a 8 bit gray scale image byte array to jpg image format in java.
static byte[] bytes = new byte[]{126, 126, 127, -128};
public static void main(String[] args) throws IOException {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("jpg");
ImageReader reader = (ImageReader) readers.next();
Object source = bis;
ImageInputStream iis = ImageIO.createImageInputStream(source);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
File imageFile = new File("C:\\newrose3.jpg");
ImageIO.write(bufferedImage, "jpg", imageFile);
System.out.println(imageFile.getPath());
}
I have bytes having image data and I want to convert it into readable image format in java.
Assuming bytes is supposed to be pixel data, you should create an image from those bytes, then write it out as JPEG.
Something like:
// Create an image type grayscale
BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_BYTE_GRAY);
// Get the backing pixels, and copy into it
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(bytes, 0, data, 0, bytes.length);
// Write it out:
ImageIO.write(image, "jpg", new File("yourPathHere");

Adding multiple images to a PDF document with itext in android

I am developing an android application in which i want to add multiple high resolution images to the pdf file with itext jar. I am getting an out of memory exception. When I set the smaller values for width and height it works fine. This is implemented inside a async background task class. The source code is as follows
fos = new FileOutputStream(pdfFilePath);
//Rectangle pagesize = new Rectangle(595.44f, 841.68f);
document = new Document(PageSize.A4, 0f, 0f, 0f, 0f);
PdfWriter.getInstance(document,new FileOutputStream(pdfFilePath));
fileArray = imageDirectory.listFiles();
Log.d("Files", "Size: "+ fileArray.length);
for (i=0; i < fileArray.length; i++){
document.open();
bMap= BitmapFactory.decodeFile(fileArray[i].getPath(), null);
bMap = Bitmap.createScaledBitmap(bMap, 2339, 1654, false);
matrix = new Matrix();
matrix.postRotate(90);
bMap = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), matrix, false);
bMap = toGrayscale(bMap);
stream = new ByteArrayOutputStream();
bMap.compress(Bitmap.CompressFormat.JPEG, 25, stream);
byteArray = stream.toByteArray();
document.add(Image.getInstance(byteArray));
Log.e("Files", "FileName:" + fileArray[i].getName());
bMap = null;
matrix = null;
byteArray = null;
stream = null;
document.close();
}
fos.close();
See: Managing Bitmap Memory.
You probably want to call bMap.recycle() before setting it to null.

Changing image quality

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().

Get bytes from iText's Barcode39 image

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.

Categories