图片二进制读取
- 格式:docx
- 大小:15.64 KB
- 文档页数:8
Python读写二进制文件的方法在Python中,我们可以使用多种方法来读取和写入二进制文件。
二进制文件是一种包含非文本数据的文件,例如图像、音频或视频文件。
与文本文件不同,二进制文件以字节的形式存储数据,而不是字符。
本文将介绍Python中常用的读写二进制文件的方法,并提供示例代码以帮助你更好地理解。
1. 读取二进制文件要读取一个二进制文件,我们可以使用open()函数以二进制模式打开文件,并使用read()方法从该文件中读取数据。
下面是一个简单的示例:with open('binary_file.bin', 'rb') as file:data = file.read()在上面的代码中,我们使用open()函数打开名为binary_file.bin的二进制文件,并指定模式为'rb'(即只读模式下打开二进制文件)。
然后,我们使用read()方法从该文件中读取数据,并将其存储在变量data中。
请注意,在处理大型二进制文件时,最好使用迭代器来逐块读取数据,而不是一次性将整个文件加载到内存中。
这样可以避免内存溢出问题。
以下是一个示例:with open('large_binary_file.bin', 'rb') as file:for chunk in iter(lambda: file.read(4096), b''):# 处理每个数据块在上面的代码中,我们使用iter()函数和lambda表达式创建了一个迭代器,该迭代器会反复调用file.read(4096)方法,直到读取到空字节为止(即文件末尾)。
每次读取的数据块大小为4096字节。
2. 写入二进制文件要写入二进制文件,我们可以使用open()函数以二进制模式打开文件,并使用write()方法将数据写入该文件。
下面是一个简单的示例:data = b'\x48\x65\x6c\x6c\x6f' # 字节串数据with open('binary_file.bin', 'wb') as file:file.write(data)在上面的代码中,我们创建了一个字节串data,其中包含ASCII编码的字符串”Hello”。
如何读取二进制图片-Gridview中显示二进制图片--2上一次描述了如何读取一张图片。
现在来讲讲更为实际的使用。
在GridView中读取数据库中保存的图片信息。
我讲采用vs2005 + sqlServer2000。
访问有名的Northwind数据库中的Employee表。
其中Employee表中的photo中保存了员工的信息(image类型)。
我要做的是讲每一个员工的信息都显示出来包括他们的图片信息。
注意:1.photo中的信息是二进制的,其中有效的图片信息是从第78位开始的。
所以当你想要转换图片信息的时候应该从第78位开始。
2. 我的例子中使用的是<img>显示图片信息的。
当然你也可以使用imageWeb控件来显示。
我尝试过,如果你使用的是Image控件的话你在调试模式下会报错,但在浏览模式下就是正常的。
其原因我也不清楚。
各位可以尝试一下。
随便也告诉一下我原因。
下面是代码。
default.aspx<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs " Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w /TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head runat="server"><title>无标题页</title></head><body><form id="form1" runat="server"><div><div style="width: 100px; position: static; height: 100px; margin:auto;"><asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="Fal se" DataKeyNames="EmployeeID"DataSourceID="SqlDataSource1" BackColor="White" BorderColor="#CC CCCC" BorderStyle="None" BorderWidth="1px" CellPadding="3"><Columns><asp:BoundField DataField="LastName" HeaderText="LastName" Sort Expression="LastName"/><asp:BoundField DataField="FirstName" HeaderText="FirstName" Sor tExpression="FirstName"/><asp:TemplateField><EditItemTemplate><asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval(" EmployeeID") %>'></asp:TextBox></EditItemTemplate><ItemTemplate><img ID="Image1" src='<%# Eval("EmployeeID", "ImageHandl er.ashx?id={0}") %>' /></ItemTemplate><AlternatingItemTemplate><img ID="Image1" src='<%# Eval("EmployeeID", "ImageHandl er.ashx?id={0}") %>'/></AlternatingItemTemplate></asp:TemplateField></Columns><FooterStyle BackColor="White" ForeColor="#000066"/><RowStyle ForeColor="#000066"/><SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor=" White"/><PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign=" Left"/><HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="Whit e"/></asp:GridView></div></div><asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString=" <%$ ConnectionStrings:NorthwindConnectionString %>"SelectCommand="SELECT [LastName], [FirstName], [EmployeeID] FROM [Employees]"></asp:SqlDataSource></form></body></html>default.aspx.cs 中不需要任何代码。
C#将图⽚以⼆进制保存,读取⼆进制转换图⽚⾸先定义数据库连接字符串:String strCn = "server=.;database=DB_NAME;user=sa;pwd=XXX";读取图⽚,将图⽚转换⼆进制保存到数据库⽅法:SqlConnection cn = new SqlConnection(strCn);SqlCommand cmd = new SqlCommand("INSERT INTO ProductID_Image (ProductID,ImageData) VALUES ('1',@BLOBData)", cn);String strBLOBFilePath = @"C:/Users/Administrator/Desktop/打印模板.jpeg";FileStream fsBLOBFile = new FileStream(strBLOBFilePath, FileMode.Open, FileAccess.Read);Byte[] bytBLOBData = new Byte[fsBLOBFile.Length];fsBLOBFile.Read(bytBLOBData, 0, bytBLOBData.Length);fsBLOBFile.Close();SqlParameter prm = new SqlParameter("@BLOBData", SqlDbType.VarBinary, bytBLOBData.Length, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, bytBLOBData); cmd.Parameters.Add(prm);cn.Open();cmd.ExecuteNonQuery();cn.Close();读取数据库中⼆进制数据,转换成图⽚⽅法:SqlConnection cn = new SqlConnection(strCn);cn.Open();SqlCommand cmd = new SqlCommand("select ProductID,ImageData from ProductID_Image", cn);SqlDataAdapter da = new SqlDataAdapter(cmd);DataSet ds = new DataSet();da.Fill(ds, "ProductID_Image");int c = ds.Tables["ProductID_Image"].Rows.Count;if (c > 0){Byte[] byteBLOBData = new Byte[0];byteBLOBData = (Byte[])(ds.Tables["ProductID_Image"].Rows[c - 1]["ImageData"]);MemoryStream stmBLOBData = new MemoryStream(byteBLOBData);pictureBox1.Image = Image.FromStream(stmBLOBData);}cn.Close();。
文件二进制读取文件二进制读取指的是以二进制的方式读取文件中的内容。
与文本读取不同,文件二进制读取是以字节为单位读取文件的内容。
在计算机领域,一切都是以二进制表达的,因此对于诸如图片、音频、视频等文件,采用二进制读取会更加方便。
文件二进制读取的方式有很多,这里介绍两种常用的方式:基于文件指针的读取和基于字节数组的读取。
一、基于文件指针的读取基于文件指针的读取是指通过文件指针的移动来读取文件中的内容。
在C语言中,可以通过fread函数实现这一功能。
以读取一个jpg图片文件为例,代码如下:``` #include <stdio.h>int main(){ FILE *fp = fopen("test.jpg", "rb");//以二进制方式打开文件 unsigned char buffer[1024]; size_t count = 0;while((count = fread(buffer, 1, 1024, fp)) >0){ //每次读取1024字节 for(int i = 0; i < count; i++){ printf("%02x", buffer[i]);//以16进制形式输出 } } fclose(fp); return 0; } ```在上述代码中,首先以二进制方式打开一个名为“test.jpg”的文件,然后每次读取1024字节,将读取到的内容以16进制形式输出,最后关闭文件。
二、基于字节数组的读取基于字节数组的读取是指将文件读入一个字节数组中,具体读取方式同样可以采用fread函数。
以读取一个wav音频文件为例,代码如下:``` #include <stdio.h>int main(){ FILE *fp = fopen("test.wav", "rb");//以二进制方式打开文件 fseek(fp, 44, SEEK_SET);//跳过前44字节的头信息 unsigned char buffer[1024]; size_t count = 0;while((count = fread(buffer, 1, 1024, fp)) >0){ //每次读取1024字节 //对读取到的字节数组进行处理 } fclose(fp); return 0; } ```在上述代码中,同样以二进制方式打开一个名为“test.wav”的文件,然后跳过前44字节的头信息(wav 文件的前44字节为文件头),接着每次读取1024字节的内容,对读取到的字节数组进行处理。
CC++图像⼆进制存储与读取本系列⽂章由@yhl_leo 出品,转载请注明出处。
⽂章链接:在深度学习时,制作样本数据集时,须要产⽣和读取⼀些⼆进制图像的数据集,如,等都提供了适合C语⾔的⼆进制版本号。
以CIFAR-10的数据集为例。
官⽹上有两段关键的介绍:⼆进制版本号数据集格式为(图像⼤⼩为32x32):<1 x label><3072 x pixel>...<1 x label><3072 x pixel>In other words, the first byte is the label of the first image, which is a number in the range 0-9. The next 3072 bytes are the values of the pixels of the image. The first 1024 bytes are the red channel values, the next 1024 the green, and the final 1024 the blue. The values are stored in row-major order, so the first 32 bytes are the red channel values of the first row of the image.由此,绘制⼀个简图:依据图像⼤⼩32x32 = 1024,不难知道。
每⼀个颜⾊值存储为1 byte,因此,对于单个图像的⼆进制存储与读取(先⽆论RGB颜⾊存储顺序)。
找了⼀张32x32的彩⾊lena图像。
例如以下实现:#include <iostream>#include <stdio.h>#include <stdlib.h>#include "cv.h"#include "highgui.h"using namespace cv;using namespace std;void main(){FILE *fpw = fopen( "E:\\patch.bin", "wb" );if ( fpw == NULL ){cout << "Open error!" << endl;fclose(fpw);return;}Mat image = imread("E:\\lena32.jpg");if ( !image.data || image.channels() != 3 ){cout << "Image read failed or image channels isn't equal to 3."<< endl;return;}// write image to binary format fileint labelw = 1;int rows = image.rows;int cols = image.cols;fwrite( &labelw, sizeof(char), 1, fpw );char* dp = (char*)image.data;for ( int i=0; i<rows*cols; i++ ){fwrite( &dp[i*3], sizeof(char), 1, fpw );fwrite( &dp[i*3+1], sizeof(char), 1, fpw );fwrite( &dp[i*3+2], sizeof(char), 1, fpw );}fclose(fpw);// read image from binary format fileFILE *fpr = fopen( "E:\\patch.bin", "rb" );if ( fpr == NULL ){cout << "Open error!" << endl;fclose(fpr);return;}int labelr(0);fread( &labelr, sizeof(char), 1, fpr );cout << "label: " << labelr << endl;Mat image2( rows, cols, CV_8UC3, Scalar::all(0) );char* pData = (char*)image2.data;for ( int i=0; i<rows*cols; i++ ){fread( &pData[i*3], sizeof(char), 1, fpr );fread( &pData[i*3+1], sizeof(char), 1, fpr );fread( &pData[i*3+2], sizeof(char), 1, fpr );}fclose(fpr);imshow("1", image2);waitKey(0);}执⾏结果例如以下:再看图⽚属性:与官⽹上的⼤⼩3073⼀致,那么这么存取应该没问题。
我看过了很多关于如何在页面中显示二进制图片的方式。
都很好,可觉得其实用性不是很强。
我介绍一种方式希望实用性能强一点。
利用“一般处理程序”。
如果你实用的是vs2005你在添加新项中可以见到“一般处理程序”,它的后缀名为.ashx。
它是什么?其实它和.aspx很类似。
先问问.aspx是如何工作的?也许你知道,.aspx 能处理来自外部传入的请求,然后它还能处理这个请求并生成一个html作为结果返回。
这是典型的处理外部请求的方式。
.aspx就是专门为处理“典型”的请求而出现的。
那么如果我们现在需要一种又能处理外部请求又需要我们自定义的处理这个请求那又要怎么做呢?(也就是不实用“典型”的方式来处理)。
.ashx就能帮你做到这一点。
上面描述的东西又怎么能帮你建立你想要的东西呢?这也是我要讲述的主体。
不过还是得先看看.ashx是什么。
<%@ WebHandler Language="C#" Class="ImageHandler" %>using System;using System.Web;///<summary>///这就一个没有任何实现的一般处理程序。
///</summary>public class ImageHandler : IHttpHandler {public void ProcessRequest (HttpContext context) {context.Response.ContentType = "text/plain";context.Response.Write("Hello World");}public bool IsReusable {get {return false;}}}首先你发现<%@ WebHandler Language="C#" Class="ImageHandler" %>这句话。
jpg格式二进制解析
JPG格式是一种图像文件格式,它使用二进制编码来表示图像。
下面是JPG格式二进制解析的大致步骤:
1. JPG文件开始以特定的字节标记开始,通常为"FF D8"。
2. 在标记之后,会跟着一个序列的段落,每个段落都有自己的标记和长度。
常见的段落包括应用程序标记(APP0~APP15),
评论段(COM),开始扫描段(SOS),定义量化表(DQT)和定义
哈夫曼表(DHT)等。
3. 在应用程序标记段中,可以包含各种应用程序特定的信息,例如缩略图或元数据。
不同的应用程序标记段由不同的标记字节标识。
4. 在定义量化表和定义哈夫曼表段中,包含了图像压缩所需的量化表和哈夫曼编码表。
这些表通过数值来表示不同的颜色分量和其对应的频率信息。
5. 开始扫描段是JPG编码的核心部分,其中包含了图像的扫
描线数据。
扫描线数据由一系列的扫描线组成,每个扫描线包含一系列的像素数据。
像素数据根据之前定义的量化表和哈夫曼表进行解码,得到图像的颜色值。
6. 扫描线数据的解码可以使用不同的方法,最常见的是基于离散余弦变换(DCT)的压缩算法。
DCT将图像从空间域转换为频域,以减少数据量和消除冗余。
7. 解码后的图像颜色值可以按照特定的格式进行存储,如RGB、YCbCr等。
8. JPG文件以特定的字节标记"FF D9"结束。
以上是JPG格式二进制解析的大致步骤,具体的细节和实现方法可能会有所不同,取决于具体的JPG文件和解析程序。
图像二进制文件的操作(1/2)2009年06月10日星期三 20:57一、操作要点:∙将文件转换为二进制,再将二进制转回为文件∙将文件写入到XML,再读出来显示或者还原∙将文件写入到数据库,再读取出来显示或者还原二、学习知识点:二进制操作的类:FileStream(文件流)、BinaryReader(二进制流读取器)、BinaryWriter(二进制流写入器)三、操作步骤:(1)新建类:fileToData.csusing System.IO;/// <summary>/// fileToData 的摘要说明/// </summary>public class fileToData{public fileToData() //构造函数{ }/// <summary>/// 将传进来的文件转换成字符串(二进制)/// </summary>/// <param name=" FilePath">待处理的文件路径</param>/// <returns>String</returns>public static string FileToBinary(string FilePath){FileStream fs=new FileStream(FilePath,FileMode.Open,FileAccess.Read); //利用新传来的路径实例化一个FileStream对象int filelength = Convert.ToInt32(fs.Length);//得到对象的大小Byte[]filebyteArray=new byte[filelength];//申明一个byte数组BinaryReader br = new BinaryReader(fs);//申明一个读取二进制流的BinaryReader对象for (int i = 0; i < filelength; i++){ //循环数组大小那么多次br.Read(filebyteArray, 0, filelength); //第一个数组用0表示//将数据读取出来放在数组中}string strData = Convert.ToBase64String(filebyteArray); //8位无符号整数数组ToBase64//将数组转换为String字符传return strData;}/// <summary>/// 将传进来的二进制字符串转换为图片文件/// </summary>/// <param name="path">保存的路径</param>/// <param name="Binary">需要转换的字符串</param>public static void BinaryToFile(string path,string Binary){FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); //利用新传来的路径实例化一个FileStream对象BinaryWriter bw = new BinaryWriter(fs);//实例化一个用于写的 BinaryWriterbw.Write(Convert.FromBase64String(Binary));//将传近来的二进制字符转换为8位无符号整数数组再写进去bw.Close(); //关闭二进制流写入器fs.Close(); //关闭文件流}}(2)将文件转换为二进制及二进制转换为文件的实现(ToBinary.aspx):public partial class toBinary : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){string a=fileToData.FileToBinary(Server.MapPath("~/图片1.gif")); //将图片1转换为二进制fileToData.BinaryToFile(Server.MapPath("~/图片2.gif"), a); //将二进制转换为图片2}}(3)新建类:FileToxml.cs加入命名空间:using System.IO;using System.Text;using System.Xml;/// <summary>/// 将文件转换为二进制/// </summary>public class FileToxml{public FileToxml(){}/// <summary>/// 从上传控件中/// </summary>/// <param name="fu">被加载了文件的FileUpload上传控件</param>/// <param name="xmlPath">XML文件的存放位置</param>/// <param name="id">图片的标识ID</param>public static void FileToXML(FileUpload fu,string xmlPath,Guid id) {if (fu.HasFile){ //先判断FileUpload对象中是否包含了文件string PathString = fu.FileName;int FileLength = fu.PostedFile.ContentLength; //只得出带扩展名的文件名try{Byte[] FileByteArray = new byte[FileLenght];//申明一个大小为文件总字节大的Byte数组以存放即将产生的二进制数据Stream Streamobj = fu.PostedFile.InputStream;//创建一个能够读取被上载文件内容的Stream对象Streamobj.Read(FileByteArray, 0, FileLength);//使用Stream对象的读取方法,参数说明将数据流存放在刚才申明的数组中,从0开始读,读取的字节数为全部XmlDocument xdom = new XmlDocument();if (!File.Exists(xmlPath)){ //如果不存在XML,则创建XmlDeclaration xdec = xdom.CreateXmlDeclaration("1.0", "utf-8", null); xdom.AppendChild(xdec); //创建第一行声明XmlElement Root = xdom.CreateElement("File"); //创建根节点File xdom.AppendChild(Root);XmlElement RootElement = xdom.CreateElement("Image"); //创建父节点ImageRoot.AppendChild(RootElement);XmlElement childElementId= xdom.CreateElement("Guid"); //图片标识字段childElementId.InnerText = id.ToString();//将传近来的GUID编号作为他的串联值RootElement.AppendChild(childElementId);XmlElement childElementImgSize= xdom.CreateElement("size");//文件大小字段childElementImgSize.InnerText = FileLength.ToString(); RootElement.AppendChild(childElementImgSize);XmlElement childElementImgData = xdom.CreateElement("imgData"); //图片信息childElementImgData.InnerText= Convert.ToBase64String(FileByteArray); //这句是关键,将上面的数组转换为字符串存起来RootElement.AppendChild(childElementImgData);xdom.Save(xmlPath);//将上面创建的构架保存到指定的xml文件中}else{ //如果XML文件存在的话就直接查找对应的节点,然后增加xdom.Load(xmlPath); //加载xml文档//将指定的XML文件读取到XMLdocument对象中XmlNode root = xdom.SelectSingleNode("File");//使用xpath表达式来查找到匹配条件的节点,我们这里当然是指根节点了XmlElement RootElement = xdom.CreateElement("Image");root.AppendChild(RootElement);//创建父节点XmlElement childElementId = xdom.CreateElement("Guid");//图片标识字段childElementId.InnerText = id.ToString();//将传近来的GUID编号作为他的串联值RootElement.AppendChild(childElementId);XmlElement childElementImgSize = xdom.CreateElement("size"); childElementImgSize.InnerText = FileLenght.ToString();//文件大小字段RootElement.AppendChild(childElementImgSize);XmlElement childElementImgData = xdom.CreateElement("imgData"); childElementImgData.InnerText = Convert.ToBase64String(fu.FileBytes);RootElement.AppendChild(childElementImgData);xdom.Save(xmlPath);//将上面创建的构架保存到指定的xml文件中}}catch (Exception e){throw e;}}}}(4)将图像文件写入到XML,再读出来显示或者还原(fileToxml.aspx):public partial class fileToxml : System.Web.UI.Page{protected void Button1_Click(object sender, EventArgs e){//(上传按钮)将文件写入XML中去string xmlpath = Server.MapPath("~/App_Data/imgxml.xml");Guid gid = Guid.NewGuid();FileToxml.FileToXML(FileUpload1, xmlpath, gid);Session["gid"] = gid;}protected void Button2_Click(object sender, EventArgs e){ //根据Gid索取图片来显示ReadImgFromXml((Guid)Session["gid"]);}private void ReadImgFromXml(Guid gid){XmlDocument xdom = new XmlDocument();xdom.Load(Server.MapPath("~/App_Data/imgxml.xml"));XmlNodeList xnl = xdom.SelectSingleNode(" //Image[Guid='" +gid.ToString() + "']").ChildNodes; //找出GUID=我们传进来的ID的那一个节点的所有子节点for (int i = 0; i < xnl.Count; i++){string imgdata = xnl.Item(2).InnerText; //节点第三项imgdata Response.OutputStream.Write(Convert.FromBase64String(imgdata), 0, imgdata.Length);Response.End();//从0开始到指定的长度输出打印所有的imgdata图像信息}}protected void Button3_Click(object sender, EventArgs e){ //从XML中读出再转换为文件XmlDocument xdom = new XmlDocument();xdom.Load(Server.MapPath("~/App_Data/imgxml.xml"));XmlNodeList xnl = xdom.SelectSingleNode(" //Image[Guid='" +Session["gid"].ToString() + "']" ).ChildNodes;for (int i = 0; i < xnl.Count; i++){string strData = xnl.Item(2).InnerText;FileStream fs = new FileStream(Server.MapPath("~/图像文件名.gif"), FileMode.Create, FileAccess.Write);BinaryWriter bw = new BinaryWriter(fs);bw.Write(Convert.FromBase64String(strData));bw.Close();fs.Close();}Image1.ImageUrl = "~/图像文件名.gif";}}(5)将图像文件写入到数据库,再读取出来显示或者还原(ToData.aspx)public partial class ToData : System.Web.UI.Page{protected void Button1_Click(object sender, EventArgs e){Guid gid=Guid.NewGuid();SqlConnection conn=newSqlConnection(ConfigurationManager.ConnectionStrings["数据源名称"].ConnectionString);conn.Open();//注意:二进制不能采用字符串相加的方式写入数据库SqlCommand cmd = new SqlCommand("Insert into img(gid,fileData) values(@gid ,@fileArray) ", conn); //新建一个表img,添加字段名gid,fileData,下面添加字段类型cmd.Parameters.Add(" @gid", SqlDbType.UniqueIdentifier).Value = gid; cmd.Parameters.Add(" @fileArray", SqlDbType.Image).Value = FileUpload1.FileBytes;cmd.ExecuteNonQuery(); //执行SQL语句,返回影响行数conn.Close();Session["gid"] = gid; //保存gid的值}protected void Button2_Click(object sender, EventArgs e){SqlConnection conn = newSqlConnection(ConfigurationManager.ConnectionStrings["数据源名称"].ConnectionString);conn.Open();SqlCommand cmd = new SqlCommand("select fileDat from img where gid='"+Session["gid"].ToString()+"'" , conn);byte[] fbt=(byte[])cmd.ExecuteScalar();conn.Close();Response.OutputStream.Write(fbt, 0, fbt.Length);Response.End();}}。
open "c:\1.bmp" for binary as #1filelen=lof(1)redim ss(1 to filelen)for i=1 to filelenget #1,i,ss(i)nextclose #1这是昨天说的全部读取..你可以先从百度百科里面学习一个BMP文件的结构./view/7671.htm一、图像文件头1)1:(这里的数字代表的是"字",即两个字节,下同)图像文件头。
424Dh=’BM’,表示是Windows支持的BMP格式。
2)2-3:整个文件大小。
4690 0000,为00009046h=36934。
3)4-5:保留,必须设置为0。
4)6-7:从文件开始到位图数据之间的偏移量。
4600 0000,为00000046h=70,上面的文件头就是35字=70字节。
5)8-9:位图图信息头长度。
6)10-11:位图宽度,以像素为单位。
8000 0000,为00000080h=128。
7)12-13:位图高度,以像素为单位。
9000 0000,为00000090h=144。
8)14:位图的位面数,该值总是1。
0100,为0001h=1。
二、位图信息头9)15:每个像素的位数。
有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。
1000为0010h=16。
10)16-17:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。
RLE简单地说是采用像素数+像素值的方式进行压缩。
T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。
图中0300 0000为00000003h=3。
11)18-19:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于位图宽度×位图高度×每个像素位数。
前段时间曾经写了一篇介绍MTK的铃声管理的工具,可以把MP3,MID,WAV等声音转化为MTK可以使用的数组以供在编程中使用。
后来针对有些朋友需要把数组再转为文件的需求,写了把数组重新写回文件的文章。
但MTK的图片管理与铃声管理差异比较大。
MTK的图片管理需要把图片信息提取出来以后,经过加工才能使用。
MTK把图片数组前八个字节用来描述图片的信息,然后才是图片的内容DATA。
所以要生成图片信息,还需要写入数组头。
数组头包括图片类型,分为GIF,BMP,PNG,JPB,PBM等,每一种使用一个unsigned char的类型描述。
图片的桢数,同样使用一个字节描述。
然后是图片的大小,使用三个字节描述,最后两个字节描述图片的高和宽。
然后是图片的数据BUFFER。
代码如下。
#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <windows.h>#define GDI_IMAGE_TYPE_INVALID 0#define GDI_IMAGE_TYPE_BMP 1#define GDI_IMAGE_TYPE_BMP_SEQUENCE 2#define GDI_IMAGE_TYPE_GIF 3#define GDI_IMAGE_TYPE_DEVICE_BITMAP 4#define GDI_IMAGE_TYPE_DEVICE_BITMAP_SEQUENCE 5#define GDI_IMAGE_TYPE_BMP_FILE 6#define GDI_IMAGE_TYPE_GIF_FILE 7#define GDI_IMAGE_TYPE_WBMP_FILE 8#define GDI_IMAGE_TYPE_JPG 9#define GDI_IMAGE_TYPE_JPG_FILE 10#define GDI_IMAGE_TYPE_WBMP 11#define GDI_IMAGE_TYPE_AVI 12#define GDI_IMAGE_TYPE_AVI_FILE 13#define GDI_IMAGE_TYPE_3GP 14#define GDI_IMAGE_TYPE_3GP_FILE 15#define GDI_IMAGE_TYPE_MP4 16#define GDI_IMAGE_TYPE_MP4_FILE 17#define GDI_IMAGE_TYPE_JPG_SEQUENCE 18#define GDI_IMAGE_TYPE_PNG 19#define GDI_IMAGE_TYPE_PNG_FILE 20#define GDI_IMAGE_TYPE_PNG_SEQUENCE 21#define GDI_IMAGE_TYPE_DEVICE_BMP_FILE 22#define GDI_IMAGE_TYPE_BMP_FILE_OFFSET 23#define GDI_IMAGE_TYPE_GIF_FILE_OFFSET 24#define GDI_IMAGE_TYPE_M3D 25#define GDI_IMAGE_TYPE_M3D_FILE 26#define GDI_IMAGE_TYPE_SVG 27#define GDI_IMAGE_TYPE_SVG_FILE 28#define GDI_IMAGE_TYPE_SWFLASH 29#define GDI_IMAGE_TYPE_SWFLASH_FILE 30#define GDI_IMAGE_TYPE_JPG_FILE_OFFSET 31#define GDI_IMAGE_TYPE_PNG_FILE_OFFSET 32#define GDI_IMAGE_TYPE_DEVICE_BMP_FILE_OFFSET 33#define GDI_IMAGE_TYPE_WBMP_FILE_OFFSET 34#define GDI_IMAGE_TYPE_M3D_FILE_OFFSET 35#define GDI_IMAGE_TYPE_SVG_FILE_OFFSET 36#define GDI_IMAGE_TYPE_SWFLASH_FILE_OFFSET 37#define GDI_IMAGE_TYPE_AVATAR 38#define GDI_IMAGE_TYPE_ABM_FILE_OFFSET 39#define GDI_IMAGE_TYPE_ABM 40#define GDI_IMAGE_TYPE_ABM_SEQUENCE 41#define GDI_IMAGE_TYPE_ABM_FILE 42#define GDI_IMAGE_TYPE_MPG 43#define GDI_IMAGE_TYPE_MPG_FILE 44#define GDI_IMAGE_TYPE_MPG_FILE_OFFSET 45#define GDI_IMAGE_TYPE_3G2 46#define GDI_IMAGE_TYPE_3G2_FILE 47#define GDI_IMAGE_TYPE_3G2_FILE_OFFSET 48#define GDI_IMAGE_TYPE_VIS 49#define GDI_IMAGE_TYPE_VIS_FILE 50#define GDI_IMAGE_TYPE_BMP_MEM 51#define GDI_IMAGE_TYPE_SUM 52char * getfilename(char * filename){char strResult[128]={0}; //保存结果char *temp, *ret;int i;temp = filename;int nStrLen = strlen(filename); //原始字符串长度for(i = nStrLen - 1; i >= 0; i--) //倒查,每个字符和反斜杠对比{if (filename[i] == '\\') //如果当前字符是反斜杠{break;}}if(i == 0){ret = temp;}else{ret = (temp+i+1);}return (ret);}char * getfileextname(char * filename){char strResult[128]={0}; //保存结果char *temp, *ret;int i;temp = filename;int nStrLen = strlen(filename); //原始字符串长度for(i = nStrLen - 1; i >= 0; i--) //倒查,每个字符和反斜杠对比{if (filename[i] == '.') //如果当前字符是反斜杠{ret = (temp+i+1);break;}}return (ret);}BOOL isImageFile(char * filename){if (memcmp(filename, "null", 4)==0){return false;}if ((memcmp(getfileextname(filename), "png", 3) == 0) || (memcmp(getfileextname(filename), "gif", 3) == 0) || (memcmp(getfileextname(filename), "pbm", 3) == 0)|| (memcmp(getfileextname(filename), "jpg", 3) == 0)||(memcmp(getfileextname(filename), "bmp", 3) == 0)){return true;}else{return false;}}char * modifystr(char * str){char *tmp;int i;tmp = str;for (i = 0; i < (int)strlen(str)-1; i++){if ((str[i] == ' ') || (str[i] == '.')){*(tmp+i) = '_';}}return tmp;}unsigned char * imagewritehead(unsigned char * head, unsigned char img_type, int img_size, int frame_number, int width, int height) {head[0] = img_type;head[1] = frame_number; //frame_number;head[2] = img_size&0xff;head[3] = (img_size>>8)&0xff;head[4] = (img_size>>16)&0xff;head[5] = height&0xff;head[6] = ((height>>8)&0x0f)|((width&0x0f)<<4);head[7] = (width>>4);return head;}//BMPBITMAPFILEHEADER file_head;BITMAPINFO fileinfo;int image2res(char * image, char * res){long infileLen; //文件长度int n=0,num=1; //n 字节计数器, NUM换行指示unsigned char c, c_in; //C_in文件字节,C转化FILE *fh_in;FILE *fh_out;char com[256]={0};char filename[256]={0};unsigned char filehead[8];char fileheads[50];assert((image != NULL) && (res != NULL));fh_in = fopen(image,"rb");if (NULL==fh_in){printf("open read file error!!");return 1;}fseek(fh_in,0,SEEK_END);infileLen=ftell(fh_in);fseek(fh_in,0,SEEK_SET);/*读取BMP文件头*/if (sizeof(file_head)!=fread(&file_head,1,sizeof(file_head),fh_in)) {printf("read bmp file error!!");fclose(fh_in);return 1;}/*读取BMP文件信息*/if (sizeof(fileinfo)!=fread(&fileinfo,1,sizeof(fileinfo),fh_in)){printf("read bmp file error!!");fclose(fh_in);return 1;}fseek(fh_in,0,SEEK_SET);imagewritehead(filehead, 1, infileLen, 1, fileinfo.bmiHeader.biWidth, fileinfo.bmiHeader.biHeight);fh_out=fopen(res,"ab");if (NULL==fh_out){printf("open write file error!!");return 1;}/*写入注释*/memcpy(filename, getfilename(image), 256);sprintf(com, "/*The image is : %s, size is: %ld byte */", filename, infileLen);fputs(com, fh_out);putc(0x0d,fh_out);putc('\n',fh_out);memset(com, 0x00, 128);modifystr(filename);sprintf(com, "__align(4) const U8 %s[] = {", filename);fputs(com, fh_out);putc(0x0d,fh_out);putc('\n',fh_out);//生成数组的前八个字节sprintf(fileheads, "0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X,0x%02X, 0x%02X,\0",filehead[0],filehead[1],filehead[2],filehead[3],filehead[4],filehead[ 5],filehead[6],filehead[7]);//把文件信息写入前八个字节fputs(fileheads, fh_out);putc(0x0d,fh_out);putc('\n',fh_out);/*写入数据*/while (n<(infileLen)){putc('0',fh_out);putc('x',fh_out);c_in=getc(fh_in);c=c_in;c=(c>>4)&0x0f; //获取高四个BIT的内容if (c<0x0a){c+=0x30; //把符号转成数字else{c+=0x37; //转成a到f}putc(c,fh_out);c=c_in&0x0f; //获取低四个BIT内容if (c<0x0a){c+=0x30;}else{c+=0x37;}putc(c,fh_out);putc(',',fh_out);putc(' ',fh_out);n++;if (num++ % 16 ==0){putc(0x0d,fh_out);putc('\n',fh_out);}}putc('}',fh_out);putc(0x0d,fh_out);putc('\n',fh_out);//memset(com, 0x00, 128);//sprintf(com, "{%s, sizeof(%s), %d}", filename, filename, getfilevalue(getfileextname(image)));//fputs(com, fh_out);putc(0x0d,fh_out);putc('\n',fh_out);fclose(fh_in);fclose(fh_out);return 0;}int main(int argc, char* argv[])WIN32_FIND_DATA fd;HANDLE hd;hd=::FindFirstFile((LPCTSTR)"*.*",&fd); //开始查找if(hd==INVALID_HANDLE_VALUE){if (!isImageFile(fd.cFileName))printf("没有找到文件");return 0;}if(!(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) {if (isImageFile(fd.cFileName)){image2res(fd.cFileName, (char *)"custimgdatahw.h"); }}while(FindNextFile(hd,&fd)) //继续查找{if(!(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) {if (isImageFile(fd.cFileName)){image2res(fd.cFileName, (char *)"custimgdatahw.h"); }}}FindClose(hd);//关闭查找return 0;}本文来自。