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

我正在尝试读取 .png 灰度图像并将灰度值转换为 double[][]数组。我需要将它们映射到 0 到 1 之间的值。


我使用 BufferedImage,并且尝试找出使用的颜色深度,img.getColorModel().getColorSpace().getType()但返回了 TYPE_5CLR 或 TYPE_6CLR 通用组件颜色空间,这没有帮助。


目前我正在读取这样的值:


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;

            }

        }

如果 65535 是 8 位的话,它应该是 256,但我不知道什么时候。


鸿蒙传说
浏览 129回答 2
2回答

蝴蝶刀刀

我在评论中写道,您可以使用ColorModel.getNormalizedComponents(...),但由于它使用float值并且不必要的复杂,因此实现这样的转换可能会更容易:BufferedImage img;try {&nbsp; &nbsp; img = ImageIO.read(new File(path));} catch (IOException e) {&nbsp; &nbsp; 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 respectivelydouble maxValue = (1 << img.getColorModel().getComponentSize(0)) - 1;for(int x = 0; x < heightmap.length; x++) {&nbsp; &nbsp; for(int y = 0; y < heightmap[0].length; y++) {&nbsp; &nbsp; &nbsp; &nbsp; heightmap[x][y] = raster.getSample(x, y, 0) / maxValue;&nbsp; &nbsp; }}return heightmap;请注意,上面的代码仅适用于灰度图像,但这似乎是您的输入。所有颜色分量的分量大小可能相同 ( getComponentSize(0)),但 R、G 和 B(以及 A,如果有 alpha 分量)可能有单独的样本,并且代码将仅获取第一个样本 ( getSample(x, y, 0)) 。xPS:为了清楚起见,我重命名了你的变量y。x如果交换高度图中的尺寸并在内循环中循环,则很可能会获得更好的性能,而不是y由于更好的数据局部性。

互换的青春

如果您假设图像是灰度图像,则调用getRGB并除以其分量之一可能会更容易:heightmap[i][j] = (img.getRGB(j, i) & 0xff) / 255.0;
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java