Скачал от сюда http://sourceforge.net/projects/libpng/files/ LibPNG но совершенно не понимаю как добиться адекватного отображения альфа прозрачности | Код | void PNGAPI user_error_fn(png_structp png, png_const_charp sz) { } void PNGAPI user_warning_fn(png_structp png, png_const_charp sz) { } HBITMAP LoadBitmapPNG(char *szFile) { HBITMAP hbm = NULL;
bool retVal = false; int size = 0; // check the header first FILE *fp = fopen(szFile, "rb"); if (!fp) return false; BYTE header[8]; fread(header, 1, 8, fp); fseek(fp, 0, SEEK_END); size = ftell(fp); fclose(fp); if (png_sig_cmp(header, 0, 8)) return false; // now allocate stuff png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, user_error_fn, user_warning_fn); if (!png_ptr) return false; png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return false; }
png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; }
fp = fopen(szFile, "rb"); if (fp) { png_init_io(png_ptr, fp);
// should really use png_set_rows() to allocate space first, rather than doubling up
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_BGR | PNG_TRANSFORM_PACKING, NULL);
fclose(fp);
png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr);//new png_bytep[info_ptr->height];
// now for a tonne of ugly DIB setup crap
int width = info_ptr->width; int height = info_ptr->height; int bpp = info_ptr->channels * 8; int memWidth = (width * (bpp >> 3) + 3) & ~3;
LPBITMAPINFO lpbi = (LPBITMAPINFO) new char[sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))];
// create a greyscale palette for (int a_i = 0; a_i < 256; a_i++) { lpbi->bmiColors[a_i].rgbRed = (BYTE)a_i; lpbi->bmiColors[a_i].rgbGreen = (BYTE)a_i; lpbi->bmiColors[a_i].rgbBlue = (BYTE)a_i; lpbi->bmiColors[a_i].rgbReserved = 0; }
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbi->bmiHeader.biWidth = width; lpbi->bmiHeader.biHeight = -height; // must be negative for top down lpbi->bmiHeader.biPlanes = 1; lpbi->bmiHeader.biBitCount = bpp; lpbi->bmiHeader.biCompression = BI_RGB; lpbi->bmiHeader.biSizeImage = memWidth * height; lpbi->bmiHeader.biXPelsPerMeter = 0; lpbi->bmiHeader.biYPelsPerMeter = 0; lpbi->bmiHeader.biClrUsed = 0; lpbi->bmiHeader.biClrImportant = 0;
BYTE * pixelData; hbm = CreateDIBSection(NULL, lpbi, DIB_RGB_COLORS, (void **)&pixelData, NULL, 0 ); if (hbm && pixelData) { // now copy the rows for (int i = 0; i < height; i++) memcpy(pixelData + memWidth * i, row_pointers[i], width * info_ptr->channels); }
delete (char*) lpbi; }
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
return hbm; }
void SetSplashImage(HWND hwndSplash, HBITMAP hbmpSplash) { // get the size of the bitmap BITMAP bm; GetObject(hbmpSplash, sizeof(bm), &bm); SIZE sizeSplash = { bm.bmWidth, bm.bmHeight }; // get the primary monitor's info POINT ptZero = { 0 }; HMONITOR hmonPrimary = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY); MONITORINFO monitorinfo = { 0 }; monitorinfo.cbSize = sizeof(monitorinfo); GetMonitorInfo(hmonPrimary, &monitorinfo); // center the splash screen in the middle of the primary work area const RECT & rcWork = monitorinfo.rcWork; POINT ptOrigin; ptOrigin.x = rcWork.left + (rcWork.right - rcWork.left - sizeSplash.cx) / 2; ptOrigin.y = rcWork.top + (rcWork.bottom - rcWork.top - sizeSplash.cy) / 2; // create a memory DC holding the splash bitmap HDC hdcScreen = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdcScreen); HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcMem, hbmpSplash); // use the source image's alpha channel for blending BLENDFUNCTION blend = { 0 }; blend.BlendOp = AC_SRC_OVER; blend.SourceConstantAlpha = 255; blend.AlphaFormat = AC_SRC_ALPHA; // paint the window (in the right location) with the alpha-blended bitmap UpdateLayeredWindow(hwndSplash, hdcScreen, &ptOrigin, &sizeSplash, hdcMem, &ptZero, RGB(0, 0, 0), &blend, ULW_ALPHA); // delete temporary objects SelectObject(hdcMem, hbmpOld); DeleteDC(hdcMem); ReleaseDC(NULL, hdcScreen); }
|
|