C#如何将【记录了图片信息的二进制文件】转为正常可打开的图片文件?

Dust_Evc 2021-04-14 09:43:28
一个原始二进制文件,一个正常图片文件,利用C#语言,前者该如何转为后者?

数据源链接(免费下载):https://download.csdn.net/download/Dust_Evc/16675902

在尝试了网上介绍的方法后还是失败(主体如下代码),故恳请各位大佬帮助!


FileStream ReadStream = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read);
byte[] data = new byte[ReadStream.Length];
ReadStream.Read(data, 0, data.Length);

// 将读取的数据转为图片
MemoryStream bs = new MemoryStream(data);
pictureBox1.Image = Image.FromStream(bs);
或者:pictureBox1.Image = new Bitmap(bs);

ReadStream.Close();
WriteStream.Close();
...全文
457 15 打赏 收藏 举报
写回复
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dust_Evc 2021-04-17
引用 6 楼 xuzuning 的回复:
tzbh...... 你这是 CAD 的加密数据文件
请问大佬是怎么知道该文件实际格式的呢? 我今天看这个帖子:https://blog.csdn.net/huddheaven/article/details/37807379,尝试用PS打开,结果成功了,直接将test.raw拖进PS,默认设置即可正确显示出图片,之后就可以导出为正常位图格式。 那问题是该如何在C#里实现呢?
  • 打赏
  • 举报
回复
Dust_Evc 2021-04-17
[quote=引用 5 楼 desperaso 的回复:]接上面 您好!您的ReadTifData、ReadRawData方法都出错了呢~ ReadTifData正常的位图格式(tif、jpg、png)也打不开,报错如下图
  • 打赏
  • 举报
回复
xuzuning 2021-04-17
不过就是把每个字节当作亮度信号而已
  • 打赏
  • 举报
回复
xuzuning 2021-04-17
既然 ps 也只认为是 二进制映射,那个 1210,1240 也真能想得出
var ar = File.ReadAllBytes("原始二进制文件.raw");
            int h = 1240;
            int w = 1210;
            bm = new Bitmap(w, h);
            int i = 0;
            for (var x = 0; x < w; x++)
            {
                for (var y = 0; y < h; y++)
                {
                    var n = ar[i++];
                    bm.SetPixel(x, y, Color.FromArgb(n, n, n));

                }

            }
            bm.Save("1,jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
  • 打赏
  • 举报
回复
desperaso 2021-04-17
引用 8 楼 Dust_Evc 的回复:
[quote=引用 5 楼 desperaso 的回复:]接上面 您好!您的ReadTifData、ReadRawData方法都出错了呢~ ReadTifData正常的位图格式(tif、jpg、png)也打不开,报错如下图
那要不试一试这个吧 链接: https://pan.baidu.com/s/1FhjbmXcm4MkJUKaXM3oh1A 提取码: ubga 在google上找找,很多的
  • 打赏
  • 举报
回复
Dust_Evc 2021-04-17
作为论坛新人,在下可用分目前只有两位数,不好意思未能给予各位太多积分
  • 打赏
  • 举报
回复
desperaso 2021-04-17
我跟raw较了个什么劲。。。。
  • 打赏
  • 举报
回复
Dust_Evc 2021-04-17
引用 10 楼 desperaso 的回复:
那要不试一试这个吧 链接: https://pan.baidu.com/s/1FhjbmXcm4MkJUKaXM3oh1A 提取码: ubga 在google上找找,很多的
好的,非常感谢大佬帮助!
  • 打赏
  • 举报
回复
Dust_Evc 2021-04-17
引用 11 楼 xuzuning 的回复:
既然 ps 也只认为是 二进制映射,那个 1210,1240 也真能想得出
非常感谢大佬的帮助!但发现您的代码把行列弄混了,导致转换后的图行列对调了。对您的代码略微改动后,成功转换成正常位图格式。
        private void button2_Click(object sender, EventArgs e)
        {
            var ar = File.ReadAllBytes("输入文件.raw");
            int w = 1240;
            int h = 1210;
            Bitmap bitm = new Bitmap(w, h);
            
            int i = 0;
            for (var y = 0; y < h; y++)
            {
                for (var x = 0; x < w; x++)
                {
                    var n = ar[i++];
                    bitm.SetPixel(x, y, Color.FromArgb(n, n, n));
                }
            }
            pictureBox1.Image = bitm;
            bitm.Save(@"输出文件.png", System.Drawing.Imaging.ImageFormat.Png);
  • 打赏
  • 举报
回复
xuzuning 2021-04-15
tzbh...... 你这是 CAD 的加密数据文件
  • 打赏
  • 举报
回复
desperaso 2021-04-15
接上面

public static Bitmap TifToBmp(int[][] TifData, int maxv, int minv)
{
int Width = TifData.Length;
int Height = TifData[1].Length;
Bitmap TifMap = new Bitmap(Width, Height);
int diff = maxv - minv;

Rectangle rect = new Rectangle(0, 0, TifMap.Width, TifMap.Height);
BitmapData srcBmpData = TifMap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
IntPtr srcPtr = srcBmpData.Scan0;
int scanWidth = srcBmpData.Width * 3;
int src_bytes = scanWidth * TifMap.Height;
byte[] srcRGBValues = new byte[src_bytes];
Marshal.Copy(srcPtr, srcRGBValues, 0, src_bytes);
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
int colr = (int)((double)(TifData[i][j] - minv) * 256 / diff);
if (colr > 255)
colr = 255;
if (colr < 0)
colr = 0;
srcRGBValues[j * scanWidth + i * 3 + 2] = (byte)colr;
srcRGBValues[j * scanWidth + i * 3 + 1] = (byte)colr;
srcRGBValues[j * scanWidth + i * 3 + 0] = (byte)colr;
}
}

Marshal.Copy(srcRGBValues, 0, srcPtr, src_bytes);
TifMap.UnlockBits(srcBmpData);
return TifMap;
}



调用
public int Maxv =65535;
public int Minv = 0;
TifData = ReadTIF.ReadRawData(open.FileName, ImgWidth宽, ImgHeight高, out Maxv,out Minv);
Pic_Show.BackgroundImage = ImageProcess.TifToBmp(TifData, Maxv, Minv);
  • 打赏
  • 举报
回复
desperaso 2021-04-15
首先你那个raw文件,用raw查看器打不开,谁知道是啥格式。
好吧,就算是raw格式的吧,用这个

public class ReadTIF
{
public static int[][] ReadTifData(string FileName)
{
Bitmap bmp = Bitmap.FromFile(FileName) as Bitmap ;
FileStream stream = new FileStream(FileName, FileMode.Open, FileAccess.Read);
BinaryReader TIFReader = new BinaryReader(stream);

int Width = bmp.Width ;
int Height = bmp.Height ;


int colr = 0;
byte[] pixelData = new byte[2];
int[][] Imdata = new int[Width][];
for (int i = 0; i < Width; i++)
{
Imdata[i] = new int[Height];
}
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
pixelData = TIFReader.ReadBytes(2);
colr = (pixelData[1] * 256 + pixelData[0]);
Imdata[i][j] = colr;

}
}
stream.Close();
return Imdata;
}


public static int[][] ReadRawData(string FileName,int Width,int Height)
{
int[][] result = new int[Width][];
for(int i=0;i<Width;i++)
{
result[i] = new int[Height];
}
ushort[] pix16;

BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open));
ushort pixShort;

long iTotalSize = br.BaseStream.Length;
int iNumberOfPixels = (int)(iTotalSize / 2);
pix16 = new ushort[iNumberOfPixels];
for (int i = 0; i < iNumberOfPixels; ++i)
{
pixShort = (ushort)(br.ReadUInt16());
pix16[i] = pixShort;
}
for(int i=0;i<Width;i++)
{
for(int j=0;j<Height;j++)
{
result[i][j]= (int)(pix16[i *Height + j]);
}
}
return result;
}



public static int[][] ReadRawData(string FileName, int Width, int Height,out int MaxValue,out int MinValue)
{
MaxValue = 0;
MinValue = 65535;
int[][] result = new int[Width][];
for (int i = 0; i < Width; i++)
{
result[i] = new int[Height];
}
ushort[] pix16;

BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open));
ushort pixShort;

long iTotalSize = br.BaseStream.Length;
int iNumberOfPixels = (int)(iTotalSize / 2);
pix16 = new ushort[iNumberOfPixels];
for (int i = 0; i < iNumberOfPixels; ++i)
{
pixShort = (ushort)(br.ReadUInt16());
pix16[i] = pixShort;
}
for (int i = 0; i < Width; i++)
{
for (int j = 0; j < Height; j++)
{
result[i][j] = (int)(pix16[i * Height + j]);
if (MaxValue < result[i][j])
MaxValue = result[i][j];
if (MinValue > result[i][j])
MinValue = result[i][j];
}

}
return result;
}

}
  • 打赏
  • 举报
回复
Dust_Evc 2021-04-14
引用 1 楼 兔子党-顾问 的回复:
无法下载,提示需要下载码,你放百度网盘吧
您好!已贴出百度网盘链接
  • 打赏
  • 举报
回复
Dust_Evc 2021-04-14
链接:https://pan.baidu.com/s/1Ae5oAo4t7nyOIAEGZbBXnQ 提取码:9958 好的,第一次在论坛提问,感谢大神帮助!
  • 打赏
  • 举报
回复
兔子-顾问 2021-04-14
无法下载,提示需要下载码,你放百度网盘吧
  • 打赏
  • 举报
回复
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2021-04-14 09:43
社区公告

让您成为最强悍的C#开发者