• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 利用C/C++二进制读写png文件的方法示例

利用C/C++二进制读写png文件的方法示例

作者:Datrilla 字体:[增加 减小] 来源:互联网 时间:2017-05-28

Datrilla 通过本文主要向大家介绍了c++进制转换,c++十进制转二进制,c++进制转换函数,c++十进制转十六进制,c++16进制转10进制等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

前言

二进制文件不是以ASCII代码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件。因为文件中的信息不是字符数据,而是字节中的二进制形式的信息,因此它又称为字节文件。

对二进制文件的操作也需要先打开文件,用完后要关闭文件。在打开时要用ios::binary指定为以二进制形式传送和存储。二进制文件除了可以作为输入文件或输出文件外,还可以是既能输入又能输出的文件。这是和ASCII文件不同的地方。

需求

最近为了弄OpenGl的纹理代码,发现书上没有图片像素的获取,然后就想写个来获取png的,结果花了一天的时间没弄清楚为什么出现数据个别正确其他的却是205

突然想起来以前弄软工的时候虽然那个网站只完成了登入注册和文本显示,但是想在数据库中存储图片的时候了解到1存图片地址,2存图片二进制数据。

没错就是二进制。然后拿起C++的翻开找啊找,弄了个ifstream iOS::binary的,成功数据正常。
时隔一天才又想起来r和rb好像是有区别的。没错,那些知识确实没有记住。然后就把C的也改ok了

以下代码只有最简单的读写。地址定位啥的,个别注释中有。如果要改动png的格式甚么的就要再了解一下png的数据结构
如果要十进制的话就跟着注释改一下

mm.png

实例代码如下

#include<iostream> 
#include<fstream> 
using namespace std; 
typedef unsigned char byte; 
 /* 
class PngMsg 
{ 
private : 
 unsigned char markMsg[8]; //十进制,相当于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带α通道数据的灰度8.16;6带α通道数据的真彩色8.16 
 unsigned char CompressionMethod;//压缩方法(LZ77派生算法) 
 unsigned char FilterMethod;//滤波器方法 
 unsigned char InterlaceMethod;//0:非隔行扫描;1:Adam7 
};*/ 
 
 
//=============================== 
 
 
//=============== 
//二进制读入。书上写ASCII码读取和二进制读取,如果对象是字母,那么一致。如果是数字,那么不一致 
//书中说明【文件中数据的组织形式,分为ASCII文件(一个字节存放一个ASCII代码)和二进制文件(内部文件,存储形式原样在磁盘上存放),】 
//字符,内存存储=ASCII=二进制形式 
//数值数据,内存存储和ASCII码不同。 
//样例内存整数100000. 
//---------------------------------------------------------------- 
//内存地址 0x00 01 02 03 
//内存 00000000 00000000 00100111 00010000【大端模式下】 
//---------------------------------------------------------------- 
//二进制 00000000 00000000 00100111 00010000 
//---------------------------------------------------------------- 
//ASCII 00110001 00110000 00110000 00110000 00110000 00110000【6个字节】 
//ASCII码对应 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结果出错!!弄了后面那个的再来看这个才发现是这个的问题!! 
 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结果出错!!弄了后面那个的再来看这个才发现是这个的问题!! 
 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);//一次性写入后面注释的是循环写入 
 
 /* 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也可以。都是一个字节。 
 
 }*/ 
 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);//一次性读入,书上的不知是错的还是旧的不可行。后面注释的是循环读入 
 /*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; 
} 
</div>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 利用C/C++二进制读写png文件的方法示例
  • C++中输出十六进制形式的字符串
  • C++实现数字转换为十六进制字符串的方法
  • c++实现十进制转换成16进制示例
  • C++十六进制宏的用法详解

相关文章

  • 2017-05-28C++入门之基础语法学习教程
  • 2017-05-28WIN32程序获取父进程ID的方法
  • 2017-05-28c++利用stl set_difference对车辆进出区域进行判定
  • 2017-05-28VC小技巧汇总之5则实用小技巧
  • 2017-05-28c语言合并两个已排序数组的示例(c语言数组排序)
  • 2017-05-28详解C语言中getgid()函数和getegid()函数的区别
  • 2017-05-28C++求1到n中1出现的次数以及数的二进制表示中1的个数
  • 2017-05-28关于C/C++中的side effect(负效应)和sequence point(序列点)
  • 2017-05-28实现一个内存池管理的类方法
  • 2017-05-28c语言网络编程-标准步骤(改进版)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 深入浅析 C++ 调用 Python 模块
    • 深入ORACLE变量的定义与使用的详解
    • C/C++程序编译流程详解
    • C++ vector删除符合条件的元素示例分享
    • c++中new的三种用法详细解析
    • C语言 数据结构中求解迷宫问题实现方法
    • C++实现多线程查找文件实例
    • C++编程中指针的声明与基本使用讲解
    • C++实现读取特定路径下文件夹及文件名的方法
    • 使用C++进行Cocos2d-x游戏开发入门过程中的要点解析

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有