c++实现对图像数据的读写

c++实现对图像数据的读写

近日,由于对图像的读取底层封装特别的好奇,想试试自己的想法是否正确,结果出乎我的意料了,仅以此篇博客记录自己的拓展心得吧!!!

一般情况下,对于图像数据的读取操作跟文件读取操作基本一致,区别在于一个使用文本模式读取,另一个使用二进制模式读取,按照这个思路开始coding,发现每次读取的图像数据都和自己计算的数据总是对不上,开始迷惑了。。。。。。

先放个图说下自己的想法
在这里插入图片描述
此图为宽高数据为(350, 499),位深度为真彩色24位。
按照正常思路,整张图的像素点为(350x499),而对于真彩色24位图像来说,每个像素是占用24位,也就是24/8=3个字节,8byte=1bit,1024bit=1kb,最后计算出的结果就是350x499x24/8/1024=511.6KB
然而
在这里插入图片描述
查看图像的属性却发现实际大小只有76.4KB,一头雾水中。。。。。

愤然跑去google查找资料,最后发现,其实图像是经过JPEG进行标准压缩后的数据大小,而且还不会让图像失真,看起来效果都很好,真的是不查不知道,一查吓一跳呀!

其实想想也对,如果对于一张分辨率为1920*1080的24位图像,那他的存储数据量就达到了5.9MB啊,而且网络上那么多的高清图,那需要的存储量可想而知!

对于压缩原理可以查看[JPEG压缩原理]

最后还进行了程序demo测试的过程,通过C++编写,读取图像中的所有数据字节数

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
	ifstream f;   // 读取图像
	f.open("D:/Images/test3.jpg", ios::in | ios::binary);

	f.seekg(0, ios::end);   // 将文件指针移动到文件末尾
	int length = f.tellg();   // 返回文件指针的位置
	cout << "图像数据总字节数:" << length << endl;
	f.seekg(0, ios::beg);
	//根据图像数据长度分配内存buffer
	uchar* ImgBuffer = new uchar[length];
	f.read((char *)ImgBuffer, length * sizeof(char));

	f.close();

	ofstream out;   // 读取图像
	out.open("C:/Users/cheng/Desktop/test.jpg", ios::out | ios::binary);
	
	//从buffer中写数据到out指向的文件中
	out.write((const char*)ImgBuffer, length * sizeof(char));
	//关闭文件指针,释放buffer内存
	out.close();
	delete[]ImgBuffer;
	return 0;
}

最后的结果反而对上了图像属性字节数
在这里插入图片描述
而如果对于需要对图像做处理,那就需要考虑的每个像素值得处理,而对于jpg图像被压缩是有RGB形式转到CMYK的形式,主要是减少数据量的目的,而最后还有一个压缩数据比,就可能需要涉及自己coding解压缩的代码,这部分就需要理解底层的压缩原理了,后续会再去研究,目前还是用OpenCV中的Mat形式读写数据,OpenCV是将图像数据封装成了一个Mat数组的形式,对于图像底层的解压缩已经封装成了类,直接调用就行了,又是个站在巨人的肩膀上前进的过程,嘻嘻!

如果有童鞋真的很喜欢研究底层图像知识的话,可以骚扰我哈,给我点见解,哈哈!

用到的知识链接:http://www.360doc.com/content/17/0901/18/41193811_683881904.shtml

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要利用C语言实现PNG图像读写,可以使用libpng库。该库是一个开源的PNG图像处理库,可以实现PNG图像的读取和写入。 首先需要在C程序中引入libpng库的头文件,并连接libpng库。可以使用`#include <png.h>`来引入头文件,并在编译选项中加上`-lpng`来连接库。 接下来可以定义一个函数来读取PNG图像。函数参数可以包括PNG文件名、图像的宽度、高度和颜色类型等信息。可以使用`png_create_read_struct()`函数来创建`png_structp`类型的结构体,并使用`png_create_info_struct()`函数来创建`png_infop`类型的结构体。然后可以使用`png_init_io()`和`png_read_png()`函数来读取PNG图像数据。 要实现PNG图像的写入,也可以定义一个写入函数。函数参数可以包括PNG文件名、图像的宽度、高度和颜色类型等信息。可以使用`png_create_write_struct()`函数来创建`png_structp`类型的结构体,并使用`png_create_info_struct()`函数来创建`png_infop`类型的结构体。然后可以使用`png_init_io()`和`png_write_png()`函数来写入PNG图像数据。 在读取和写入PNG图像的过程中,还可以使用libpng提供的其他函数来进行必要的图像处理操作,例如图像格式转换、颜色空间转换等。 在编写完成读取和写入PNG图像的函数后,可以在主函数中调用这些函数来实现PNG图像读写。可以通过传递相应的参数来完成图像的读取和写入操作。 使用libpng库可以方便地实现PNG图像读写,并且具有较好的跨平台性能。在使用该库之前,可以先了解一下PNG图像的文件格式和相关知识,以便更好地应用和理解这些函数的使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值