EDN Admin
Well-known member
<pre class="prettyprint" style=" #include <windows.h>
#include <stdio.h>
#include <gdiplus.h>
#include <wincodec.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "windowscodecs.lib")
using namespace Gdiplus;
bool WICLoad(UINT *tpWidth, UINT *tpHeight, UINT *tpSize, LPBYTE *tpBuffer);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusInput;
GdiplusStartup(&gdiplusToken, &gdiplusInput, NULL);
static TCHAR szAppName [] = TEXT ("BitBlt") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_INFORMATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("BitBlt Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
GdiplusShutdown(gdiplusToken);
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient, cxSource, cySource ;
HDC hdcClient, hdcWindow ;
int x, y ;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
{
cxSource = GetSystemMetrics (SM_CXSIZEFRAME) +
GetSystemMetrics (SM_CXSIZE) ;
cySource = GetSystemMetrics (SM_CYSIZEFRAME) +
GetSystemMetrics (SM_CYCAPTION) ;
assert(CoInitialize(NULL) == S_OK);
}
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_PAINT:
{
static Status status;
static DWORD dwStart, dwEnd;
hdcClient = BeginPaint (hwnd, &ps);
//draw with gdiplus
{
dwStart = GetTickCount();
Graphics graphics(hdcClient);
Image img(L"e:\test.jpg");
assert(img.GetWidth() && img.GetHeight());
status = graphics.DrawImage(&img, 0, 0);
assert(status == Ok);
dwEnd = GetTickCount();
printf("GdiPlus render time used = %dn", dwEnd - dwStart);
}
//draw with wic
{
dwStart = GetTickCount();
UINT width = 0;
UINT height = 0;
UINT size = 0;
LPBYTE pBuffer = NULL;
bool bRet = false;
bRet = WICLoad(&width, &height, &size, &pBuffer);
assert(bRet && width > 0 && height > 0 && size > 0 && pBuffer);
BITMAPINFO bmi = {0};
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biSizeImage = size;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
SetDIBitsToDevice(hdcClient, width + 20, 0, width, height, 0, 0, 0, height, pBuffer, &bmi, DIB_RGB_COLORS);
//HDC hdcPaint = CreateCompatibleDC(hdcClient);
//HBITMAP hbm = CreateBitmap(width, height, 1, 24, pBuffer);
//HBITMAP hbmOld = (HBITMAP)SelectObject(hdcPaint, hbm);
//assert(hbmOld != HGDI_ERROR);
//BitBlt(hdcClient, width + 20, 0, width, height, hdcPaint, 0, 0, SRCCOPY);
////HBITMAP hbm = CreateCompatibleBitmap(hdcClient, width, height);
/*SelectObject(hdcPaint, hbmOld);
DeleteObject(hbm);
DeleteDC(hdcPaint);*/
dwEnd = GetTickCount();
printf("WIC render time used = %dn", dwEnd - dwStart);
}
EndPaint (hwnd, &ps) ;
return 0 ;
}
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
bool WICLoad(UINT *tpWidth, UINT *tpHeight, UINT *tpSize, LPBYTE *tpBuffer)
{
IWICImagingFactory *pFactory = NULL;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pFrameDecode = NULL;
IWICBitmapLock *pLock = NULL;
WICPixelFormatGUID format;
LPBYTE pBuffer = NULL;
HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory,
(LPVOID*)&pFactory);
assert(hr == S_OK && pFactory);
hr = pFactory->CreateDecoderFromFilename(L"e:\test.jpg", NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder);
assert(hr == S_OK && pDecoder);
UINT count = 0;
hr = pDecoder->GetFrameCount(&count);
printf("image frame count = %dn", count);
assert(hr == S_OK &&count == 1);
hr = pDecoder->GetFrame(0, &pFrameDecode);
assert(hr == S_OK && pFrameDecode);
hr = pFrameDecode->GetPixelFormat(&format);
assert(hr == S_OK && format == GUID_WICPixelFormat24bppBGR);
UINT width = 0;
UINT height = 0;
hr = pFrameDecode->GetSize(&width, &height);
assert(hr == S_OK && width && height);
int widthBytes = (width * 24 + 7) / 8;
pBuffer = new BYTE[widthBytes * height];
hr = pFrameDecode->CopyPixels(NULL, widthBytes, widthBytes *height, (LPBYTE)pBuffer);
assert(hr == S_OK && pBuffer != NULL);
*tpWidth = width;
*tpHeight = height;
*tpSize = widthBytes * height;
*tpBuffer = pBuffer;
return true; } [/code]
the original file here,
<img alt="" src="http://social.msdn.microsoft.com/Forums/getfile/219817 <br/>
but the result out is,
<br/>
<img alt="" src="http://social.msdn.microsoft.com/Forums/getfile/219852
<br/>
I know that I could use WIC format converter to convert to 32-bit GUID_WICPixelFormat32bppBGR, but why this failed?
<br/>
<br/>
<br/>
View the full article
#include <stdio.h>
#include <gdiplus.h>
#include <wincodec.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "windowscodecs.lib")
using namespace Gdiplus;
bool WICLoad(UINT *tpWidth, UINT *tpHeight, UINT *tpSize, LPBYTE *tpBuffer);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusInput;
GdiplusStartup(&gdiplusToken, &gdiplusInput, NULL);
static TCHAR szAppName [] = TEXT ("BitBlt") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_INFORMATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("BitBlt Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
GdiplusShutdown(gdiplusToken);
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient, cxSource, cySource ;
HDC hdcClient, hdcWindow ;
int x, y ;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
{
cxSource = GetSystemMetrics (SM_CXSIZEFRAME) +
GetSystemMetrics (SM_CXSIZE) ;
cySource = GetSystemMetrics (SM_CYSIZEFRAME) +
GetSystemMetrics (SM_CYCAPTION) ;
assert(CoInitialize(NULL) == S_OK);
}
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_PAINT:
{
static Status status;
static DWORD dwStart, dwEnd;
hdcClient = BeginPaint (hwnd, &ps);
//draw with gdiplus
{
dwStart = GetTickCount();
Graphics graphics(hdcClient);
Image img(L"e:\test.jpg");
assert(img.GetWidth() && img.GetHeight());
status = graphics.DrawImage(&img, 0, 0);
assert(status == Ok);
dwEnd = GetTickCount();
printf("GdiPlus render time used = %dn", dwEnd - dwStart);
}
//draw with wic
{
dwStart = GetTickCount();
UINT width = 0;
UINT height = 0;
UINT size = 0;
LPBYTE pBuffer = NULL;
bool bRet = false;
bRet = WICLoad(&width, &height, &size, &pBuffer);
assert(bRet && width > 0 && height > 0 && size > 0 && pBuffer);
BITMAPINFO bmi = {0};
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biSizeImage = size;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
SetDIBitsToDevice(hdcClient, width + 20, 0, width, height, 0, 0, 0, height, pBuffer, &bmi, DIB_RGB_COLORS);
//HDC hdcPaint = CreateCompatibleDC(hdcClient);
//HBITMAP hbm = CreateBitmap(width, height, 1, 24, pBuffer);
//HBITMAP hbmOld = (HBITMAP)SelectObject(hdcPaint, hbm);
//assert(hbmOld != HGDI_ERROR);
//BitBlt(hdcClient, width + 20, 0, width, height, hdcPaint, 0, 0, SRCCOPY);
////HBITMAP hbm = CreateCompatibleBitmap(hdcClient, width, height);
/*SelectObject(hdcPaint, hbmOld);
DeleteObject(hbm);
DeleteDC(hdcPaint);*/
dwEnd = GetTickCount();
printf("WIC render time used = %dn", dwEnd - dwStart);
}
EndPaint (hwnd, &ps) ;
return 0 ;
}
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
bool WICLoad(UINT *tpWidth, UINT *tpHeight, UINT *tpSize, LPBYTE *tpBuffer)
{
IWICImagingFactory *pFactory = NULL;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pFrameDecode = NULL;
IWICBitmapLock *pLock = NULL;
WICPixelFormatGUID format;
LPBYTE pBuffer = NULL;
HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory,
(LPVOID*)&pFactory);
assert(hr == S_OK && pFactory);
hr = pFactory->CreateDecoderFromFilename(L"e:\test.jpg", NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder);
assert(hr == S_OK && pDecoder);
UINT count = 0;
hr = pDecoder->GetFrameCount(&count);
printf("image frame count = %dn", count);
assert(hr == S_OK &&count == 1);
hr = pDecoder->GetFrame(0, &pFrameDecode);
assert(hr == S_OK && pFrameDecode);
hr = pFrameDecode->GetPixelFormat(&format);
assert(hr == S_OK && format == GUID_WICPixelFormat24bppBGR);
UINT width = 0;
UINT height = 0;
hr = pFrameDecode->GetSize(&width, &height);
assert(hr == S_OK && width && height);
int widthBytes = (width * 24 + 7) / 8;
pBuffer = new BYTE[widthBytes * height];
hr = pFrameDecode->CopyPixels(NULL, widthBytes, widthBytes *height, (LPBYTE)pBuffer);
assert(hr == S_OK && pBuffer != NULL);
*tpWidth = width;
*tpHeight = height;
*tpSize = widthBytes * height;
*tpBuffer = pBuffer;
return true; } [/code]
the original file here,
<img alt="" src="http://social.msdn.microsoft.com/Forums/getfile/219817 <br/>
but the result out is,
<br/>
<img alt="" src="http://social.msdn.microsoft.com/Forums/getfile/219852
<br/>
I know that I could use WIC format converter to convert to 32-bit GUID_WICPixelFormat32bppBGR, but why this failed?
<br/>
<br/>
<br/>
View the full article