Skip to main content

breaking Tiff into multiple pages not saving correctly...

9 replies [Last post]
jparrish
Offline
Joined: 2007-02-27
Points: 0

I'm very new to this jai stuff and had a question in regards to some problems I'm facing. I am trying to take a raw byte array from a TIFF and break it up into a seperate TIFF for each page in the original raw data. I've got everything working almost, but the individual TIFF files that I create for each page all seem larger than the original doc, are all the same size, and all appear skewed and zoomed in very closely when I view them. It seems like perhaps there is some metatdata in the original tiff that I'm not passing on to the individual ones. Please provide any tips or help you can think of, if possible.

I'll attach the code I'm using. First of all, here is the method I wrote to get the arraylist of pages from the original tiff's byte array, and I think perhaps this is the one with the issue...

/////////////////////////////method to get array list of page data
public ArrayList getTiffPagesAsByteArrayList(byte[] argFileBytes) throws Exception{

ArrayList tiffList = new ArrayList(); //list with byte[] images of tiffs
ByteArrayOutputStream baos;
ByteArraySeekableStream bArrSeekStream = null;
bArrSeekStream = new ByteArraySeekableStream(argFileBytes);
ImageDecoder dec = ImageCodec.createImageDecoder("TIFF", bArrSeekStream, null);
int noOfPages = dec.getNumPages();

boolean bWriteResult = false;

for (int pageNbr = 0; pageNbr < noOfPages; pageNbr++){
baos = new ByteArrayOutputStream();
System.out.println("BAOS Size: " + baos.size());
bWriteResult = ImageIO.write(dec.decodeAsRenderedImage(pageNbr), "TIFF", baos);
System.out.println("BAOS Size: " + baos.size() + " -> " + bWriteResult);
tiffList.add(baos.toByteArray());
}
return tiffList;

}
////////////////////////end of first method

I pass the original byte array into the method above and get back an array list, which I iterate through with the code below to call the write method for each page...

//////////code to iterate though the list and write each page to the filesystem
ArrayList alTifPages = getTiffPagesAsByteArrayList(fileContents);

if (alTifPages != null && alTifPages.size() > 0) {
for (int i=0;i

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
lcfonseca
Offline
Joined: 2007-04-06
Points: 0

I forgot to remove a stretch of the function, would be this:

// BufferedImage bufferedImage = null;
// while (true) {
// ByteArrayInputStream bais = new ByteArrayInputStream(out);
// bufferedImage = ImageIO.read(bais);
// }

lcfonseca
Offline
Joined: 2007-04-06
Points: 0

...
if (!foundWriter) {
throw new RuntimeException("Error: no writer found for image type '" + imageType + "'");
}
}
pdf.closePdfFile();

BufferedImage bufferedImage = null;
while (true) {
ByteArrayInputStream bais = new ByteArrayInputStream(out);
bufferedImage = ImageIO.read(bais);
}
}
catch (Exception e) {
e.printStackTrace();
}
return out;
}

Brian Burkhalter

One quick comment: if you are new to JAI then you should be using the JAI
Image I/O Tools plugins https://jai-imageio.dev.java.net in preference to the
older com.sun.media.jai.codec classes which they supersede.

As to the problem at hand, what version are you using and could you supply a
self-contained test case without hard-coded paths, particular those which are
OS-dependent?

Brian

On Tue, 27 Feb 2007, jai-imageio@javadesktop.org wrote:

> I'm very new to this jai stuff and had a question in regards to some problems I'm facing. I am trying to take a raw byte array from a TIFF and break it up into a seperate TIFF for each page in the original raw data. I've got everything working almost, but the individual TIFF files that I create for each page all seem larger than the original doc, are all the same size, and all appear skewed and zoomed in very closely when I view them. It seems like perhaps there is some metatdata in the original tiff that I'm not passing on to the individual ones. Please provide any tips or help you can think of, if possible.
>
> I'll attach the code I'm using. First of all, here is the method I wrote to get the arraylist of pages from the original tiff's byte array, and I think perhaps this is the one with the issue...
>
> /////////////////////////////method to get array list of page data
> public ArrayList getTiffPagesAsByteArrayList(byte[] argFileBytes) throws Exception{
>
> ArrayList tiffList = new ArrayList(); //list with byte[] images of tiffs
> ByteArrayOutputStream baos;
> ByteArraySeekableStream bArrSeekStream = null;
> bArrSeekStream = new ByteArraySeekableStream(argFileBytes);
> ImageDecoder dec = ImageCodec.createImageDecoder("TIFF", bArrSeekStream, null);
> int noOfPages = dec.getNumPages();
>
> boolean bWriteResult = false;
>
> for (int pageNbr = 0; pageNbr < noOfPages; pageNbr++){
> baos = new ByteArrayOutputStream();
> System.out.println("BAOS Size: " + baos.size());
> bWriteResult = ImageIO.write(dec.decodeAsRenderedImage(pageNbr), "TIFF", baos);
> System.out.println("BAOS Size: " + baos.size() + " -> " + bWriteResult);
> tiffList.add(baos.toByteArray());
> }
> return tiffList;
>
> }
> ////////////////////////end of first method
>
>
> I pass the original byte array into the method above and get back an array list, which I iterate through with the code below to call the write method for each page...
>
> //////////code to iterate though the list and write each page to the filesystem
> ArrayList alTifPages = getTiffPagesAsByteArrayList(fileContents);
>
> if (alTifPages != null && alTifPages.size() > 0) {
> for (int i=0;i > System.out.println("Writing page " + i);
> byte[] thisPage = (byte[])alTifPages.get(i);
> writeTifFile(thisPage,i);
> System.out.println("After writing page " + i);
> }
> }
> //////end of code
>
> And here is the write method I'm using...
>
> ///////////////////////actual method to write each file to filesystem
> public void writeTifFile(byte[] argFileBytes,int pageNumber) {
> //save the BufferedImage as a tif
> try {
> File file = new File("c:\\temp\\images\\", "output_page_" + pageNumber + ".tif");
> FileOutputStream out = new FileOutputStream(file);
> out.write(argFileBytes);
> out.close();
> } catch (Exception ex) {
> ex.printStackTrace();
> }
> }
> ////////////////////////////end of writeTifFile
> [Message sent by forum member 'jparrish' (jparrish)]
>
> http://forums.java.net/jive/thread.jspa?messageID=205538
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-imageio.dev.java.net
>
>

----------------
Brian Burkhalter
Java Media, Imaging, and Graphics
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

jparrish
Offline
Joined: 2007-02-27
Points: 0

Thanks again for the help. I'm using the following:

jai 1.1.3
jai-imageio 1.1
j2sdk 1.4.2_12

I will look into https://jai-imageio.dev.java.net

as for a self contained example, I'm fairly certain that the issue is in the getTiffPagesAsByteArrayList method I pasted, which is fairly independant of the environment OS etc... let me know if you still need me to write an entire self-contained example...

jparrish
Offline
Joined: 2007-02-27
Points: 0

I'm a little lost trying to figure out what to do by just looking at the javadoc for jai-imageio...

It was implied from previous posts and other threads I've read on here that I should not have to use any jai api stuff, but rather just jai-imageio api stuff... so I assume I should not be using ByteArraySeekableStream and the ImageCodec and the ImageDecoder classes, but I don't know any other way to splice out specific pages from the original TIF (in this example I splice out the last page)

What jai-imageio classes/techniques should I be using to replace this code?

////////////////code example start
import java.io.ByteArrayOutputStream;
...
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import com.sun.media.jai.codec.ByteArraySeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;

...
...
...
//argFileBytes is a byte array (byte[]) from an actual TIF image

ByteArrayOutputStream baos;
ByteArraySeekableStream bArrSeekStream = null;
bArrSeekStream = new ByteArraySeekableStream(argFileBytes);
ImageDecoder dec = ImageCodec.createImageDecoder("TIFF", bArrSeekStream, null);
int noOfPages = dec.getNumPages();

boolean bWriteResult = false;

//write the last page to boas
bWriteResult = ImageIO.write(dec.decodeAsRenderedImage(noOfPages-1), "TIFF", baos);

///////////////////code example end

Message was edited by: jparrish

jparrish
Offline
Joined: 2007-02-27
Points: 0

I've replaced the code above with java image i/o stuff... but I'm still experiencing the issue/problem... when I export the individual byte arrays returned in the ArrayList from the method below, the height of the images appears skewed in the viewer. I think the problem is that metadata or something like that from the original tiff image is not getting copied into the individual images correctly... I will look to see if there is something from the jai-ioimage api i should be using here instead... here's the code in case you're interested...

///code start
public ArrayList getTiffPagesAsByteArrayList(byte[] argFileBytes) throws Exception{

ArrayList tiffList = new ArrayList(); //list with byte[] images of tiffs

ByteArraySeekableStream bArrSeekStream = null;
bArrSeekStream = new ByteArraySeekableStream(argFileBytes);

Iterator readers = ImageIO.getImageReadersByFormatName("tiff");
ImageReader reader = (ImageReader)readers.next();
ImageInputStream iis = ImageIO.createImageInputStream(bArrSeekStream);
reader.setInput(iis);
int noOfPages=reader.getNumImages(true);

for (int pageNbr = 0; pageNbr < noOfPages; pageNbr++){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage bufferedImage = reader.read(pageNbr);
IIOImage currentImage = new IIOImage(bufferedImage, null, null);
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
Iterator writers = ImageIO.getImageWritersByFormatName("tiff");
ImageWriter writer = (ImageWriter)writers.next();
writer.setOutput(ios);
writer.write(null, currentImage, null);
writer.dispose();
ios.close();

System.out.println("BAOS Size: " + baos.size());
tiffList.add(baos.toByteArray());
}
return tiffList;

}
///code end

jparrish
Offline
Joined: 2007-02-27
Points: 0

Ok I've figured out what's not "saving over" correctly...

when i look at the original image data (the multi-page tiff) the properties for the first page are as follows:

Bits Per Sample: 1
Compression: CCITT Group 4 FAX
Image Length: 1075 pixels (5.27 inch)
Image Width: 1728 pixels (17.63 inch)
Resolution (X): 204 DPI
Resolution (Y): 98 DPI

but the image data for the spliced out first page from the code above (which I want to be the same) is:

Bits Per Sample: 1
Compression: None
Image Length: 1075 pixels (1075 inches)
Image Width: 1728 pixels (1728 inches)
Resolution (X): 1 DPI
Resolution (Y): 1 DPI

So... I'm definitely doing something wrong.

jparrish
Offline
Joined: 2007-02-27
Points: 0

Got it... I used reader.readAll(...) and everything works now.

lcfonseca
Offline
Joined: 2007-04-06
Points: 0

An alternative would be:

public static byte[] PDFToImage(byte[] bai, String imageType) {
byte[] out = null;
try {
PdfDecoder pdf = new PdfDecoder();
pdf.openPdfArray(bai);
if (pdf.isFileViewable()) {
int dpi = 600;
pdf.setExtractionMode(32, dpi, 2);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
boolean foundWriter = false;
Iterator writerIter = ImageIO.getImageWritersByFormatName(imageType);
while (writerIter.hasNext() && !foundWriter) {
foundWriter = true;
ImageWriter writer = (ImageWriter)writerIter.next();
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
writer.prepareWriteSequence(null);
for (int i = 0; i < pdf.getPageCount(); i++) {
int pageNumber = i + 1;
BufferedImage image = pdf.getPageAsImage(pageNumber);
IIOImage iioImage = new IIOImage(image, null, null);
writer.writeToSequence(iioImage, param);
}
writer.endWriteSequence();
ios.flush();
writer.dispose();
ios.close();
out = baos.toByteArray();
}
if (!foundWriter) {
throw new RuntimeException("Error: no writer found for image type '" + imageType + "'");
}
}
pdf.closePdfFile();

BufferedImage bufferedImage = null;
while (true) {
ByteArrayInputStream bais = new ByteArrayInputStream(out);
bufferedImage = ImageIO.read(bais);
}
}
catch (Exception e) {
e.printStackTrace();
}
return out;
}

[b]Luiz Carlos Fonseca[/b]
http://www.fonsecanet.com.br