由于最近需要用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. C++ static(施工中)

    static 变量 头文件中的static会在引用该头文件的cpp中分别生成副本 //H.h #ifndef _H_H_ #define _H_H_ ; #endif //Ex_2.c #includ ...

  2. SRM 397(1-250pt)

    题意:对于一个长度n的数列(由1-n组成,n <= 8),每次操作可以reverse k个连续的数.问最少多少次操作可以将该数列转化成递增的数列. 解法:就是一个BFS.只是由于最开始学习BFS ...

  3. oracle的nvl函数的使用解析

    Oracle的Nvl函数 nvl( ) 函数 从两个表达式返回一个非null 值. 语法 NVL(eExpression1, eExpression2) 参数 eExpression1, eExpre ...

  4. SVN安装图解

    SVN服务器搭建和使用(一) Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上 ...

  5. 如何提高Lucene构建索引的速度

    如何提高Lucene构建索引的速度 hans(汉斯) 2013-01-27 10:12 对于Lucene>=2.3:IndexWriter可以自行根据内存使用来释放缓存.调用writer.set ...

  6. Jquery AJAX 调用WebService服务

    对Jquery+JSON+WebService的一点认识 文章不错:http://www.cnblogs.com/tyb1222/archive/2011/10/13/2210549.html Jqu ...

  7. 由阿里巴巴一道笔试题看Java静态代码块、静态函数、动态代码块、构造函数等的执行顺序

    一.阿里巴巴笔试题: public class Test { public static int k = 0; public static Test t1 = new Test("t1&qu ...

  8. MsSql省市联动表

    drop table area CREATE TABLE [dbo].[Area] ( , ) NOT NULL , ) COLLATE Chinese_PRC_CI_AS NOT NULL , ) ...

  9. Android中Application全局方法(变量)的调用

    Application和Actovotu,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息.通常我们是 ...

  10. android自定义listview实现圆角

    在项目中我们会经常遇到这种圆角效果,因为直角的看起来确实不那么雅观,可能大家会想到用图片实现,试想上中下要分别做三张图片,这样既会是自己的项目增大也会增加内存使用量,所以使用shape来实现不失为一种 ...