由于最近需要用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. 动态规划——G 回文串

    G - 回文串 Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  2. 程序集引用异常 处理 app.config内控制runtime运行时应用的程序集版本指向 assemblyBinding结点 bindingRedirect

    异常: 解决方法: <?xml version="1.0" encoding="utf-8"?> <configuration> < ...

  3. HAProxy、Nginx 配置 HTTP/2 完整指南

    基于最近对HTTP/2的争论和它的优势,是时候升级底层架构了.这篇文章将会介绍如何在安装和配置HAProxy和Ngnix(使用ssl终端).为了简化流程,我建议你准备好使用Docker镜像. 如果你想 ...

  4. git 七图七模式 -- 工作流

    git 是现在最流行的代码合作工作方式,本文通过七张图来描述一下当下最流行的 git 工作模式 集中式工作流 集中式工作流 功能分支工作流 Gitflow工作流 Forking 工作流 Pull Re ...

  5. mysql数据类型介绍

    一.int.bigint.smallint 和 tinyint的区别详细介绍 bigint 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854 ...

  6. SQL中存储过程中使用事务,并且加入异常处理机制.

    --存储过程中使用事务,并且加入异常处理机制. -- ============================================= CREATE PROCEDURE [dbo].[UP_ ...

  7. Gradle 1.12 翻译——第十三章 编写构建脚本

    有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...

  8. iOS:编译错误Undefined symbols for architecture i386: _OBJC_CLASS_$_XXX&quot;, referenced from: error

    Undefined symbols for architecture i386: _OBJC_CLASS_$_XXX", referenced from: error 这个意思为无法找到名为 ...

  9. 使用 Java 配置进行 Spring bean 管理--转

    概述 众所周知,Spring 框架是控制反转 (IOC) 或依赖性注入 (DI) 模式的推动因素,而这种推动是通过基于容器的配置实现的.过去,Spring 允许开发人员使用基于 XML 的配置,通过利 ...

  10. 用crontab设置svn的定期更新任务

    本以为用crontab设置svn的定期更新任务是件非常容易的事情,实践后方才知道,其实并不那么容易.设置例行性工作如下:0 8 * * * /usr/bin/svn up /data/test第二天, ...