java - 在java中区分16位和8位grascale图像
问题描述
我正在尝试读取 .png grayscaleimages 并将灰度值转换为
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,但我不知道什么时候。
解决方案
我在评论中写道,您可以使用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;
请注意,上述代码仅适用于灰度图像,但这似乎是您的输入。所有颜色分量的分量大小可能相同getComponentSize(0)
(getSample(x, y, 0)
.
PS:为了清楚起见x
,我重命名了您的变量y
。如果您交换高度图中的尺寸并x
在内部循环中循环,而不是y
由于更好的数据局部性,您很可能会获得更好的性能。
推荐阅读
- c++ - 使用单独的线程执行 C++ 中的命令列表
- gdb - 缓冲区溢出堆栈金丝雀位置
- javascript - 需要帮助格式化 Phonegap/Cordova 应用程序的小时、分钟和秒。在 Android 上工作,但不是在 ios 上工作 .. 让 Nan
- python - 如何查看 Dash 应用中的活跃用户数?
- javascript - 没有重复和固定长度的数组的排列
- javascript - 有没有办法隐藏您最小化浏览器或从某个窗口失去焦点的事实
- mysql - 查找从上一个日历月开始增加流式传输时间的用户
- java - Intellij IDE 在实体中显示错误突出显示
- android - 如何获取 android OAuth 的令牌?
- eclipse - Eclipse 2020-03 上 SCALA-Ide 插件的性能调优