C#无法显示具有正确颜色映射的RAW16灰度图像
修改此链接中提供的代码: 我写道:C#无法显示具有正确颜色映射的RAW16灰度图像,c#,.net,image,picturebox,C#,.net,Image,Picturebox,修改此链接中提供的代码: 我写道: private void btnLoad\u单击(对象发送方,事件参数e) { if(System.IO.File.Exists(txtPicture.Text)) { 字节[]_data=System.IO.File.ReadAllBytes(txtPicture.Text); var _rgbData=convert16bitgrascaletorgb16(_data,160120); var _bmp=CreateBitmapFromBytes(_rg
private void btnLoad\u单击(对象发送方,事件参数e)
{
if(System.IO.File.Exists(txtPicture.Text))
{
字节[]_data=System.IO.File.ReadAllBytes(txtPicture.Text);
var _rgbData=convert16bitgrascaletorgb16(_data,160120);
var _bmp=CreateBitmapFromBytes(_rgbData,160,120);
pbFrame.Image=\u bmp;
}
}
专用静态void Convert16bitGSToRGB(UInt16颜色,输出字节红色,输出字节绿色,输出字节蓝色)
{
红色=(字节)(颜色&0x31);
绿色=(字节)((颜色&0x7E0)>>5);
蓝色=(字节)((颜色&0xF800)>>11);
}
专用静态字节[]Convert16BitGrayScaleToRgb48(字节[]inBuffer,int-width,int-height)
{
int inbytesperpix=2;
int outbytesperpoixel=6;
byte[]exputffer=新字节[宽度*高度*输出字节/像素];
int inStride=宽度*字节内像素;
int outStride=宽度*outbytesperpoixel;
//逐行浏览图像
对于(int y=0;y UInt16 color=(UInt16)(hibyte我使用GIMP找到了一个可能的提示。如果我通过这个应用程序加载原始文件(在.data
中更改扩展名和/或强制加载为原始文件),并将其设置为160x120 16bpp BigEndian
我得到了一个近乎黑色的框架(!),但如果我改变级别,压缩出现的唯一小峰值(大约12,0黑色-13,0白色)周围的范围,图像结果是正确的。改变endianism非常简单,压缩动态范围稍微少一点,但我正在努力
这一经历的第一个教训是“不要相信你的眼睛”:-
我努力的最终结果是以下三种方法:
public static void GetMinMax(byte[] data, out UInt16 min, out UInt16 max, bool big_endian = true)
{
if (big_endian)
min = max = (UInt16)((data[0] << 8) | data[1]);
else
min = max = (UInt16)((data[1] << 8) | data[0]);
for (int i = 0; i < (data.Length - 1); i += 2)
{
UInt16 _value;
if (big_endian)
_value = (UInt16)((data[i] << 8) | data[i + 1]);
else
_value = (UInt16)((data[i + 1] << 8) | data[i]);
if (_value < min)
min = _value;
if (_value > max)
max = _value;
}
}
public static void CompressRange(byte MSB, byte LSB, UInt16 min, UInt16 max, out byte color, Polarity polarity)
{
UInt16 _value = (UInt16)((MSB << 8) | LSB);
_value -= min;
switch (polarity)
{
case Polarity.BlackHot:
_value = (UInt16)((_value * 255) / (max - min));
_value = (UInt16)(255 - _value);
break;
default:
case Polarity.WhiteHot:
_value = (UInt16)((_value * 255) / (max - min));
break;
}
color = (byte)(_value & 0xff);
}
public static byte[] Convert16BitGrayScaleToRgb24(byte[] inBuffer, int width, int height, UInt16 min, UInt16 max, bool big_endian = true, Polarity polarity = Polarity.WhiteHot)
{
int inBytesPerPixel = 2;
int outBytesPerPixel = 3;
byte[] outBuffer = new byte[width * height * outBytesPerPixel];
int inStride = width * inBytesPerPixel;
int outStride = width * outBytesPerPixel;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int inIndex = (y * inStride) + (x * inBytesPerPixel);
int outIndex = (y * outStride) + (x * outBytesPerPixel);
byte hibyte;
byte lobyte;
if (big_endian)
{
hibyte = inBuffer[inIndex];
lobyte = inBuffer[inIndex + 1];
}
else
{
hibyte = inBuffer[inIndex + 1];
lobyte = inBuffer[inIndex];
}
byte gray;
CompressRange(hibyte, lobyte, min, max, out gray, polarity);
outBuffer[outIndex] = gray;
outBuffer[outIndex + 1] = gray;
outBuffer[outIndex + 2] = gray;
}
}
return outBuffer;
}
public static void GetMinMax(字节[]数据,out UInt16 min,out UInt16 max,bool big_endian=true)
{
如果(大恩迪安)
最小值=最大值=(UInt16)((数据[0]如果您将使用PixelFormat.Format48bppRgb构建的图像保存到PNG文件中,您可能会得到接近预期的结果。@Jimi not.Uhm…不太可能。保存的图片与picturebox描述的图片有所不同,但无论如何都不正确:是的,嗯,不完全支持原始16位灰度图像。T编码器可以做到这一点,将代码转换为每个通道8位。颜色空间无法正确调整。你必须自己执行标准化。顺便说一句,你发布的原始图像,用PhotoShop打开,给出了相同的精确结果(类似于过度曝光:局部分辨率损失)。它可能是针对某个特定的解码器,类似于DICOM图像格式(用于显微镜或x射线)。@Jimi nope!问题是1)endianism 2)亮度范围3)picturebox。最后一个特别重要(可能取决于图形卡)似乎是48bpp帧渲染失败的原因。:)这就是为什么我建议使用PNG编码器来执行转换。并对颜色空间进行规范化。因为没有人知道关于这幅图像的任何信息,是什么产生了它,以及使用了什么参数-同时考虑到PhotoShop产生的结果与PNG编码器相同-这个你说不出更多。