'Grayscale PNG writing from BufferedImage using PNGJ - hightest-level approach

I just want to, at first, use PNGJ at the highest possible level to write a grayscale PNG with bit-depth 8. I am working from a BufferedImage. Here's a snippet of the code used:

BufferedImage scaledBI;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
...
ImageInfo imi = new ImageInfo(scaledBI.getWidth(), scaledBI.getHeight(), 8, false, true, false);
PngWriter pngw = new PngWriter(baos, imi);
pngw.setCompLevel(3);
DataBufferByte db =((DataBufferByte) scaledBI.getRaster().getDataBuffer());
byte[] dbbuf = db.getData();
ImageLineByte line = new ImageLineByte(imi, dbbuf);

for (int row = 0; row < imi.rows; row++) {
    pngw.writeRow(line, row);
}
pngw.end();
return baos.toByteArray();

The original image is in j2k and is a palm print scan. The PNG looks similar to the background of the j2k with some vertical gray lines of different shades. I tried the same buffered image data with ImageIO:

ImageIO.write(scaledBI, "png", baos);

and com.pngencoder.PngEncoder:

new PngEncoder().withBufferedImage(scaledBI).withCompressionLevel(3).toStream(baos);

which both render the image properly. The long term aim is to improve on the speed offered by ImageIO and PngEncoder (which doesn't support grayscale). I am stuck on just trying to run PNGJ with all default settings. I looked at the snippets in PNGJ Wiki Snippets and the test code but I couldn't find a simple example with grayscale without scanline or chunk manipulation. Looking at the PNGJ code it seems like we are properly going through block deflation row after row. What am I missing here?



Solution 1:[1]

my problem sprung from my misunderstanding of what ImageLineByte stores, although as the name suggests it deals with a line, not the entire image data. I got confused by the fact that it references the image info. So my output was fine once I used ImageByteLine for each line:

for (int row = 0, offset = 0; row < imi.rows; row++) {
  int newOffset = offset + imi.cols;
  byte[] lineBuffer = Arrays.copyOfRange(dbbuf, offset, newOffset);
  ImageLineByte line = new ImageLineByte(imi, lineBuffer);
  pngw.writeRow(line, row);
  offset = newOffset;
}

Sorry for the trouble.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fabrice Camous