欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用C/C++二進制讀寫png文件的方法示例

 更新時間:2016年12月31日 14:10:02   作者:Datrilla  
最近在做項目的時候遇到了這個問題,所以想著總結(jié)下,方法自己和有需要的朋友,下面這篇文章主要介紹了利用C/C++二進制讀寫png文件的方法,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

二進制文件不是以ASCII代碼存放數(shù)據(jù)的,它將內(nèi)存中數(shù)據(jù)存儲形式不加轉(zhuǎn)換地傳送到磁盤文件,因此它又稱為內(nèi)存數(shù)據(jù)的映像文件。因為文件中的信息不是字符數(shù)據(jù),而是字節(jié)中的二進制形式的信息,因此它又稱為字節(jié)文件。

對二進制文件的操作也需要先打開文件,用完后要關(guān)閉文件。在打開時要用ios::binary指定為以二進制形式傳送和存儲。二進制文件除了可以作為輸入文件或輸出文件外,還可以是既能輸入又能輸出的文件。這是和ASCII文件不同的地方。

需求

最近為了弄OpenGl的紋理代碼,發(fā)現(xiàn)書上沒有圖片像素的獲取,然后就想寫個來獲取png的,結(jié)果花了一天的時間沒弄清楚為什么出現(xiàn)數(shù)據(jù)個別正確其他的卻是205

突然想起來以前弄軟工的時候雖然那個網(wǎng)站只完成了登入注冊和文本顯示,但是想在數(shù)據(jù)庫中存儲圖片的時候了解到1存圖片地址,2存圖片二進制數(shù)據(jù)。

沒錯就是二進制。然后拿起C++的翻開找啊找,弄了個ifstream iOS::binary的,成功數(shù)據(jù)正常。
時隔一天才又想起來r和rb好像是有區(qū)別的。沒錯,那些知識確實沒有記住。然后就把C的也改ok了

以下代碼只有最簡單的讀寫。地址定位啥的,個別注釋中有。如果要改動png的格式甚么的就要再了解一下png的數(shù)據(jù)結(jié)構(gòu)
如果要十進制的話就跟著注釋改一下

mm.png

實例代碼如下

#include<iostream> 
#include<fstream> 
using namespace std; 
typedef unsigned char byte; 
 /* 
class PngMsg 
{ 
private : 
 unsigned char markMsg[8]; //十進制,相當(dāng)于16進制89.50.4e.47.0d.0a.1a.0a; 
 char widthloc; 
 char heigtMsgloc; 
 char BitDepthloc;//圖像深度 
 char ColorTypeloc; 
 char CompressionMethodloc;//壓縮方法(LZ77派生算法) 
 char FilterMethodloc;//濾波器方法 
 char InterlaceMethodloc; 
public: 
 PngMsg() 
 { 
 markMsg[0] = 137;markMsg[1] = 80; markMsg[2] = 78;markMsg[3] = 71; markMsg[4] = 13;markMsg[5] = 10; markMsg[6] = 26; markMsg[7] = 10; 
 widthloc = 'a'; 
 heigtMsgloc = 'b'; 
 BitDepthloc = 'c';//圖像深度 
 ColorTypeloc = 'd'; 
 CompressionMethodloc = 'e';//壓縮方法(LZ77派生算法) 
 FilterMethodloc = 'f';//濾波器方法 
 InterlaceMethodloc = 'g'; 
 } 
 long int getMsg(char loc) 
 { 
 if (loc == 'a')return 0x10; 
 if (loc == 'b')return 0x14; 
 if (loc == 'c')return 0x15; 
 if (loc == 'd')return 0x16; 
 if (loc == 'e')return 0x17; 
 if (loc == 'f')return 0x18; 
 if (loc == 'g')return 0x19; 
 } 
 unsigned char width[4];//圖像寬度,單位像素 
 unsigned char height[4];//圖像高度,單位像素 
 unsigned char BitDepth; 
 //圖像深度 
 //索引彩色1.2.4.8;灰度1.2.4.8.16;真彩色8.16 
 unsigned char ColorType; 
 //0灰度1.2.4.8.16;2真彩色8.16;3索引彩色1.2.4.8 
 //4帶α通道數(shù)據(jù)的灰度8.16;6帶α通道數(shù)據(jù)的真彩色8.16 
 unsigned char CompressionMethod;//壓縮方法(LZ77派生算法) 
 unsigned char FilterMethod;//濾波器方法 
 unsigned char InterlaceMethod;//0:非隔行掃描;1:Adam7 
};*/ 
 
 
//=============================== 
 
 
//=============== 
//二進制讀入。書上寫ASCII碼讀取和二進制讀取,如果對象是字母,那么一致。如果是數(shù)字,那么不一致 
//書中說明【文件中數(shù)據(jù)的組織形式,分為ASCII文件(一個字節(jié)存放一個ASCII代碼)和二進制文件(內(nèi)部文件,存儲形式原樣在磁盤上存放),】 
//字符,內(nèi)存存儲=ASCII=二進制形式 
//數(shù)值數(shù)據(jù),內(nèi)存存儲和ASCII碼不同。 
//樣例內(nèi)存整數(shù)100000. 
//---------------------------------------------------------------- 
//內(nèi)存地址 0x00 01 02 03 
//內(nèi)存 00000000 00000000 00100111 00010000【大端模式下】 
//---------------------------------------------------------------- 
//二進制 00000000 00000000 00100111 00010000 
//---------------------------------------------------------------- 
//ASCII 00110001 00110000 00110000 00110000 00110000 00110000【6個字節(jié)】 
//ASCII碼對應(yīng) 1的49 0的48 0的48 0的48 0的48 0的48 
//---------------------------------------------------------------- 
 
 
 
//只有含‘寫'的不存在的文件會新建,其他會報錯 
 
//r只讀;w只寫;a尾增(附加/寫);文本ASCII 
//rb讀;wb寫;ab尾增;二進制 
//以下讀寫↓ 
//r+;w+;a+;文本ASCII 
//rb+;wb+;ab+二進制 
void writeImage(byte*imgbuf, int size) 
{ 
 //FILE* fp = fopen(shaderFile, "wb"); 
 //由于vs甚么安全性的原因,不讓使用fopen,用下面的fopen_s代替; 
 FILE*imgPo; 
 fopen_s(&imgPo, "mag.png", "wb");//這里是用二進制讀取,read-r;binary-b;因為只弄r結(jié)果出錯??!弄了后面那個的再來看這個才發(fā)現(xiàn)是這個的問題??! 
 if (imgPo == NULL)return; 
 fwrite(imgbuf, sizeof(char),size,imgPo); 
 fclose(imgPo); 
} 
void readImageFile(const char* Imgname) 
{ 
 //FILE* fp = fopen(shaderFile, "rb"); 
 //由于vs甚么安全性的原因,不讓使用fopen,用下面的fopen_s代替; 
 FILE*imgP; 
 fopen_s(&imgP,Imgname,"rb");//這里是用二進制讀取,read-r;binary-b;因為只弄r結(jié)果出錯??!弄了后面那個的再來看這個才發(fā)現(xiàn)是這個的問題??! 
 if (imgP == NULL)return ; 
 fseek(imgP, 0L, SEEK_END); 
 long size = ftell(imgP); 
 byte*imgbuf = new byte[size+ 1]; 
 fseek(imgP,0x0L,SEEK_SET);//圖片源 
 fread(imgbuf, sizeof(imgbuf[0]), size, imgP); 
 /*for (int j = 0; j < size; j++) 
 cout << (imgbuf[j] & 0xff) << ":";*/ 
 fclose(imgP); 
 
 writeImage(imgbuf, size); 
} 
 
 
//=========================================================== 
 
 
void WriteImage(byte*imgbuf, int size) 
{ 
 
 ofstream imgFo("Image2.png", ios::binary); 
 if (!imgFo) 
 { 
 cerr << "open error!" << endl; 
 abort(); 
 } 
 imgFo.write((char*)imgbuf, size);//一次性寫入后面注釋的是循環(huán)寫入 
 
 /* for (int i = 0; i < size; i++) 
 { 
 char ct = (imgbuf[i] & 0xFF); 
 imgFo.write(&ct, sizeof(char)); 
 
 //byte ct = (imgbuf[i] & 0xFF); 
 //imgFo.write((char*)&ct, sizeof(byte)); 
 //嘗試這樣輸出的是否正確. 
 //byte是我自己給名的unsigned char,出來的是對的,用char也可以。都是一個字節(jié)。 
 
 }*/ 
 imgFo.close(); 
} 
void ReadImageFile(const char* Imgname) 
{ 
 ifstream imgF(Imgname, ios::binary); 
 if (!imgF) { 
 cerr << "open error!" << endl; 
 abort(); 
 } 
 imgF.seekg(0, ios::end); 
 int size = imgF.tellg(); 
 //查了C++Library Reference才知道怎么得到size。 
 /*int pixscnt; 
 byte width[4], height[4]; 
 
 imgF.seekg(0x10); 
 imgF.read((char*)&width, sizeof(width)); 
 
 imgF.seekg(0x14); 
 imgF.read((char*)&height, sizeof(height)); 
 
 for (int i = 0; i < 4; i++) 
 cout << (width[i] & 0xff) << ":"; 
 
 for (int i = 0; i < 4; i++) 
 cout << (height[i] & 0xff) << ":"; 
 
 pixscnt = (width[2] * (0x100) + width[3])*(height[2] * (0x100) + height[3]); 
 cout << pixscnt << endl;//像素 
 cout << size << endl;*/ 
 byte*imgbuf = new byte[size]; 
 //imgF.seekg(0x10); 
 imgF.seekg(0,ios::beg); 
 imgF.read((char*)imgbuf, size);//一次性讀入,書上的不知是錯的還是舊的不可行。后面注釋的是循環(huán)讀入 
 /*for (int i = 0; i<size; i++) 
 imgF.read( (char*)&imgbuf[i], sizeof(byte));*/ 
 imgF.close(); 
 /*for (int i = 0; i < size; i++) 
 { 
 cout << hex << (imgbuf[i] & 0xff) << ":"; 
 if (i % 4 == 0)cout << endl; 
 } */ 
WriteImage(imgbuf, size); 
} 
 
int main() 
{ 
 readImageFile("mm.png");//C/C++的 
 ReadImageFile("mm.png");//C++的 
 system("pause"); 
 return 0; 
} 

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關(guān)文章

  • C語言回調(diào)函數(shù)的簡單運用

    C語言回調(diào)函數(shù)的簡單運用

    回調(diào)函數(shù)就是函數(shù)指針變量作為另外一個函數(shù)的參數(shù)而使用的一種應(yīng)用情形。本文就詳細的介紹一下C語言回調(diào)函數(shù)的簡單運用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • QT中進程的創(chuàng)建實現(xiàn)

    QT中進程的創(chuàng)建實現(xiàn)

    本文主要介紹了QT中進程的創(chuàng)建實現(xiàn),詳細介紹了創(chuàng)建進程的整個過程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-08-08
  • C++無鎖數(shù)據(jù)結(jié)構(gòu)實現(xiàn)示例詳解

    C++無鎖數(shù)據(jù)結(jié)構(gòu)實現(xiàn)示例詳解

    這篇文章主要為大家介紹了C++無鎖數(shù)據(jù)結(jié)構(gòu)實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 12個關(guān)于C語言的有趣問答

    12個關(guān)于C語言的有趣問答

    這篇文章主要介紹了12個關(guān)于C語言的有趣問答,有助于讀者加深對C語言程序設(shè)計的理解,需要的朋友可以參考下
    2014-07-07
  • C++實現(xiàn)機票預(yù)訂系統(tǒng)

    C++實現(xiàn)機票預(yù)訂系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)機票預(yù)訂系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C++11中std::async的使用詳解

    C++11中std::async的使用詳解

    這篇文章主要介紹了C++11中std::async的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 深入了解C++中基于模板的類型擦除

    深入了解C++中基于模板的類型擦除

    在C\C++中主要有三種類型擦除的方式:基于void*的類型擦除、面向?qū)ο蟮念愋筒脸突谀0宓念愋筒脸?本文主要為大家詳細介紹基于模板的類型擦除的相關(guān)知識,需要的可以了解下
    2023-12-12
  • C++ Primer 第一部分基本語言

    C++ Primer 第一部分基本語言

    這篇文章主要介紹了C++ Primer 第一部分基本語言的相關(guān)資料,需要的朋友可以參考下
    2014-02-02
  • OpenGL掃描線填充算法詳解

    OpenGL掃描線填充算法詳解

    這篇文章主要為大家詳細介紹了OpenGL實現(xiàn)掃描線填充算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 使用C語言實現(xiàn)CRC校驗的方法

    使用C語言實現(xiàn)CRC校驗的方法

    本篇文章是對使用C語言實現(xiàn)CRC校驗的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05

最新評論