最近在跟長時間Suspend回來後,按Send/End鍵Sometimes不能用的BUG. 本人認為不關應用什麼事, 雖然PhoneCanvas部分是我做的. 但
驅動那邊人就是要我來跟, 唉,沒辦法,寫了一個hook Send/End鍵的應用來跟,看COM有沒有列印相關消息,來判斷按鍵消息是否傳到了上層,
是以就有了些時間來搞一下PNG顯示. MSFT有IImage來顯示圖檔, 但如果直接Draw出來的話, 每次都要花大量的時間來解碼,是以就感覺會慢. Google了一下,有人說把PNG轉成PARGB,然後再畫出來,會快很多. 是以就自己試了一下這個方法, 感覺還不錯哦。
先用IImage接口把PNG轉成PARGB Bitmap并存起來, 然後再根據需要将圖檔畫出來就OK了...
#include <imaging.h>
#include <initguid.h>
#include <imgguids.h>
#pragma comment(lib,"Imaging.lib")
#pragma comment(lib,"uuid.lib")
typedef struct _tagPARGBImageInfo
{
UINT Width; // the Width of the image
UINT Height; // the Height of the image
HBITMAP hBitMap; // the Handle of the PARGB image
}PARGBImageInfo;
PARGBImageInfo g_PARGBImageInfo = {0};
// load png and create a PARGB Bitmap
void Load_PNG2PARGBBitmap()
{
IImagingFactory *pImgFactory = NULL;
IImage *pImage = NULL;
// Normally you would only call CoInitialize/CoUninitialize
// once per thread. This sample calls CoInitialize in this
// draw function simply to illustrate that you must call
// CoInitialize before calling CoCreateInstance.
CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Create the imaging factory.
if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IImagingFactory,
(void **)&pImgFactory)))
{
INT nTimer = GetTickCount();
// Load the image from the png file and get the image info
if (SUCCEEDED(pImgFactory->CreateImageFromFile(TEXT("//My Documents//test.png"), &pImage)))
{
ImageInfo imgInfo = {0};
// Get the image info
if (SUCCEEDED(pImage->GetImageInfo(&imgInfo)))
{
BitmapData bmpData = {0};
IBitmapImage *pBitmapImage = NULL;
RECT rc = {0, 0, imgInfo.Width, imgInfo.Height};
// Save the image Width and Height
g_PARGBImageInfo.Width = imgInfo.Width;
g_PARGBImageInfo.Height = imgInfo.Height;
// Create a bitmap image from an IImage object
if (SUCCEEDED(pImgFactory->CreateBitmapFromImage(pImage, 0, 0, PIXFMT_32BPP_PARGB, InterpolationHintDefault, &pBitmapImage)))
{
// Lock an area of a bitmap image object and access bitmap data in the specified pixel format
pBitmapImage->LockBits(&rc, ImageLockModeRead, PIXFMT_32BPP_PARGB, &bmpData);
// Create a bitmap with the specified width, height, and bit depth. And Save the Bitmap handle
g_PARGBImageInfo.hBitMap = CreateBitmap(imgInfo.Width, imgInfo.Height, 1, GetPixelFormatSize(imgInfo.PixelFormat), bmpData.Scan0);
ASSERT(g_PARGBImageInfo.hBitMap);
// Unlock an area of the bitmap image object locked by a previous call to the IBitmapImage::LockBits call
pBitmapImage->UnlockBits(&bmpData);
pBitmapImage->Release();
}
}
pImage->Release();
}
DEBUGMSG(1, (TEXT("...Load_PNG2PARGBBitmap...Timer = %d....../r/n"), GetTickCount()-nTimer));
pImgFactory->Release();
}
// Close the OLE Component Object Model (COM) library, freeing any resources that it maintains.
CoUninitialize();
}
// draw PARGB Bitmap
void DrawImage_PARGB(HDC hdc)
{
INT nTimer = GetTickCount();
// draw image
HDC hdcMem = ::CreateCompatibleDC(hdc);
HGDIOBJ hGdiObjOld = ::SelectObject(hdcMem, g_PARGBImageInfo.hBitMap);
// AlphaBlend the hdcTemp data to the hdc
BLENDFUNCTION blendFunction = {0};
blendFunction.AlphaFormat = AC_SRC_ALPHA;
blendFunction.BlendFlags = 0;
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.SourceConstantAlpha = 255; //0-255 (透明度設定, 可以用于圖檔的漸變顯示 (^v^; )
// Alpha Blend to hdcTemp
AlphaBlend(hdc, 0, 0, g_PARGBImageInfo.Width, g_PARGBImageInfo.Height,
hdcMem, 0, 0, g_PARGBImageInfo.Width, g_PARGBImageInfo.Height, blendFunction);
::SelectObject(hdcMem, hGdiObjOld);
if (hdcMem)
{
DeleteDC(hdcMem);
hdcMem = NULL;
}
DEBUGMSG(1, (TEXT("...DrawImage_PARGB...Draw PNG Timer = %d....../r/n"), GetTickCount()-nTimer));
}
測試DEBUG模式下512X512(186KB) PNG對比:
用直接Draw出來:
...DrawImage_ImageDraw.....Draw PNG Timer = 124......
// Draw the image.
INT nTimer = GetTickCount();
pImage->Draw(hdc, &rc, NULL);
DEBUGMSG(1, (TEXT("...DrawImage_ImageDraw.....Draw PNG Timer = %d....../r/n"), GetTickCount()-nTimer));
先轉換,然後畫出來:
...Load_PNG2PARGBBitmap...Timer = 121......
...DrawImage_PARGB...Draw PNG Timer = 15......
// Load and Draw the image.
Load_PNG2PARGBBitmap();
DrawImage_PARGB(GetDC(hWnd));
Merry Christmas :&)
Jacky Lee
2009-12-25