简体   繁体   English

在Java中区分16位和8位grascale图像

[英]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. 我正在尝试读取.png grayscaleimages并将grayvalues转换为double[][]数组。 and i need to map them to a value between 0 and 1. 我需要将它们映射到0到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. 我正在使用BufferedImage,并且尝试使用img.getColorModel().getColorSpace().getType()找出颜色深度,但返回的TYPE_5CLR或TYPE_6CLR通用组件颜色空间无济于事。

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. 65535如果是8位,则为256,但我不知道何时。

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: 我在评论中写道,您可以使用ColorModel.getNormalizedComponents(...) ,但是由于它使用float值并且不必要地复杂,因此实现这样的转换可能会更容易:

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) ). 所有颜色分量的分量大小可能都相同( getComponentSize(0) ),但是R,G和B(如果有alpha分量,则可能有A)是单独的样本,并且代码只会得到第一个样本( getSample(x, y, 0) )。

PS: I renamed your variables x and y for clarity. PS:为清楚起见,我将变量xy重命名。 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. 如果交换高度图中的尺寸,并在内部循环中通过x而不是y循环,则很有可能会获得更好的性能,这是因为数据位置更好。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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