简体   繁体   中英

Telling apart 16 and 8 bit grascale Images in java

I am trying to read .png grayscaleimages and convert the grayvalues to a double[][] array. and i need to map them to a value between 0 and 1.

Im using a BufferedImage and I have tried to find out the colordepth using img.getColorModel().getColorSpace().getType() but that returned the TYPE_5CLR or TYPE_6CLR Generic component color space which did not help.

Currently im reading the values like this:

BufferedImage img = null;
        try {
            img = ImageIO.read(new File(path));
        } catch (IOException e) {
            return null;
        }

        double[][] heightmap= new double[img.getWidth()][img.getHeight()];
        WritableRaster raster = img.getRaster();
        for(int i=0;i<heightmap.length;i++)
        {
            for(int j=0;j<heightmap[0].length;j++)
            {
                heightmap[i][j]=((double) raster.getSample(i,j,0))/65535.0;
            }
        }

The 65535 sould be a 256 if its 8bit but i dont know when.

I wrote in the comments that you could use ColorModel.getNormalizedComponents(...) , but as it uses float values and is unnecessary complicated, it might just be easier to implement the conversion like this:

BufferedImage img;
try {
    img = ImageIO.read(new File(path));
} catch (IOException e) {
    return null;
}

double[][] heightmap = new double[img.getWidth()][img.getHeight()];

WritableRaster raster = img.getRaster();

// Component size should be 8 or 16, yielding maxValue 255 or 65535 respectively
double maxValue = (1 << img.getColorModel().getComponentSize(0)) - 1;

for(int x = 0; x < heightmap.length; x++) {
    for(int y = 0; y < heightmap[0].length; y++) {
        heightmap[x][y] = raster.getSample(x, y, 0) / maxValue;
    }
}

return heightmap;

Note that the above code will work reliable only for grayscale images, but this seems to be your input anyway. The component size is likely to be the same for all color components ( getComponentSize(0) ), but there might be separate samples for R, G and B (and A, if there's an alpha component), and the code will only get the first sample ( getSample(x, y, 0) ).

PS: I renamed your variables x and y for clarity. Most likely you will get better performance if you swap the dimensions in your height map, and loop over x in the inner loop, instead of y due to better data locality.

如果假设图像是灰度的,则调用getRGB并划分其成分之一可能会更容易:

heightmap[i][j] = (img.getRGB(j, i) & 0xff) / 255.0;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM