1. 显示程序资源中的位图(位图的所有数据均存在于可执行文件中) ) j' t, M6 Q6 z0 V4 I+ z7 q
● 调用CBitmap成员函数LoadBitmap(),如m_Bitmap.LoadBitmap(IDB_BITMAP1); 0 ], . j" \8 r
m_Bitmap.GetObject(sizeof(BM),&BM); $ T. A' t) I4 F q2 X; \ V( N' ]
( X,Y, //目标设备逻辑横、纵坐标 , @ V! w4 M) Z. p6 l
0,0, //源数据中的横、纵坐标$ G X3 s. f% x4 ^+ j+ p. \
2. 显示独立文件方式的位图(位图的所有数据独立于可执行文件) 5 U' r/ l [* C! B: Y) }
HBITMAP *hBitmap; //定义位图对象句柄 . P6 G$ z* ^, M3 X# v3 j, D
MemDC.SelectObject(hBitmap); $ s% [( k D: S, l' s+ e. Z& k6 h
:: GetObject(hBitmap,sizeof(BM),&BM); ) ~. P, \; t E- ]8 t' P
实现方法. M7 r, J, w3 t6 E9 y
下面介绍各种图形显示技巧的具体实现原理及方法。以下所有程序算法的实现均可放在视类(CView,也可视自己的需要放在其他类)中处理,且有必要进行如下的相关操作:5 i/ r/ G1 B8 a
CDC m_MemDC; //内存设备情境对象 ( {: A) f. n, r! f1 b, y5 f1 x2 b
LR_LOADFROMFILE ); , H) Z. y* R- [.
保存位图, b! w5 B' z9 v' W
# c2 ~+ c" h7 M2 f: b
CString m_Path("C://");
1 E! u9 L8 v& Y
int nX, nY, nX2, nY2; % e5 {. o# d. y; w
// 选定区域坐标
int Width, Height;0 d6 p5 F/ L, v3 ! j6 o
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
4 Q. c/ g* a# v* R
6 i5 m7 K5 Q( y& ]9 _* L0 O
// 获得选定区域坐标
nX = lpRect->left;. z7 H8 G: T% l$ g; {( q# i
nY = lpRect->top;5 C# b* j) Q* U6 |2 u$ {
nX2 = lpRect->right;( x' h* \. Z! Y. H6 C6 m, d
nY2 = lpRect->bottom;/ l# X* S) O/ K! x5 P+ E$ V
//确保选定区域是可见的6 }% C& % s3 W9 e
if (nX < 0). S( r2 J" M; W
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > m_xScreen)# p0 ^0 I$ v3 # A5 U
nX2 = m_xScreen;7 |- j7 l8 ~+ g
if (nY2 > m_yScreen)
nY2 = m_yScreen;</SPA< span>n>4 R5 V, K' f# i' i/ I; H
Width = nX2 - nX;
Height = nY2 - nY;6 ' i" m, }3 B1 {. v+ N
CDC dc;
dc.CreateDC("DISPLAY",NULL,NULL,NULL);: }2 Y" u& O" k( 1 `
CBitmap bm;2 B u. G! m, N; }$ J! W) w
bm.CreateCompatibleBitmap(&dc,Width,Height);
CDC tdc;. C# g+ G6 {1 g$ y. J. L& ], N' i
tdc.CreateCompatibleDC(&dc);; u0 t. {& r) o; D% X. H9 n' j0 T
CBitmap*pOld=tdc.SelectObject(&bm);$ M' M$ w/ }/ K8 j
tdc.BitBlt(0,0,Width,Height,&dc,nX,nY,SRCCOPY);5 l& O5 v- c' z. L0 @
tdc.SelectObject(pOld);5 i- V7 f2 p3 a# s
BITMAP btm;" q# P- v6 [$ O# I) z, @
bm.GetBitmap(&btm);* A0 O% L( Z& a z2 A8 g
( N, T3 F- c. u" V3 j: d6 S' j
DWORD size=btm.bmWidthBytes*btm.bmHeight;
LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);9 H1 W% F! _. M( e% m, D
/////////////////////////////////////////////
BITMAPINFOHEADER bih;8 U' R$ Y* i3 ~* [1 N7 U9 @
bih.biBitCount=btm.bmBitsPixel;
bih.biClrImportant=0;
bih.biClrUsed=0;0 E; n/ Y/ m/ T' K
bih.biCompression=0;
bih.biHeight=btm.bmHeight;. O* O( f1 w) D( f9 y" b
bih.biPlanes=1;$ _% k( X) U+ V& ~( I
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biSizeImage=size;
bih.biWidth=btm.bmWidth;
bih.biXPelsPerMeter=0;7 C8 P. n2 O* e% e9 y
bih.biYPelsPerMeter=0;* e, y E7 X, H7 d
///////////////////////////////////
GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
// bm.GetBitmapBits(size,lpData); //此函数在处理5-5-5模式的16位色下会出现颜色混乱8 L- Q; P, N8 [. @
/////////////////////////////// g. Y O' U( v3 \( f6 a8 r
static int filecount=0;8 W4 t% f S5 N, c$ P% O
CString name;
name.Format("pict%04d.bmp",filecount++);
name=m_Path+name;
MessageBox(name);; Y; y1 ^& c: C }( c9 Z1 D3 T
BITMAPFILEHEADER bfh;
bfh.bfReserved1=bfh.bfReserved2=0;
bfh.bfType=((WORD)(''M''<< 8)|''B'');
bfh.bfSize=54+size;
bfh.bfOffBits=54;1 M0 a6 k" F/ O- Y" u! 3 {
CFile bf;
if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)){: d" X# l$ [' \
bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));; P" L' _$ D; b
bf.WriteHuge(lpData,size);7 k3 {' W* w2 J1 O
bf.Close();
}, E8 j1 U6 y. L1 [( D
GlobalFreePtr(lpData);8 @8 c- h* G: Y( U! g6 O% T ^
) s7 N/ _! M6 T8 v
- d( p5 B. a. [2 k6 n: J4 N' u4 w
32位位图到24位位图的转换
(一)功能9 n( x$ s4 m9 p6 |
在图像处理的很多实际应用中,我们需要对图像的颜色表示进行转换(如,将32位颜色转换到24位颜色等等)。本文通过一个简单的例子,说明了32位颜色到24位颜色的转换过程。程序假设当前windows桌面颜色为32位颜色值。
(一)功能
在图像处理的很多实际应用中,我们需要对图像的颜色表示进行转换(如,将32位颜色转换到24位颜色等等)。本文通过一个简单的例子,说明了32位颜色到24位颜色的转换过程。程序假设当前windows桌面颜色为32位颜色值。 + v; m+ w" T+ j9 \ }3 n
(二)准备工作
建立VC CONSOLE APPLICATION,选择MFC SUPPORT+ O& o" N2 n2 Y
(三)主函数
函数Bmp32ToBmp24将32位位图转换到24位位图格式。
注意:该函数假设当前windows桌面颜色为32位颜色值。
// transform 32-bit bitmap format to 24-bit bitmap format
void Bmp32ToBmp24(char Filename[])7 t5 j" u( y% C- x6 |
{
char Filename2[] = "output.bmp";4 T% {" f2 G5 f4 C; b; r; r* h$ a
& h2 J. ], ~& y9 {- F" x$ z
//注意:如果没有LR_CREATEDIBSECTION,位图颜色将被映射到屏幕DC颜色7 J5 U4 I* c1 t. F9 \
//也就是说,如果屏幕是16位颜色,则所有的图像都将映射到16位颜色5 I# {5 |( Z) J+ e: s& X0 m0 h
HBITMAP hbmp32 = (HBITMAP) LoadImage(NULL, Filename, + P* I: E; g) n+ k, l( c, c: o& n
IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | ( v/ g/ k( u$ X, `: @
LR_CREATEDIBSECTION);
BITMAP bmp;//获取位图信息
GetObject(hbmp32, sizeof(BITMAP), &bmp);5 u6 v1 b- X+ g4 H' q
3 l4 Y Z+ S0 E7 C5 `0 p
printf("Image Bit Depth : %d/nWidth : %d , Height : %d /n",
bmp.bmBitsPixel, bmp.bmWidth, bmp.bmHeight);//显示位图颜色模式和图像宽高" l/ q: X! G8 h1 @4 ^$ X, O
7 [5 z' j: Z9 Y) ~/ $ U7 [# `+ e m
//计算24位图像每行的字节数
int BytesPerLine = 3 * bmp.bmWidth;
while(BytesPerLine % 4 != 0)
BytesPerLine ++;
% T, o' b6 B6 T& h) E
BITMAPINFOHEADER bih = {0};//位图信息头; v& H3 N9 M |2 j: , y2 v
bih.biBitCount = 24;//每个像素字节大小0 X5 H, W% n2 S4 }
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度4 \ V4 |/ C O. B
bih.biPlanes = 1;: l! S3 M9 Q0 C1 ]0 O! B
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = BytesPerLine * bmp.bmHeight;//图像数据大小: f3 Q- D# u* m
bih.biWidth = bmp.bmWidth;//宽度
, H; L- a" ~3 f1 K
BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量3 _# z- ]* {6 C- v; v
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;//文件总的大小
bfh.bfType = (WORD)0x4d42;6 r4 O q' G1 F* O
/ i8 @$ N' A! c! f+ V
FILE *fp = fopen(Filename2, "w+b");# [' M) c' u* g0 `6 t
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头+ Q4 m. [! V' m `# }
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头
byte * p = new byte[bih.biSizeImage];
9 S& [ E& G6 l' L
//获取当前32位图像数据
GetDIBits(GetDC(NULL), hbmp32, 0, bmp.bmHeight, p, (LPBITMAPINFO)&bih, DIB_RGB_COLORS);
& q4 V: E [: }. q0 Q: \
//只取rgb值,存入文件3 U7 F4 W2 l2 6 e
byte b = 0;//用于填充7 X* t$ v! a/ I' [
for(int i = 0 ; i < bmp.bmWidth * bmp.bmHeight ; i ++)$ W8 I4 V& w/ X/ @, M* k- c
{" v9 t; {9 Y: H9 |
//32位位图图像的格式为:Blue, Green, Red, Alpha
fwrite(&(p[i * 3]), 1, 3, fp);3 v p6 l( B5 l: X% m% Z
if(i % bmp.bmWidth == bmp.bmWidth - 1)//填充字节9 }2 H. }2 ) f, `* \
{$ y& S( ) S2 q. v, d ]4 N6 |
for(int k = 0 ; k < (BytesPerLine - bmp.bmWidth * 3) ; k ++)
fwrite(&b, sizeof(byte), 1, fp);
}0 r% O) W. n: G/ h9 Y' l8 s4 S
}
1 ]: q6 ]0 z/ o% H2 U
delete [] p;0 i5 S- r# q% d k( r
fclose(fp);# ]0 w% a" ~3 O
- {& O$ j! y2 ~/ v' y( D
DeleteObject(hbmp32); k, ~- e3 C: T! }+ n) X
}