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,则需要导出至目标服务器的系统目录(如: ...
随机推荐
- 动态规划——G 回文串
G - 回文串 Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- 程序集引用异常 处理 app.config内控制runtime运行时应用的程序集版本指向 assemblyBinding结点 bindingRedirect
异常: 解决方法: <?xml version="1.0" encoding="utf-8"?> <configuration> < ...
- HAProxy、Nginx 配置 HTTP/2 完整指南
基于最近对HTTP/2的争论和它的优势,是时候升级底层架构了.这篇文章将会介绍如何在安装和配置HAProxy和Ngnix(使用ssl终端).为了简化流程,我建议你准备好使用Docker镜像. 如果你想 ...
- git 七图七模式 -- 工作流
git 是现在最流行的代码合作工作方式,本文通过七张图来描述一下当下最流行的 git 工作模式 集中式工作流 集中式工作流 功能分支工作流 Gitflow工作流 Forking 工作流 Pull Re ...
- mysql数据类型介绍
一.int.bigint.smallint 和 tinyint的区别详细介绍 bigint 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854 ...
- SQL中存储过程中使用事务,并且加入异常处理机制.
--存储过程中使用事务,并且加入异常处理机制. -- ============================================= CREATE PROCEDURE [dbo].[UP_ ...
- Gradle 1.12 翻译——第十三章 编写构建脚本
有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...
- iOS:编译错误Undefined symbols for architecture i386: _OBJC_CLASS_$_XXX", referenced from: error
Undefined symbols for architecture i386: _OBJC_CLASS_$_XXX", referenced from: error 这个意思为无法找到名为 ...
- 使用 Java 配置进行 Spring bean 管理--转
概述 众所周知,Spring 框架是控制反转 (IOC) 或依赖性注入 (DI) 模式的推动因素,而这种推动是通过基于容器的配置实现的.过去,Spring 允许开发人员使用基于 XML 的配置,通过利 ...
- 用crontab设置svn的定期更新任务
本以为用crontab设置svn的定期更新任务是件非常容易的事情,实践后方才知道,其实并不那么容易.设置例行性工作如下:0 8 * * * /usr/bin/svn up /data/test第二天, ...