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, , buffer1.Length); //直接读取全部文件到buffer1中(以十进制方式)偶数为数据
fs.Close();
最后,做出来的效果。

完整版程序:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Globalization;
using System.IO; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int num;
private byte[] buffer; //解压后的一维数组
private byte[,] img_all; //解压后的二维数组 Bitmap bitmap_original; public Form1()
{
InitializeComponent();
//变量初始化
but_deal.Enabled = false;
PublicValue.Width = int.Parse(text_width.Text); //设置宽度
PublicValue.Height = int.Parse(text_heigh.Text);//设置高度
buffer =new byte [PublicValue.Width *PublicValue .Height];
img_all = new byte[PublicValue.Height, PublicValue.Width];
bitmap_original = new Bitmap(PublicValue.Width, PublicValue.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); string sPath = @"D:\解压图片";//默认在D盘创建一个文件夹,用于存放图片
if (!Directory.Exists(sPath))
{
Directory.CreateDirectory(sPath);
}
} private void button1_Click(object sender, EventArgs e)
{
but_modfi.Enabled = false;
int width = PublicValue.Width ;
int height = PublicValue.Height;
//写文件
//StreamWriter sfile = new StreamWriter("D://sufei.text");//写入到sufei.text文件中
//sfile.Write("sufeifufei\n1212\nkjhdfgjhj");
//sfile.Close();
//二进制读取
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]; //存放十六进制数据
byte[] buffer2 = new byte[count* ]; //存放解压后的数据
br.Read(buffer1, , buffer1.Length); //直接读取全部文件到buffer1中(以十进制方式)偶数为数据
fs.Close(); CreatFile();//创建文件夹(默认在D盘的“解压图片”目录下创建子文件夹) //-------------分离图片--------------------------------------------------------------------------------
if (count > (width * height / ))
{
for (int num = ; num < (count - (width * height / )); )
{ //匹配4个通信协议
if (buffer1[num] == 0x00 && buffer1[num + ] == 0xff && buffer1[num + ] == 0x01 && buffer1[num + ] == 0x00)
{
//解压
Jieya(buffer1, num + ); drawImage(); //标记图像 SavePicture(); //保存图片 num += + (width * height / );//下一个
}
else { num++; }
}
} } private void button2_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "(*.txt)|*.txt";
if(DialogResult.OK == openFileDialog1 .ShowDialog ())
{
PublicValue.OpenFileName = openFileDialog1.FileName;//得到目标文件路径
but_deal.Enabled = true; //激活处理按钮
label2.Text = PublicValue.OpenFileName; //显示文件地址
}
text_heigh.Enabled = false;
text_width.Enabled = false;
// but_modfi.Enabled = false; } private void button1_Click_1(object sender, EventArgs e)//修改图片大小
{
MessageBoxButtons messButton = MessageBoxButtons.OKCancel;
DialogResult dr = MessageBox.Show("确定要修改吗?","提醒",messButton);
if(dr == DialogResult.OK)//选择确定
{
PublicValue.Width = int.Parse(text_width.Text); //设置宽度
PublicValue.Height = int.Parse(text_heigh.Text);//设置高度
buffer = new byte[PublicValue.Width * PublicValue.Height];
img_all = new byte[PublicValue.Height, PublicValue.Width];
bitmap_original = new Bitmap(PublicValue.Width, PublicValue.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
}
} void buffer2bitmap_original()
{
for (int i = ; i < PublicValue.Height; i++)
{
for (int j = ; j < PublicValue.Width; j++)
{
Color color = Color.FromArgb(, img_all[i, j], img_all[i, j], img_all[i, j]); //相当于直接把CCD数据描绘成图的颜色
bitmap_original.SetPixel(j, i, color);
}
}
}
delegate void delegate_drawPic(PictureBox pic, Bitmap bitmap);
void drawPic(PictureBox pic, Bitmap bitmap)//第一个参数 使我们用来刷图像的控件 第二个参数时我们选择的模式mode=0 是刷原始图像 mode=1 是刷二值化图像
{
if (pic.InvokeRequired)
{
delegate_drawPic d_drawPic = new delegate_drawPic(drawPic);
pic.Invoke(d_drawPic, new object[] { pic, bitmap });
}
else
{
pic.Refresh();//图像控件刷新
pic.Image = bitmap;//显示图像
}
} void drawImage()
{
buffer2bitmap_original();
drawPic(pictureBox1, (Bitmap)bitmap_original.Clone()); //使用对象复制 可以解决两个线程同时使用一个资源的问题
} void Jieya(byte [] buffer_temp,int begin_num)
{
byte[] colour; //0.1分别对应的颜色
colour = new byte[] { , };
int dst = ;
int srclen = (PublicValue.Width * PublicValue.Height) / ;
byte tmpsrc = ;
int tempscr = begin_num;
while (srclen > )
{
srclen--;
tmpsrc = buffer_temp[tempscr];
tempscr++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
buffer[dst] = colour[(tmpsrc >> ) & 0x01]; dst++;
} //一维数组转二维数组 把原始图像赋值给新的数组用于处理
for (int height = ; height < PublicValue.Height; height++)
{
for (int weight = ; weight < PublicValue.Width; weight++)
{
img_all[height, weight] = buffer[(height * PublicValue.Width) + weight];
}
}
} void SavePicture()
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Save(PublicValue.SavePath +"\\"+ PublicValue.pic_num.ToString()+".jpg");
PublicValue.pic_num++;//进行编号
} } 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);//创建存放图片的文件夹
}
} }
}
C#笔记(Hex转JPG)的更多相关文章
- win10 服务(系统默认服务)注册表
---恢复内容开始--- Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services] ...
- HEX文件格式学习笔记
这也是一篇学习摘抄:原文地址:http://blog.csdn.net/syrchina/article/details/7004998 为了编写一个可以按照自己的要求进行ISP的程序, ...
- 瘋子C++笔记
瘋耔C++笔记 欢迎关注瘋耔新浪微博:http://weibo.com/cpjphone 参考:C++程序设计(谭浩强) 参考:http://c.biancheng.net/cpp/biancheng ...
- 两千行PHP学习笔记
亲们,如约而至的PHP笔记来啦~绝对干货! 以下为我以前学PHP时做的笔记,时不时的也会添加一些基础知识点进去,有时还翻出来查查. MySQL笔记:一千行MySQL学习笔记http://www.cnb ...
- 【转】COM技术内幕(笔记)
COM技术内幕(笔记) COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象 ...
- linux 驱动学习笔记01--Linux 内核的编译
由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...
- Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识
目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...
- python笔记 - day3
python笔记 - day3 参考:http://www.cnblogs.com/wupeiqi/articles/5453708.html set特性: 1.无序 2.不重复 3.可嵌套 函数: ...
- mysql提权笔记
最近小菜遇到mysql提权,总是会搞错,就记记笔记吧!以后方便用 先说手工吧! mysql<5.0,导出路径随意:5.0<=mysql<5.1,则需要导出至目标服务器的系统目录(如: ...
随机推荐
- 《A First Course in Probability》-chaper4-离散型随机变量-负二项分布
基于我们最为熟悉的离散型分布——二项分布,我们能够衍生出很多别的分布列,对于之前介绍过的几何分布,我们赋予其的含义是:某个事件成功的概率是p,在n次独立重复实验中恰好成功一次的概率是多少.顺着这层含义 ...
- docs
https://www.eucalyptus.com/docs/eucalyptus/3.4/index.html [Eucalyptus PDF官方下载] http://aws.amazon.co ...
- 十大纺织品、布料、面料品牌排名 - 十大品牌 - 中国品牌网 Chinapp.com
十大纺织品.布料.面料品牌排名 - 十大品牌 - 中国品牌网 Chinapp.com 十大纺织品.布料.面料品牌排名
- Ring - HDU 2296(自动机+dp)
题目大意:斯蒂文想送给他女盆友一个戒指,并且他想在戒指上刻一些字,他非常了解他女盆友喜欢什么单词,比如"love""forvevr"....并且他还把女盆友喜欢 ...
- Wow! Such Doge! - HDU 4847 (水题)
题目大意:题目描述了一大堆.....然而并没什么用,其实就是让求给的所有字符串里面有多少个"doge",不区分大小写. 代码如下: ====================== ...
- 完美逆向百度手机助手5.0底部菜单栏 - Android Tabhost 点击动画
先看看百度手机助手5.0的样子: 发现他是用一个CustomTabHost.java来实现底部TabHost点击效果的,很漂亮,点击Tab的时候文字会上跑,图片会从底部跑出来的一个小动画. 下面我用自 ...
- CDH5 安装过程
一.环境 1.1 操作系统 $ cat /etc/redhat-release CentOS release 6.5 (Final) 1.2 Java环境 $ java -version java v ...
- Android(java)学习笔记248:ContentProvider使用之虚拟短信
1.虚拟短信应用场景: 急着脱身?应付老婆(老公.男女朋友查岗)? 使用虚拟通话短信吧.您只需通过简单设置,软件就会在指定时间会模拟一个“真实”来电或短信来迷惑对方,通过“真实”的证据让对方相 ...
- iOS网络HTTP、TCP、UDP、Socket 知识总结
OSI 七层模型 我们一般使用的网络数据传输由下而上共有七层,分别为物理层.数据链路层.网络层.传输层.会话层.表示层.应用层,也被依次称为 OSI 第一层.第二层.⋯⋯. 第七层. 如下图: 各层功 ...
- vijos P1375 大整数(高精不熟的一定要做!)
/* 我尼玛这题不想说啥了 亏了高精写的熟..... 加减乘除max都写了 高精二分 */ #include<iostream> #include<cstdio> #inclu ...