1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
bool
ImageUtil :: CreateGdiplusBmpFromHBITMAP_Alpha ( HBITMAP
hBmp , Gdiplus :: Bitmap ** bmp ) { BITMAP bitmap ; GetObject ( hBmp , sizeof
( BITMAP ), & bitmap ); if
( bitmap . bmBitsPixel != 32) { return
false ; } Gdiplus :: Bitmap * pWrapBitmap = Gdiplus :: Bitmap :: FromHBITMAP ( hBmp , NULL ); if
( pWrapBitmap ) { Gdiplus :: BitmapData bitmapData ; Gdiplus :: Rect rcImage (0, 0, pWrapBitmap -> GetWidth (), pWrapBitmap -> GetHeight ()); pWrapBitmap -> LockBits (& rcImage , Gdiplus :: ImageLockModeRead , pWrapBitmap -> GetPixelFormat (), & bitmapData ); * bmp = new
Gdiplus :: Bitmap ( bitmapData . Width , bitmapData . Height , bitmapData . Stride , PixelFormat32bppARGB , ( BYTE
*) bitmapData . Scan0 ); pWrapBitmap -> UnlockBits (& bitmapData ); delete
pWrapBitmap ; return
true ; } return
false ; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 |
Gdiplus :: Bitmap * ImageUtil :: CreateBitmapFromHBITMAP ( IN HBITMAP
hBitmap ) { BITMAP bmp = { 0 }; if
( 0 == GetObject ( hBitmap , sizeof
( BITMAP ), ( LPVOID
)& bmp ) ) { return
FALSE ; } // Although we can get bitmap data address by bmp.bmBits member of BITMAP // which is got by GetObject function sometime, // we can determine the bitmap data in the HBITMAP is arranged bottom-up // or top-down, so we should always use GetDIBits to get bitmap data. BYTE
* piexlsSrc = NULL ; LONG
cbSize = bmp . bmWidthBytes * bmp . bmHeight ; piexlsSrc = new
BYTE [ cbSize ]; BITMAPINFO bmpInfo = { 0 }; // We should initialize the first six members of BITMAPINFOHEADER structure. // A bottom-up DIB is specified by setting the height to a positive number, // while a top-down DIB is specified by setting the height to a negative number. bmpInfo . bmiHeader . biSize = sizeof
( BITMAPINFOHEADER ); bmpInfo . bmiHeader . biWidth = bmp . bmWidth ; bmpInfo . bmiHeader . biHeight = bmp . bmHeight ; // 正数,说明数据从下到上,如未负数,则从上到下 bmpInfo . bmiHeader . biPlanes = bmp . bmPlanes ; bmpInfo . bmiHeader . biBitCount = bmp . bmBitsPixel ; bmpInfo . bmiHeader . biCompression = BI_RGB ; HDC
hdcScreen = CreateDC ( L "DISPLAY"
, NULL , NULL , NULL ); LONG
cbCopied = GetDIBits ( hdcScreen , hBitmap , 0, bmp . bmHeight , piexlsSrc , & bmpInfo , DIB_RGB_COLORS ); DeleteDC ( hdcScreen ); if
( 0 == cbCopied ) { delete
[] piexlsSrc ; return
FALSE ; } // Create an GDI+ Bitmap has the same dimensions with hbitmap Bitmap * pBitmap = new
Bitmap ( bmp . bmWidth , bmp . bmHeight , PixelFormat32bppPARGB ); // Access to the Gdiplus::Bitmap‘s pixel data BitmapData bitmapData ; Rect rect (0, 0, bmp . bmWidth , bmp . bmHeight ); if
( Ok != pBitmap -> LockBits (& rect , ImageLockModeRead , PixelFormat32bppPARGB , & bitmapData ) ) { delete
( pBitmap ); return
NULL ; } BYTE
* pixelsDest = ( BYTE
*) bitmapData . Scan0 ; int
nLinesize = bmp . bmWidth * sizeof
( UINT
); int
nHeight = bmp . bmHeight ; // Copy pixel data from HBITMAP by bottom-up. for
( int
y = 0; y < nHeight ; y ++ ) { // 从下到上复制数据,因为前面设置高度时是正数。 memcpy_s ( ( pixelsDest + y * nLinesize ), nLinesize , ( piexlsSrc + ( nHeight - y - 1) * nLinesize ), nLinesize ); } // Copy the data in temporary buffer to pBitmap if
( Ok != pBitmap -> UnlockBits (& bitmapData ) ) { delete
pBitmap ; } delete
[] piexlsSrc ; return
pBitmap ; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 |
bool
ImageUtil::SavePng( HBITMAP
hBmp, LPCTSTR
lpszFilePath ) { DIBSECTION dibsection; bool
m_bIsDIBSection; int
m_nWidth, m_nHeight, m_nBPP, m_nPitch; LPVOID
m_pBits; int
nBytes = ::GetObject( hBmp, sizeof ( DIBSECTION ), &dibsection ); // 1. I find no way to save nonDIB from ATL::CImage::Save. 2. Only ARGB(32) has Alpha channel if (nBytes != sizeof (DIBSECTION) || dibsection.dsBm.bmBitsPixel != 32) { return
false ; } m_bIsDIBSection = true ; m_nWidth = dibsection.dsBmih.biWidth; m_nHeight = abs ( dibsection.dsBmih.biHeight ); m_nBPP = dibsection.dsBmih.biBitCount; m_nPitch = (((m_nWidth*m_nBPP)+31)/32)*4; //计算行宽,四字节对齐ATL::CImage::ComputePitch m_pBits = dibsection.dsBm.bmBits; if ( dibsection.dsBmih.biHeight > 0 ) { m_pBits = LPBYTE ( m_pBits )+((m_nHeight-1)*m_nPitch); m_nPitch = -m_nPitch; } Gdiplus::Bitmap bm( m_nWidth, m_nHeight, m_nPitch, PixelFormat32bppARGB, static_cast < BYTE * >(m_pBits )); CLSID clsid = GetGdiplusEncoderClsid(NULL, &Gdiplus::ImageFormatPNG); if (clsid != CLSID_NULL) { return
Gdiplus::Ok == bm.Save(lpszFilePath, &clsid, NULL); } return
false ; } |
使用GDI+保存带Alpha通道的图像,布布扣,bubuko.com
原文:http://www.cnblogs.com/yedaoq/p/3579036.html