由于最近需要用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)的更多相关文章

  1. win10 服务(系统默认服务)注册表

    ---恢复内容开始--- Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services] ...

  2. HEX文件格式学习笔记

    这也是一篇学习摘抄:原文地址:http://blog.csdn.net/syrchina/article/details/7004998        为了编写一个可以按照自己的要求进行ISP的程序, ...

  3. 瘋子C++笔记

    瘋耔C++笔记 欢迎关注瘋耔新浪微博:http://weibo.com/cpjphone 参考:C++程序设计(谭浩强) 参考:http://c.biancheng.net/cpp/biancheng ...

  4. 两千行PHP学习笔记

    亲们,如约而至的PHP笔记来啦~绝对干货! 以下为我以前学PHP时做的笔记,时不时的也会添加一些基础知识点进去,有时还翻出来查查. MySQL笔记:一千行MySQL学习笔记http://www.cnb ...

  5. 【转】COM技术内幕(笔记)

    COM技术内幕(笔记) COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象 ...

  6. linux 驱动学习笔记01--Linux 内核的编译

    由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...

  7. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  8. python笔记 - day3

    python笔记 - day3 参考:http://www.cnblogs.com/wupeiqi/articles/5453708.html set特性: 1.无序 2.不重复 3.可嵌套 函数: ...

  9. mysql提权笔记

    最近小菜遇到mysql提权,总是会搞错,就记记笔记吧!以后方便用 先说手工吧! mysql<5.0,导出路径随意:5.0<=mysql<5.1,则需要导出至目标服务器的系统目录(如: ...

随机推荐

  1. QQ空间自动发广告解决方法

    最近空间好多人QQ都中了毒.每天我都有几十个好友刷空间话费.流量广告! QQ空间自动发广告的原因: 最近使用了刷赞或者其他QQ外挂软件(有些开发者或破解者会在这样的软件上留后门,请自己判断). 或者最 ...

  2. wcf系列学习5天速成——第三天 分布性事务的使用 有时间再验证下 不同库的操作

    原文地址:http://www.cnblogs.com/huangxincheng/archive/2011/11/06/2238273.html 今天是速成的第三天,再分享一下WCF中比较常用的一种 ...

  3. WCF扩展系列 - 行为扩展(Behaviors)

    原文地址:http://www.cnblogs.com/Creator/archive/2011/05/21/2052687.html 这个系列的第一部分将会重点关注WCF行为(behaviors), ...

  4. D - Flip tile

    题目大意 翻瓷砖(姑且认为题目就是这个意思吧)     农民约翰知道越聪明越快乐的牛产的牛奶越多(神马鬼理论),于是他开始安排牛进行一个智力运动在一个M*N][] = { {,},{,},{,-},{ ...

  5. java 编辑报错 非法字符: \ufeff 解决方案

    用Notepad ++ 调成utf-8 格式 bom 或无bom根据情况 新建类 把代码一句句粘进去 ok

  6. ArrayList、LinkedList、HashMap底层实现

    ArrayList 底层的实现就是一个数组(固定大小),当数组长度不够用的时候就会重新开辟一个新的数组,然后将原来的数据拷贝到新的数组内. LinkedList 底层是一个链表,是由java实现的一个 ...

  7. PHP 函数的“引用返回”概念释疑(转)

    很多时候我们会看到这样的代码(出自 CI 框架源码): 1 $class =& load_class('a','b'); 我们都知道其中的'&'是指引用,但是它的作用是什么呢?它能够解 ...

  8. 10 条提升 Android 性能的建议

    About the Speaker: Boris Farber 每个人都知道一个 App 的成功,更这个 App 的性能体验有着很密切的关系.但是如何让你的 App 拥有极致性能体验呢?在 Droid ...

  9. 【小TIP】记录各种错误【更新中】

    最好程序一遍通过,为了提高代码能力,这里将用TIP的形式记录来犯过的错误.不断更新中. *已经转移到闪存.. [150214]WA:检查是否数组开小了. [150212]WA:如果程序中有乘号,需要留 ...

  10. 使用ef code first模式,在部署后服务器端把数据库同步到最新版本的方法

    共有两种方法: 1.使用migrate.exe 具体使用方法请参考 msdn migrate使用方法,这里只做介绍 复制migrate.exe 在使用 NuGet 安装实体框架时,migrate.ex ...