BOOL CImgPng::LoadImage(LPCTSTR lpstrPath) { int dwMinSize = WideCharToMultiByte(CP_ACP,NULL,lpstrPath,-1,NULL,0,NULL,FALSE); //计算长度 char* cFileName = new char[dwMinSize]; WideCharToMultiByte(CP_OEMCP,NULL,lpstrPath,-1,cFileName,dwMinSize,NULL,FALSE); FILE* file = fopen(cFileName, "rb"); if ( NULL != file) { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_infop info_ptr = png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr)); // 这句很重要,初始化 png_init_io(png_ptr, file); // 读文件了 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0); // 得到文件的宽高色深 int m_width = png_get_image_width(png_ptr, info_ptr); int m_height = png_get_image_height(png_ptr, info_ptr); int color_type = png_get_color_type(png_ptr, info_ptr); //int pixel_depth=info_ptr->pixel_depth; //if (pixel_depth > 16 ) pixel_depth=24; //if (pixel_depth == 16 ) pixel_depth=8; //Create(info_ptr->width, info_ptr->height, pixel_depth); // 申请内存 int size = m_height * m_width * 4; pAlpha = new unsigned char[size]; int pos = 0; // row_pointers里边就是传说中的rgba数据了 png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr); // 拷贝!!注意,如果你读取的png没有A通道,就要3位3位的读。还有就是注意字节对齐的问题, // 最简单的就是别用不能被4整除的宽度就行了。读过你实在想用,就要在这里加上相关的对齐处理。 for(int i = 0; i < m_height; i++) { for(int j = 0; j < (4 * m_width); j += 4) { pAlpha[pos++] = row_pointers[i][j + 2]; // blue pAlpha[pos++] = row_pointers[i][j + 1]; // green pAlpha[pos++] = row_pointers[i][j]; // red pAlpha[pos++] = row_pointers[i][j + 3]; // alpha } } fclose(file); return TRUE; } return FALSE; } // 显示图片 BOOL CImgPng::BitBlt(HDC hdc,long nx,long ny,long width,long height,long x,long y) { if(pAlpha) { int r,g,b; int A,B,C; for(int j=height;j>0;j--) for(int i=0;i<width;i++) { b=*pAlpha++; A=b; g=*pAlpha++; B=g; r=*pAlpha++; C=r; *pAlpha++; // alpha值暂不知如何处理,可参考 //http://blog.youkuaiyun.com/cpq37/archive/2010/10/11/5933918.aspx SetPixel(hdc, i,j,RGB(C,B,A)); } } return TRUE; }