• 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 }
  • 相关阅读:
    cygwin 下配置ssh
    使用MarsEdit写博客
    bash no job control in this shell
    安装devtoolset-2:因由安装gcc 4.8而引起
    AFNetworking Property with 'retain (or strong)' attribute must be of object type
    从xib 创建 collectionViewCell
    CocoaPods 安装
    个人理解的 Https 通信流程
    cellforrowatindexpath 不执行 的原因
    do{} while(0) 的意义和用法
  • 原文地址:https://www.cnblogs.com/zou107/p/3859075.html
Copyright © 2020-2023  润新知