C#笔记(Hex转JPG)

    

    由于最近需要用SD卡记录摄像头拍的图像,记录的文件格式十六进制的(例如:0xf0就是对应图像中的八个像素点)需要做一个SD卡上位机来将十六进制文件转换成JPG图像格式,方便对图像的分析。

总体的思路是这样的

1.创建文件流,打开十六进制的文件

2.讲十六进制文件数据存放在一个数组中

3.读取数据,寻找事先设定的通讯协议(0x00,0xff,0x01,0x00)

4.安位解压数据,缓存在一个临时存放图片数据的数组中

5.将图像数据画在pictureBox上,编号进行保存(JPG格式)

6.放回到第三步继续执行,直到读取到文件尾部,即完成。

这里具体说说文件读取和JPG的保存

一、创建一个保存图片的文件夹

 1.在窗口初始化时,默认在D盘创建一个总文件夹

    string sPath = @"D:解压图片";//默认在D盘创建一个文件夹,用于存放图片
    if (!Directory.Exists(sPath))
    {
        Directory.CreateDirectory(sPath);
    }  

2.为了方便查看,按时间对文件夹分类

        void CreatFile()//创建子文件夹
        {
            PublicValue.SaveTime = DateTime.Now.ToString("yyyy年MM月dd日hh时mm分", DateTimeFormatInfo.InvariantInfo);
            string sPath = @"D:\解压图片\" + PublicValue.SaveTime;
            PublicValue.SavePath = @"D:\解压图片\" + PublicValue.SaveTime;
            if (!Directory.Exists(sPath))
            {
                Directory.CreateDirectory(sPath);//创建存放图片的文件夹
            }  
        }

二、文件流的使用

    //二进制读取
    FileStream fs = new FileStream(PublicValue.OpenFileName, FileMode.Open);
    BinaryReader br = new BinaryReader(fs);
    int count = (int)fs.Length;
    PublicValue.FileLength =(int)fs.Length ;//文件长度
    byte[] buffer1 = new byte[count];    //存放十六进制数据
    br.Read(buffer1, 0, buffer1.Length); //直接读取全部文件到buffer1中(以十进制方式)偶数为数据
    fs.Close();


最后,做出来的效果。

 

完整版程序:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 using System.Globalization;
 11 using System.IO;
 12 
 13 namespace WindowsFormsApplication1
 14 {
 15     public partial class Form1 : Form
 16     {
 17         private int num;
 18         private byte[] buffer;         //解压后的一维数组
 19         private byte[,] img_all;       //解压后的二维数组
 20 
 21         Bitmap bitmap_original;
 22 
 23         public Form1()
 24         {
 25             InitializeComponent();
 26             //变量初始化
 27             but_deal.Enabled = false;
 28             PublicValue.Width = int.Parse(text_width.Text); //设置宽度
 29             PublicValue.Height = int.Parse(text_heigh.Text);//设置高度
 30             buffer =new byte [PublicValue.Width *PublicValue .Height];
 31             img_all = new byte[PublicValue.Height, PublicValue.Width];
 32             bitmap_original = new Bitmap(PublicValue.Width, PublicValue.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 33 
 34             string sPath = @"D:解压图片";//默认在D盘创建一个文件夹,用于存放图片
 35             if (!Directory.Exists(sPath))
 36             {
 37                 Directory.CreateDirectory(sPath);
 38             }  
 39         }
 40 
 41         private void button1_Click(object sender, EventArgs e)
 42         {
 43             but_modfi.Enabled = false;
 44             int width = PublicValue.Width ;
 45             int height = PublicValue.Height;
 46             //写文件
 47             //StreamWriter sfile = new StreamWriter("D://sufei.text");//写入到sufei.text文件中
 48             //sfile.Write("sufeifufei
1212
kjhdfgjhj");
 49             //sfile.Close();
 50             //二进制读取
 51             FileStream fs = new FileStream(PublicValue.OpenFileName, FileMode.Open);
 52             BinaryReader br = new BinaryReader(fs);
 53 
 54             int count = (int)fs.Length;
 55             PublicValue.FileLength =(int)fs.Length ;//文件长度
 56             byte[] buffer1 = new byte[count];    //存放十六进制数据
 57             byte[] buffer2 = new byte[count* 8]; //存放解压后的数据
 58             br.Read(buffer1, 0, buffer1.Length); //直接读取全部文件到buffer1中(以十进制方式)偶数为数据
 59             fs.Close();
 60 
 61             CreatFile();//创建文件夹(默认在D盘的“解压图片”目录下创建子文件夹)
 62 
 63   //-------------分离图片--------------------------------------------------------------------------------
 64             if (count > (width * height / 8))
 65             {
 66                 for (int num = 0; num < (count - (width * height / 8)); )
 67                 {  //匹配4个通信协议
 68                     if (buffer1[num] == 0x00 && buffer1[num + 1] == 0xff && buffer1[num + 2] == 0x01 && buffer1[num + 3] == 0x00)
 69                     {
 70                         //解压
 71                         Jieya(buffer1, num + 4);
 72 
 73                         drawImage();   //标记图像
 74 
 75                         SavePicture(); //保存图片
 76 
 77                         num += 4 + (width * height / 8);//下一个
 78                     }
 79                     else { num++; }
 80                 }
 81             }
 82 
 83         }
 84 
 85         private void button2_Click(object sender, EventArgs e)
 86         {
 87             openFileDialog1.Filter = "(*.txt)|*.txt";
 88             if(DialogResult.OK == openFileDialog1 .ShowDialog ())
 89             {
 90                 PublicValue.OpenFileName = openFileDialog1.FileName;//得到目标文件路径
 91                 but_deal.Enabled = true;                            //激活处理按钮
 92                 label2.Text = PublicValue.OpenFileName;             //显示文件地址
 93             }
 94             text_heigh.Enabled = false;
 95             text_width.Enabled = false;
 96           //  but_modfi.Enabled = false;
 97          
 98         }
 99 
100         private void button1_Click_1(object sender, EventArgs e)//修改图片大小
101         {
102             MessageBoxButtons messButton = MessageBoxButtons.OKCancel;
103             DialogResult dr = MessageBox.Show("确定要修改吗?","提醒",messButton);
104             if(dr == DialogResult.OK)//选择确定
105             {
106                 PublicValue.Width = int.Parse(text_width.Text); //设置宽度
107                 PublicValue.Height = int.Parse(text_heigh.Text);//设置高度
108                 buffer = new byte[PublicValue.Width * PublicValue.Height];
109                 img_all = new byte[PublicValue.Height, PublicValue.Width];
110                 bitmap_original = new Bitmap(PublicValue.Width, PublicValue.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
111             }
112         }
113 
114         void buffer2bitmap_original()
115         {
116             for (int i = 0; i < PublicValue.Height; i++)
117             {
118                 for (int j = 0; j < PublicValue.Width; j++)
119                 {
120                     Color color = Color.FromArgb(0, img_all[i, j], img_all[i, j], img_all[i, j]);     //相当于直接把CCD数据描绘成图的颜色
121                     bitmap_original.SetPixel(j, i, color);       
122                 }     
123             }
124         }
125         delegate void delegate_drawPic(PictureBox pic, Bitmap bitmap);
126         void drawPic(PictureBox pic, Bitmap bitmap)//第一个参数 使我们用来刷图像的控件 第二个参数时我们选择的模式mode=0 是刷原始图像 mode=1 是刷二值化图像
127         {
128             if (pic.InvokeRequired)
129             {
130                 delegate_drawPic d_drawPic = new delegate_drawPic(drawPic);
131                 pic.Invoke(d_drawPic, new object[] { pic, bitmap });
132             }
133             else
134             {
135                 pic.Refresh();//图像控件刷新
136                 pic.Image = bitmap;//显示图像
137             }
138         }
139 
140         void drawImage()
141         {
142             buffer2bitmap_original();
143             drawPic(pictureBox1, (Bitmap)bitmap_original.Clone()); //使用对象复制 可以解决两个线程同时使用一个资源的问题     
144         }
145 
146         void Jieya(byte [] buffer_temp,int begin_num)
147         {
148             byte[] colour;          //0.1分别对应的颜色
149             colour = new byte[2] { 255, 0 };
150             int dst = 0;
151             int srclen = (PublicValue.Width * PublicValue.Height) / 8;
152             byte tmpsrc = 0;
153             int tempscr = begin_num;
154             while (srclen > 0)
155             {
156                 srclen--;
157                 tmpsrc = buffer_temp[tempscr];
158                 tempscr++;
159                 buffer[dst] = colour[(tmpsrc >> 7) & 0x01]; dst++;
160                 buffer[dst] = colour[(tmpsrc >> 6) & 0x01]; dst++;
161                 buffer[dst] = colour[(tmpsrc >> 5) & 0x01]; dst++;
162                 buffer[dst] = colour[(tmpsrc >> 4) & 0x01]; dst++;
163                 buffer[dst] = colour[(tmpsrc >> 3) & 0x01]; dst++;
164                 buffer[dst] = colour[(tmpsrc >> 2) & 0x01]; dst++;
165                 buffer[dst] = colour[(tmpsrc >> 1) & 0x01]; dst++;
166                 buffer[dst] = colour[(tmpsrc >> 0) & 0x01]; dst++;
167             }
168 
169             //一维数组转二维数组 把原始图像赋值给新的数组用于处理
170             for (int height = 0; height < PublicValue.Height; height++)
171             {
172                 for (int weight = 0; weight < PublicValue.Width; weight++)
173                 {
174                     img_all[height, weight] = buffer[(height * PublicValue.Width) + weight];
175                 }
176             }
177         }
178 
179         void SavePicture()
180         {
181             if (pictureBox1.Image != null)
182             {
183                 pictureBox1.Image.Save(PublicValue.SavePath +"\"+ PublicValue.pic_num.ToString()+".jpg");
184                 PublicValue.pic_num++;//进行编号
185             }
186         
187         }
188 
189         void CreatFile()//创建文件夹
190         {
191             PublicValue.SaveTime = DateTime.Now.ToString("yyyy年MM月dd日hh时mm分", DateTimeFormatInfo.InvariantInfo);
192             string sPath = @"D:\解压图片\" + PublicValue.SaveTime;
193             PublicValue.SavePath = @"D:\解压图片\" + PublicValue.SaveTime;
194             if (!Directory.Exists(sPath))
195             {
196                 Directory.CreateDirectory(sPath);//创建存放图片的文件夹
197             }  
198         }
199 
200     }
201 }
原文地址:https://www.cnblogs.com/zou107/p/3859075.html