How to create HBITMAP from WICBitmapSource
来源:互联网 发布:常见的木马编程技术 16 编辑:程序博客网 时间:2024/05/16 14:17
// Creates a 32-bit DIB from the specified WIC bitmap.
HBITMAP CreateHBITMAP(IWICBitmapSource * ipBitmap)
{
// initialize return value
HBITMAP hbmp = NULL;
// get image attributes and check for valid image
UINT width = 0;
UINT height = 0;
if (FAILED(ipBitmap->GetSize(&width, &height)) || width == 0 || height == 0)
goto Return;
// prepare structure giving bitmap information (negative height indicates a top-down DIB)
BITMAPINFO bminfo;
ZeroMemory(&bminfo, sizeof(bminfo));
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bminfo.bmiHeader.biWidth = width;
bminfo.bmiHeader.biHeight = -((LONG) height);
bminfo.bmiHeader.biPlanes = 1;
bminfo.bmiHeader.biBitCount = 32;
bminfo.bmiHeader.biCompression = BI_RGB;
// create a DIB section that can hold the image
void * pvImageBits = NULL;
HDC hdcScreen = GetDC(NULL);
hbmp = CreateDIBSection(hdcScreen, &bminfo, DIB_RGB_COLORS, &pvImageBits, NULL, 0);
ReleaseDC(NULL, hdcScreen);
if (hbmp == NULL)
goto Return;
// extract the image into the HBITMAP
const UINT cbStride = width * 4;
const UINT cbImage = cbStride * height;
if (FAILED(ipBitmap->CopyPixels(NULL, cbStride, cbImage, static_cast<BYTE *>(pvImageBits))))
{
// couldn't extract image; delete HBITMAP
DeleteObject(hbmp);
hbmp = NULL;
}
Return:
return hbmp;
}
Use CreateDIBSection to allocate a DIB that can be written to directly. By setting up a BITMAPINFO structure with the right values, the DIB will be of the same format as the 32bpp BGRA image loaded by WIC, and the pixels can be copied directly from the WIC bitmap to the DIB.
Or use SetDIBits to set DIB to a HBITMAP like the following:
HBITMAP GetImageFromBitmapSource(IWICBitmapSource* image)
{
// Maps a WIC image source to an aready cached HBITMAP.
// If not already cached, it creates the HBITMAP from WIC.
if (image == NULL)
return NULL;
// Convert the WIC image to a ready-to-use device-dependent GDI bitmap.
// so that we don't recreate a new bitmap every draw call.
//
// * Note this expects BGRA pixel format.
UINT width, height;
if (FAILED(image->GetSize(&width, &height)))
return NULL;
UINT stride = width * 4;
UINT pixelBufferSize = stride * height;
std::vector<UINT8> pixelBuffer(pixelBufferSize);
if (FAILED(image->CopyPixels(NULL, stride, pixelBufferSize, &pixelBuffer[0])))
return NULL;
// Initialize bitmap information.
BITMAPINFO bmi = {
sizeof(BITMAPINFOHEADER), // biSize
width, // biWidth
-int(height), // biHeight
1, // biPlanes
32, // biBitCount
BI_RGB, // biCompression
pixelBufferSize, // biSizeImage
1, // biXPelsPerMeter
1, // biYPelsPerMeter
0, // biClrUsed
0, // biClrImportant
0 // RGB QUAD
};
HDC hdc = GetDC(NULL);
HDC hMemoryDC = CreateCompatibleDC(hdc);
HBITMAP bitmap = CreateCompatibleBitmap(hdc, width, height);
if (bitmap == NULL)
return NULL;
SetDIBits(
hMemoryDC,
bitmap,
0, // starting line
height, // total scanlines
&pixelBuffer[0],
&bmi,
DIB_RGB_COLORS
);
return bitmap;
}
Then create BITMAPINFO struct for bitmap, and save the HBITMAP to bitmap file:
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
// Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
return NULL;
// Convert the color format to a count of bits.
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)
if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));
// There is no RGBQUAD array for the 24-bit-per-pixel format.
else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));
// Initialize the fields in the BITMAPINFO structure.
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
// If the bitmap is not compressed, set the BI_RGB flag.
pbmi->bmiHeader.biCompression = BI_RGB;
// Compute the number of bytes in the array of color
// indices and store the result in biSizeImage.
// For Windows NT, the width must be DWORD aligned unless
// the bitmap is RLE compressed. This example shows this.
// For Windows 95/98/Me, the width must be WORD aligned unless the
// bitmap is RLE compressed.
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
// Set biClrImportant to 0, indicating that all of the
// device colors are important.
pbmi->bmiHeader.biClrImportant = 0;
return pbmi;
}
void CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi,
HBITMAP hBMP, HDC hDC)
{
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp;
pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits)
return;
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
return;
}
// Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE)
return;
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD);
// Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL) )
{
return;
}
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, NULL))
return;
// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
return;
// Close the .BMP file.
if (!CloseHandle(hf))
return;
// Free memory.
GlobalFree((HGLOBAL)lpBits);
}
- How to create HBITMAP from WICBitmapSource
- How to create a server from scratch
- How to create Magento invoice from order
- How to create ArrayList (ArrayList from array (T[]) in Java
- How To Create manually an ASM Instance From Scratch
- How to create WSDL SourceCode from a webservice.
- How to create an EMF model from a Java application ?
- How to create XML validator from XML schema?
- How to create caffe.deploy from train.prototxt
- How to create singleton
- How to create alarm
- How to create WCF
- How to Create Tables
- How to load FIBITMAP and convert it to HBITMAP
- Animating with Blender: How to Create Short Animations from Start to Finish
- How to Create a Range From 1 to 10 in SQL
- Siebel HOW TO: How to create Products?
- How to create unit test folder separated from src folder in eclipse project?
- 《大话设计模式》之 装饰模式 Delphi实现
- 在C#使用JScript的技巧
- VC,状态栏上对话框大小与实际像素关系
- VS2010负载测试,防止您的程序成为“烂尾楼”
- j2ME打包后,运行JAD文件,报com.sun.kvem.midletsuite.InvalidJadException: Reason = 22
- How to create HBITMAP from WICBitmapSource
- Basic concepts about camera
- 冒泡排序
- 使用 bjam 构建 crypto++
- HttpClient的认识
- 迭代器失效 、删除两个相邻元素
- 小时候难忘的一件事
- rman测试系列一
- “中国保险IT应用高峰论坛2009”现场实录