在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
CImg为开源图像处理库,仅有一个头文件CImg.h便包含了对图像的所有处理函数,函数操作简单,编程方便,但国内使用者较少 其homepage:http://cimg.sourceforge.net/ 通常windows的CImage 或nokia的QT中的Qimage 对图片的存储均为按照每个像素的RGB循序: 例如:像素点(0,0)(0,1)(0,2) 在内存中存储顺序为R1 G1 B1 R2 G2 B2 R3 G3 B3 但是CImg中的存储却不同像素点(0,0)(0,1)(0,2) 在内存中存储顺序为R1 R2 R3 G1 G2 G3 B1 B2 B3
#include <iostream> using namespace std; #include "CImg.h" using namespace cimg_library; #include <iomanip> int main() { CImg<unsigned char> image("car.bmp"); int rgb_leng = image.width()*image.height(); unsigned char *ptr = image.data(0,0); unsigned char *ptest = new unsigned char[rgb_leng*3]; int width = image.width(); int height = image.height(); for(int i=0;i<height;i++) { for(int j=0;j<width;j++) { ptest[i*width+j]=ptr[i*width+j]; ptest[i*width+j+rgb_leng]=ptr[i*width+j+rgb_leng]; ptest[i*width+j+rgb_leng*2]=ptr[i*width+j+rgb_leng*2]; } } CImg<unsigned char> imtest(ptest,width,height,1,3); cout<<"size of iamge"<<image.size()<<endl; cout<<"size of copy iamge"<<imtest.size()<<endl; imtest.save("test.bmp"); image.display("test"); return 0; }
由于CImg库刚刚看了一天,难免会误解其中含义,以上仅代表个人观点。
总结C++中取成员函数地址的几种方法 这里, 我整理了4种C++中取成员函数地址的方法, 第1,2,4种整理于网上的方法, 第3种cdecl_cast是我自己想到的. 方法1: pointer_cast - 通过静态转换 template<typename dst_type,typename src_type> dst_type pointer_cast(src_type src) { return *static_cast<dst_type*>(static_cast<void*>(&src)); } 其实, 我并不明白这个方法为什么成功了, 而且要使用两个static_cast, 一个不行. 而且函数里面使用的&src, 方法2: union_cast - 通过联合体的共享储存机制 template<typename dst_type,typename src_type> dst_type union_cast(src_type src) { union{ src_type s; dst_type d; }u; u.s = src; return u.d; } 这种方法是最常规, 也是最好理解的一种方法了, 巧妙地利用了联合体的优点. 当然, 模板的使用恰到好处. 同时,传入参数时注意数据类型大小一致. 方法3: cdecl_cast - 通过C语言的可变参数不检测参数类型 __declspec(naked) void* __cdecl cdecl_cast(...) { __asm{ mov eax,dword ptr[esp+4] ret } } 注:在Windows上函数返回值通过eax返回, 所以只需要这么两条汇编语句就行了. 只用于32位平台, 若用于64位, 需要修改一下寄存器. #define asm_cast(var,addr) \ { \ __asm{ \ mov var,offset addr \ } \ } 注:这个方法也比较巧妙, 不过貌似在VC6上编译不过. VS2012没问题. #include <iostream> using namespace std; class A { public: void fn(){} }; int main(void) { void* p1 = pointer_cast<void*>(&A::fn); void* p2 = union_cast<void*>(&A::fn); void* p3 = cdecl_cast(&A::fn); void* p4 = 0; asm_cast(p4,A::fn); cout<<p1<<endl<<p2<<endl<<p3<<endl<<p4<<endl; return 0; }
http://www.cnblogs.com/nbsofer/ C++
类成员回调函数
CImg 数据格式 jpg
CImg为开源图像处理库,仅有一个头文件CImg.h便包含了对图像的所有处理函数,函数操作简单,编程方便,但国内使用者较少 其homepage:http://cimg.sourceforge.net/ 通常windows的CImage 或nokia的QT中的Qimage 对图片的存储均为按照每个像素的RGB循序: 例如:像素点(0,0)(0,1)(0,2) 在内存中存储顺序为R1 G1 B1 R2 G2 B2 R3 G3 B3 但是CImg中的存储却不同像素点(0,0)(0,1)(0,2) 在内存中存储顺序为R1 R2 R3 G1 G2 G3 B1 B2 B3
#include <iostream> using namespace std; #include "CImg.h" using namespace cimg_library; #include <iomanip> int main() { CImg<unsigned char> image("car.bmp"); int rgb_leng = image.width()*image.height(); unsigned char *ptr = image.data(0,0); unsigned char *ptest = new unsigned char[rgb_leng*3]; int width = image.width(); int height = image.height(); for(int i=0;i<height;i++) { for(int j=0;j<width;j++) { ptest[i*width+j]=ptr[i*width+j]; ptest[i*width+j+rgb_leng]=ptr[i*width+j+rgb_leng]; ptest[i*width+j+rgb_leng*2]=ptr[i*width+j+rgb_leng*2]; } } CImg<unsigned char> imtest(ptest,width,height,1,3); cout<<"size of iamge"<<image.size()<<endl; cout<<"size of copy iamge"<<imtest.size()<<endl; imtest.save("test.bmp"); image.display("test"); return 0; }
由于CImg库刚刚看了一天,难免会误解其中含义,以上仅代表个人观点。
这里, 我整理了4种C++中取成员函数地址的方法, 第1,2,4种整理于网上的方法, 第3种cdecl_cast是我自己想到的. 方法1: pointer_cast - 通过静态转换 template<typename dst_type,typename src_type> dst_type pointer_cast(src_type src) { return *static_cast<dst_type*>(static_cast<void*>(&src)); } 其实, 我并不明白这个方法为什么成功了, 而且要使用两个static_cast, 一个不行. 而且函数里面使用的&src, 方法2: union_cast - 通过联合体的共享储存机制 template<typename dst_type,typename src_type> dst_type union_cast(src_type src) { union{ src_type s; dst_type d; }u; u.s = src; return u.d; } 这种方法是最常规, 也是最好理解的一种方法了, 巧妙地利用了联合体的优点. 当然, 模板的使用恰到好处. 同时,传入参数时注意数据类型大小一致. 方法3: cdecl_cast - 通过C语言的可变参数不检测参数类型 __declspec(naked) void* __cdecl cdecl_cast(...) { __asm{ mov eax,dword ptr[esp+4] ret } } 注:在Windows上函数返回值通过eax返回, 所以只需要这么两条汇编语句就行了. 只用于32位平台, 若用于64位, 需要修改一下寄存器. #define asm_cast(var,addr) \ { \ __asm{ \ mov var,offset addr \ } \ } 注:这个方法也比较巧妙, 不过貌似在VC6上编译不过. VS2012没问题. #include <iostream> using namespace std; class A { public: void fn(){} }; int main(void) { void* p1 = pointer_cast<void*>(&A::fn); void* p2 = union_cast<void*>(&A::fn); void* p3 = cdecl_cast(&A::fn); void* p4 = 0; asm_cast(p4,A::fn); cout<<p1<<endl<<p2<<endl<<p3<<endl<<p4<<endl; return 0; }
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论