CImg是个简单方便的图像库,只有一个头文件和一些plugin文件,直接用就可以了,应用非常方便;
这里以位图举例子:如:
一:
#include "CImg.h"
using namespace cimg_library;
void showbmp()
{
CImg
image.load_bmp("t.bmp");
image.display();
}
二:
当然也可以获取图像的宽高等信息,包括可以获取图像像素指针;
如:
CImg
unsigned char * pix = image.data();
三:
但是这里要注意:
1:CImg获取的图像宽度,而没有获取图像字节对齐后的宽度;
2:获取的像素指针与图像在内存中实际的排列方式不同;
我根据const CImg
unsigned char * get_CImgRgbPixBuf( CImg
{
if ( image._width == 0 || image._height == 0 )
{
return 0;
}
const unsigned long wh = (unsigned long)( image._width * image._height );
unsigned char *const buffer = new unsigned char[3*wh], *nbuffer = buffer;
unsigned char * ptr1 = 0;
unsigned char * ptr2 = 0;
unsigned char * ptr3 = 0;
ptr1 = image.data(0,0,0,0),
ptr2 = image._spectrum>1?image.data(0,0,0,1):0,
ptr3 = image._spectrum>2?image.data(0,0,0,2):0;
switch (image._spectrum)
{
case 1 :
{ // Scalar image
for (unsigned long k = 0; k
const unsigned char val = (unsigned char)*(ptr1++);
*(nbuffer++) = val;
*(nbuffer++) = val;
*(nbuffer++) = val;
}
} break;
case 2 :
{ // RG image
for (unsigned long k = 0; k
*(nbuffer++) = (unsigned char)(*(ptr1++));
*(nbuffer++) = (unsigned char)(*(ptr2++));
*(nbuffer++) = 0;
}
} break;
default :
{ // RGB image
for (unsigned long k = 0; k
*(nbuffer++) = (unsigned char)(*(ptr1++));
*(nbuffer++) = (unsigned char)(*(ptr2++));
*(nbuffer++) = (unsigned char)(*(ptr3++));
}
}
}
return buffer;
}
但是,这个函数依然有一些问题,因为没有考虑到图像的字节对齐,当然大部分情况是可以用的;
如果一定要考虑字节对齐的问题,可以参考:const CImg
简单讲解一下这个函数:
(1):这个函数默认保存到是24位位图;
const unsigned int align = (4 - (3*_width)%4)%4; //计算位图字节对齐所每行需要的字节数;
const unsigned int buf_size = (3*_width + align)*height(); //获取像素实际需要的内存大小;
......
//获取相关像素内存指针;
const T
*ptr_r = data(0,_height-1,0,0),
*ptr_g = (_spectrum>=2)?data(0,_height-1,0,1):0,
*ptr_b = (_spectrum>=3)?data(0,_height-1,0,2):0;
//循环将像素写到文件中;
default : {
cimg_forY(*this,y) { //高度;
cimg_forX(*this,x) { //每行;
std::fputc((unsigned char)(*(ptr_b++)),nfile);
std::fputc((unsigned char)(*(ptr_g++)),nfile);
std::fputc((unsigned char)(*(ptr_r++)),nfile);
}
cimg::fwrite(align_buf,align,nfile); //字节对齐;
ptr_r-=2*_width; ptr_g-=2*_width; ptr_b-=2*_width;
}
}
这个算法才是真正需要的获取内存像素的算法,所以之前的函数可以修改:
当然,如果有人说,CImg库中有可以转换为OpenCV的Iplimage 结构的函数,可以更方便获取像素指针, 但是这就必须安装OpenCV了。
四:
不过这个库还是有一些优点可以应用:
如:跨平台,图片格式转换,尤其是支持YUV的格式;
五:
通常情况下,如果没有特别需求,可以用这个图像库,不过如果是对图像处理有严格要求,用OpenCV比较好。