QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3629|回复: 0
打印 上一主题 下一主题

BMP位图文件结构及平滑缩放

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:42 |只看该作者 |倒序浏览
|招呼Ta 关注Ta

+ ^4 R4 H. Y- H* \! v

西安交通大学流体机械研究所

; I- x' ^' J+ [+ T) \- ~" H1 y

张义云

7 g& k* I' R7 {5 s4 ?

6 b/ s, Y5 B' r: j

---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,

9 l4 t+ ~3 s% O1 ]/ t

在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数

4 v5 v7 X" \: E# H

显示BMP位图,可以消除以上的缺点。

' V2 D+ C- Y* J

0 |) l3 Q7 I4 A

---- 一、BMP文件结构

. R6 b2 i$ D1 v4 S4 ^- l4 U

- z& E/ l4 e8 j5 L- W, a) A$ X9 A

---- 1. BMP文件组成

8 \$ e; K# h. k Q5 @4 Q

1 ~+ d. q, K, X0 t2 [7 Z

---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。

1 B! w9 b9 p" j3 I# R. l7 B

$ }1 y( g9 {7 U1 [+ N* p2 B9 Y; J" Z5 J

---- 2. BMP文件头

$ [. z0 H! S0 P3 c4 S

1 u+ V; S+ n k$ e* `

---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息

2 g) R- q1 Z% X9 Y5 j

. \ b% s2 K. u9 @4 I' t

8 v9 J( T& d0 U8 m2 p- j

---- 其结构定义如下:

4 ?% ^6 ~" L$ O+ N$ t! k4 t/ Q

& N) S5 G* M8 f7 ^" u: h* O0 e( M$ K

typedef struct tagBITMAPFILEHEADER

5 Y) b) U4 z+ j# N

{

0 Z! ~+ z! ]) }/ u' S( d9 @3 c( i P

WORDbfType; // 位图文件的类型,必须为BM

* n+ c) p" i; O2 z( `& d

DWORD bfSize; // 位图文件的大小,以字节为单位

' y7 o3 K! M4 j7 m

WORDbfReserved1; // 位图文件保留字,必须为0

) H6 I# ~8 Y. ~9 y

WORDbfReserved2; // 位图文件保留字,必须为0

+ e# r X; P- {- P# B( l# C

DWORD bfOffBits; // 位图数据的起始位置,以相对于位图

. _! B- ]5 n c9 Q# ~

// 文件头的偏移量表示,以字节为单位

, w" s6 V, A D+ U+ k( L3 s

} BITMAPFILEHEADER;

5 u9 Z, C. g* G% S+ Y+ }7 q2 E5 R

8 {7 w* R3 J( t3 @0 w* j% D

5 i- b* P3 I& c; B

---- 3. 位图信息头

# i: r6 A3 n S: @

----

b( y4 O% f# e' ^& v2 I" r" b( a

0 @9 @# R% L- i5 {7 j* b/ f6 s: ]! U

BMP位图信息头数据用于说明位图的尺寸等信息。

$ l% C( t0 r. |: V3 X) J2 g

typedef struct tagBITMAPINFOHEADER{

5 D, G. g' B1 z g( @

DWORD biSize; // 本结构所占用字节数

/ P$ c, U4 U+ i; z8 P0 y

LONGbiWidth; // 位图的宽度,以像素为单位

- r% f6 E$ z: s& x* i, x

LONGbiHeight; // 位图的高度,以像素为单位

1 f$ P; m3 X+ _4 m( J

WORD biPlanes; // 目标设备的级别,必须为1

; X$ Z' e5 w- i r$ i7 I5 m

WORD biBitCount// 每个像素所需的位数,必须是1(双色),

& m$ _1 S3 |, L! H' T s# G }3 F

// 4(16色),8(256色)或24(真彩色)之一

3 G, V4 k0 r6 X! g9 U+ e

DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),

1 j, C; n5 d3 U$ k% ]

// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一

- ?9 S! r' `1 U# j M; k

DWORD biSizeImage; // 位图的大小,以字节为单位

& a$ Q( D( |: A* v- m

LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数

" J; H1 [& H7 t3 g" M7 z! l

LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数

. ~9 ~0 i6 g* h- r5 t

DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数

& i; Z. Q4 t. m$ e! p; g# H

DWORD biClrImportant;// 位图显示过程中重要的颜色数

7 [8 Z: K7 @7 ? _& E: V+ e

} BITMAPINFOHEADER;

) I- l+ i! D0 K5 |5 w

5 x0 V2 ]0 P W0 i8 Z* M$ d" L

9 O. T$ u0 {" j5 Z/ ]( R/ C9 L8 @

---- 4. 颜色表

! h9 F, a4 t6 v3 E. T

---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个

. x: t A; N! v/ n' y" q1 d

RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:

& r$ J( W) A* l6 y

8 d; q: x+ e3 X: a, l

typedef struct tagRGBQUAD {

* j. l) H2 c2 C

BYTErgbBlue;// 蓝色的亮度(值范围为0-255)

. G, h. G5 j% E4 z! u8 z

BYTErgbGreen; // 绿色的亮度(值范围为0-255)

% W; I) @( n- Z" T& A( n

BYTErgbRed; // 红色的亮度(值范围为0-255)

/ }2 X0 _! }& k" a# N% j

BYTErgbReserved;// 保留,必须为0

! q) T; j& u& q

} RGBQUAD;

2 A, X/ K. `6 G) }) ~! Z6 a+ t

颜色表中RGBQUAD结构数据的个数有biBitCount来确定:

. y) Y$ G, l. l: ~& ^$ s

当biBitCount=1,4,8时,分别有2,16,256个表项;

* d9 J# P. O+ {! a2 s- r# W) u

当biBitCount=24时,没有颜色表项。

5 |) n& K" h, d* j f# A* n# Z1 b

位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:

7 R, h* [6 s& X

typedef struct tagBITMAPINFO {

2 s/ l4 ~. H* D% k1 V9 w' o8 Y' O

BITMAPINFOHEADER bmiHeader; // 位图信息头

8 _# U( Z/ W2 ~! o5 R7 {9 I

RGBQUAD bmiColors[1]; // 颜色表

; z* y1 b+ Q* D2 R' [" m) {5 L& {+ d

} BITMAPINFO;

' D+ f8 _6 L2 t: q% h

+ d4 Y* ~5 g; C" T! E

' o& y4 o4 o- D' y, ^# ?

; J: r8 E, ], l4 i$ R0 h+ O" A

---- 5. 位图数据

$ c" \( v2 l$ Q& x# c1 C

---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右

& C; W5 ^8 G- n$ V! E! X

,扫描行之间是从下到上。位图的一个像素值所占的字节数:

9 `& {) h r2 {4 a

2 ?! W1 {" f7 N

当biBitCount=1时,8个像素占1个字节;

; q* e) i% J2 Q4 n+ W. [5 r

当biBitCount=4时,2个像素占1个字节;

& b; K" `' b1 V4 V+ W' x7 U7 K8 s/ X

当biBitCount=8时,1个像素占1个字节;

( H+ C0 k, R! {0 D

当biBitCount=24时,1个像素占3个字节;

9 I0 s a V4 m2 g6 a: g

Windows规定一个扫描行所占的字节数必须是

& P3 B, @- N4 X0 X+ L. @8 m

4的倍数(即以long为单位),不足的以0填充,

+ D% q0 n5 B! C7 f- H! f+ n+ U

一个扫描行所占的字节数计算方法:

$ l9 c1 t$ H1 R Y, C& V4 i

DataSizePerLine= (biWidth* biBitCount+31)/8;

+ T* ~+ [# R2 x. ^

// 一个扫描行所占的字节数

8 O$ ]5 @0 t1 s' X0 O8 H3 b5 ~

DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数

4 y# N5 b- j& z6 Z

位图数据的大小(不压缩情况下):

: h- d5 I" |9 c) ~6 v/ W$ b. @

DataSize= DataSizePerLine* biHeight;

/ W; V+ e3 A G" G; o3 I1 N7 W: G7 Y

& X& L3 W9 u0 U) u

2 I) Q! h; @. N3 K$ K8 ]

---- 二、BMP位图一般显示方法

: F0 K, A* _4 Z1 N# _3 H9 w! f& q

---- 1. 申请内存空间用于存放位图文件

' }. e+ A m' l3 n z5 w) _

0 X/ n) {% B- N7 h

---- GlobalAlloc(GHND,FileLength);

# {' w6 {1 m7 o% P, ^/ N1 a

+ z$ E& ]7 M0 d1 ^, s

---- 2. 位图文件读入所申请内存空间中

& T$ V! ~+ g1 @% X& ?& h

4 X' ^9 E6 D2 X' B( U: @9 N

---- LoadFileToMemory( mpBitsSrc,mFileName);

3 B7 H4 p1 o4 q% z8 ^7 c

3 U# ?( E' H4 P K, T8 `

---- 3. 在OnPaint等函数中用创建显示用位图

* T4 |3 x6 \/ b9 R

3 {1 [5 r `" |. m+ l8 K

---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容

# O& S9 ^: ?' D* b- U N: { Q0 f

DC,

7 O0 G$ B: b- }8 d' P

$ e9 t' a4 R* H! |) C! M. \1 x% _

---- 用SelectBitmap()选择显示位图。

# s3 G; R6 N, y$ h5 m& f

+ V4 K, Q6 a, k4 Q

---- 4. 用BitBlt或StretchBlt等函数显示位图

* w* W& K; N, h5 [# S

0 w4 F# X) I& y( f( v% X

---- 5. 用DeleteObject()删除所创建的位图

# [. s1 v" X) K2 H% P$ J. B

* @3 s3 V% _' T& T7 M* o

---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示

8 v- E1 g( r5 C* m2 w' k8 |

时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(

; R, n" I7 S3 `, }4 q, V7 r

如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。

% E; c; j3 x& k1 h

2 G, y% L* X& M. u" u$ q& p9 J5 Z

---- 三、BMP位图缩放显示

9 G+ N& Z% m& @% t: q: I

9 P) m) Z9 e) i4 E/ r0 ~

---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形

- f c8 l5 K( b. r

进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比

0 S" b6 v' i* |$ ~$ X6 m5 ?

图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下:

0 w1 {9 G8 e6 ^: w7 z& }

* z* ^" l2 e8 P1 X# y; Y& l8 Q

---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中

" A- p, M- P( |% G6 t9 x- r* l: e

; U6 R5 q/ G( ^+ k9 ~

---- 2. 申请内存空间用于存放位图文件

+ l1 r- W2 A* |) t# x" }

! u2 x$ E* ^! F* X0 B

---- GlobalAlloc(GHND,FileLength);

: G, K% {% R! L& ]) \" v& N. c: z

8 o+ F& O( |5 |' r" u

---- 3. 位图文件读入所申请内存空间中

( d" |( t( u( e6 j; V/ D

! N! q$ U; ~& M- B

---- LoadFileToMemory( mpBitsSrc,mFileName);

' }7 I/ G/ i3 X( R7 I

/ j7 K! [9 v* R% X% d% K) E

---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图

8 P2 d6 `+ l( Y0 p+ R

! w5 J% H k/ w3 N) p4 R

---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中

% C. W9 Y+ F0 D" A1 e

* y) f2 I- z2 d i

---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形

+ z: F* O) X) E' A& L; {) Z

失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通

. Y" g) G) T# |# ?0 J

过直接处理位图数据,可以制作简单动画。

2 m T5 {9 t! z8 I: y' b

2 H& S3 C, A( `- \

---- 四、CViewBimap类编程要点

% m# G, ~( d1 U! w: b, X D. |

8 \1 Q1 R! w* w

---- 1. 在CViewBimap类中添加视频函数等成员

}- s B2 h+ J8 Q- z

: T; q: E. L6 o0 V5 u

HDRAWDIB m_hDrawDib; // 视频函数

% b8 C5 z8 Z; F/ e$ |

HANDLEmhBitsSrc; // 位图文件句柄(内存)

& _5 B3 p7 r, }1 g' z

LPSTR mpBitsSrc; // 位图文件地址(内存)

# u6 T) g1 K2 E

BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头

; z+ ?7 [. `7 `. [9 x

* G F6 |7 R/ Z" K- o; Z

! ^& ]+ ^. l n

---- 2. 在CViewBimap类构造函数中添加打开视频函数

; C) N1 `' [8 D! b6 i1 T

---- m_hDrawDib= DrawDibOpen();

% V) \- X" K! h9 A8 T! N7 ~

. o H% X( b* S: f/ A( _" k

---- 3. 在CViewBimap类析构函数中添加关闭视频函数

& I9 d/ W) W/ ^7 C

- M* L8 u6 Z! Z) M

if( m_hDrawDib != NULL)

# i$ b. Y0 b4 P

{

! I5 _& y- E4 l( h. v, E

DrawDibClose( m_hDrawDib);

: ?. B7 m0 |3 y& W

m_hDrawDib = NULL;

" k( K. O1 c. V* P

}

+ A9 N. ]6 `& d

$ \ J; N7 f# F' d$ k# e

0 s2 |3 }8 O- l9 q9 ]% Y- g/ B: h

---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw()

* K. _6 E$ ^" `( r2 J9 t

voidCViewBitmap::OnPaint()

" F! n7 s, N; J6 y# v" O0 Z

{

( H" `- l% C" Y, A* ]) G

CPaintDC dc(this); // device context for painting

% ^6 j2 n, W( V( u

GraphicDraw( );

9 M7 s) |3 X# s

}

3 ?( G" O! n# I) B% J( D7 r' w* c% t4 g

' A0 c; Y: a3 H9 ^! J

voidCViewBitmap::GraphicDraw( void )

0 b& a7 M. x% E; @& D

{

6 H; r: ~7 L( N$ M: V; N

CClientDC dc(this); // device context for painting

, w- y* F2 l. S: j( Z. c

BITMAPFILEHEADER *pBitmapFileHeader;

; v |( j \! \( X ]

ULONG bfoffBits= 0;

# ` C6 ?1 {2 l L% J* I

CPoint Wid;

3 X: U w5 m& P ~, W

2 v. _' c1 p8 z' ^3 A

// 图形文件名有效 (=0 BMP)

6 V7 O0 j) s' Y

if( mBitmapFileType < ID_BITMAP_BMP ) return;

# R, }) {- v& Y; n- M

& ^8 Q/ n6 C9 B3 ]% H) F0 x

// 图形文件名有效 (=0 BMP)

, X$ a* {$ W, ?0 n

// 准备显示真彩位图

7 y/ U, `7 p, d, \4 K

pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;

' _0 W2 F& @4 B/ C4 u5 j" d, J

bfoffBits= pBitmapFileHeader->bfOffBits;

, s3 r3 x3 b' H+ C* n

3 v4 Q3 I+ m+ t, I. X

// 使用普通函数显示位图

+ X" F8 D2 P' W7 {: t% d$ ^

1 P. F& x. I3 j n5 E' `. {

if( m_hDrawDib == NULL || mDispMethod == 0)

, {, P& S# ^4 ?3 f$ n/ w$ O6 C D: _

{

2 L) h/ f r, {4 j, K( i

HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,

6 h/ ]$ \3 O; v& A

mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,

& U- l, [: J) v) Q3 P6 P3 y

(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);

' O6 H( ]; C" I d: {' \

// 建立位图

9 [( t% w9 Q Q/ M1 W1 G- y0 j

HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存

6 f! X4 v( V' L, P) h

HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象

" i8 a+ k. x+ p v" n

// 成员CRect mDispR用于指示图形显示区域的大小.

. f0 M/ \4 I0 y5 M

// 成员CPoint mPos用于指示图形显示起始位置坐标.

- V! C: i* A' A U2 a' h0 ~" j

if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))

! K h, M; S# [, m. N

mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;

4 E4 ?# `: X7 t8 V% \+ o N

if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))

2 o1 g# I( P3 o0 M* ?

mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();

' Q; i- j' b/ ^5 E# P! }- S

if( mPos.x < 0 ) mPos.x= 0;

r0 J1 ]2 @! q

if( mPos.y < 0 ) mPos.y= 0;

, B! \7 W: O$ ]4 r% u/ p9 c+ s

8 @9 Q% ^8 z7 E0 D7 p+ d+ p8 @1 c

if( mFullViewTog == 0)

6 W( x1 U, D# ^" j

{

# Q5 h" j p% Q& j5 \! U

// 显示真彩位图

/ o. c& n; {/ {- j$ P/ O/ R

::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),

1 e9 G5 h# v8 x. d( z5 }

hMemDC,mPos.x,mPos.y, SRCCOPY);

" a, r a/ `8 R3 c- H9 P

} else {

& K( N+ \; d' _) N0 s. S

::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),

; i: x, D( j$ R2 [& z

hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-

; ^! ?2 q$ @! o0 i# P8 j1 I; P

>biHeight, SRCCOPY);

! a1 t3 N/ b/ z3 M

}

\. `# l3 H: }7 D4 M P

// 结束显示真彩位图

# s; \1 t5 p$ Y1 f! y

:eleteObject(SelectObject(hMemDC,hBitmapOld));

! R- Y/ u5 i( O+ {

// 删 除 位 图

, A4 ]8 |+ J# D7 F3 |/ x0 G

} else {

. E5 N( M$ W' z( n9 K5 h

! b2 T% y7 l0 a3 Z* `3 m- w

// 使用视频函数显示位图

# {8 y7 \6 B5 q

/ p( a% a, d: J, I9 l

if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))

5 V, O" L% X$ F

mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;

# K6 R& o. L H8 \+ |

if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))

# {+ e) \) C9 g) o

mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();

0 O @, E" R% `/ y7 U& z D

if( mPos.x < 0 ) mPos.x= 0;

% k# z2 ` e7 s% [

if( mPos.y < 0 ) mPos.y= 0;

$ l0 _/ T0 O3 @. o1 o& X, f

2 p# l( E9 c7 a; E6 f! B Z

// 显示真彩位图

' L. E3 m7 x6 `7 \6 G& T, o5 c

DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);

2 ^6 s; `; B$ G

* a$ U8 \, M9 b) z% ?9 g

if( mFullViewTog == 0)

* P$ L+ `. R/ ?+ h6 c% C

{

9 K4 @. m, n9 o- t

Wid.x= mDispR.Width();

& f/ {; e' E: L8 O. ~( _; ]

Wid.y= mDispR.Height();

% r5 @0 r& H% {1 N+ S4 j" T

// 1:1 显示时, 不能大于图形大小

- K$ [: S9 ^1 C4 L; e5 F. C

if( Wid.x > mpBitmapInfo- >biWidth )

. {. ?& i# {: _& ?0 k3 d; E

Wid.x = mpBitmapInfo- >biWidth;

4 G' {: h+ r% X' l7 H( W* e/ j

if( Wid.y > mpBitmapInfo- >biHeight)

0 j' \' b% b1 \ u

Wid.y = mpBitmapInfo- >biHeight;

8 E5 t8 J2 G. t& [

5 i5 c% b# z1 N% q" q, B! z

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()

# h d }* a0 E+ u" e, [, H: E

, 0, 0, Wid.x, Wid.y,

! \5 u7 n9 I+ c V9 a

mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),

$ d* f( y* r G( ^ S- h

mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL);

5 }4 s1 z2 \" [/ x( P' M% X1 ?8 q

} else {

" l7 E9 b' X* S8 ^6 w5 G' v5 |

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),

# T% \4 Z0 F0 M! f3 d

0, 0, mDispR.Width(), mDispR.Height(),

$ M+ S" D5 Y: F d$ e) F8 X1 R' ~

mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),

' e, p. g1 U7 ]% Q3 D6 j

0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,

0 [, G. v8 O6 B

DDF_BACKGROUNDPAL);

) d' ^- L B" B* q: A/ h6 n D

}

1 ? N1 x& k. y4 y2 @) `- Z

}

/ ?) w" C6 v* S/ _7 j, E+ N

return;

( q. y S) Q% {

}

2 u2 k4 p1 a! i& \. p4 s6 N

3 f& D2 q$ X4 w- N

2 |; p( y5 @. P9 [& z5 e5 V

---- 五、使用CViewBimap类显示BMP位图

9 n- R$ y0 E; ?

---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC

% }0 D& L' c3 b b8 \) c

AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点

) r- `( r7 k, y1 {- R3 Z

击ResourceView,点击Menu左侧的+符号展开Menu条目,双击IDR_MAINFRAME条目

2 L. S9 _" T& F& }7 C

,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的

, W, {/ H( }0 @$ C1 D6 z$ I

尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。

+ M# K8 d7 t* s9 Y* E

. l" o, `/ ]1 {* @1 L( L" A

---- 2. 在Visual C++5.0中点击下拉式菜单Project- >Add To project-

/ Q7 T6 D i, }

>Files...,将Bitmap0.h和Bitmap0.cpp添加到工程文件中。

3 [; k7 P" ?; u7 V' h1 s( H7 Z; @

* F- x3 S5 K3 g0 ]- s+ W

---- 3. 在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为

8 S: ~4 K! I0 C, |3 p8 n

CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages选择Command,然后点击Add

8 S% R/ p9 D, W) X

Fucction按钮,然后输入函数名为OnViewBimap。在添加OnViewBimap后,在

/ q0 r+ n/ i0 Q0 `. ?3 M

Member functions: 中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码

. n z( `6 k; p u5 p: Q

。代码如下:

, T9 b. R& _1 Z; P

5 I7 b* N2 `; W2 N) m

void CMainFrame::OnViewBitmap()

7 W0 D- `5 l' c' d! h5 H: G

{

. H9 j2 t( \5 t6 r' w

// TOD Add your command handler code here

. c, Q# k$ x. W( `$ F' t

CViewBitmap *pViewBitmap= NULL;

4 l2 ] W7 g2 {7 S

`3 I) E9 c! A$ w

pViewBitmap= new CViewBitmap( "BITMAP.BMP", this);

$ j% E2 R2 g. B: J/ C5 m

pViewBitmap- >ShowWindow( TRUE);

/ r0 [9 r% r; @3 z

}

* x; `8 Q$ B5 ?5 |$ n& }4 }- L

" R% m, e: y3 {- Z

% y" K9 N- c; l C6 i8 `

---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。

7 q7 D9 n) T; x' ^9 @; M/ D0 ~( [

---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。

5 F) b4 g) K; ]- U+ b8 }

4 b/ f1 V8 }4 C

---- 5. 运行时,点击下拉式菜单“查看(V)- >ViewBitmap”(英文版为View- >

1 x; B" q2 q1 ]. e) _8 H: J3 v& _

ViewBitmap)即可显示BITMAP.BMP位图。

# I6 p. W% W. u# j( k6 w

/ O1 a1 U+ x( Q i9 z# e

---- 六、CViewBimap类功能说明

8 E9 u' e$ Y* b. k3 E$ I

7 y1 C, _5 |% o) i6 w

---- 1. 在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可

3 M) B' c( Q0 c1 n0 F m0 g+ N

以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。

, E9 N( [0 t1 r# y* S/ E

7 k- E; @/ x, R6 Q. @, C

---- 2. 在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为

. g7 _' o) [4 G, D

位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标

: c4 y- ]! u* S( S* a' `

,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在

" f5 h) @7 @0 u0 o" [" |( d- T

第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区

5 G1 |) V% b# W: T J% I

小,则对位图放大; 如果位图比客户区大,则对位图缩小。

+ `6 e* n3 f7 w# u/ I& e2 f

$ l5 p, Z6 U) _

---- 3. 支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,

# h8 A' P, g- S: r! t

就可以显示该位图。

" k) |1 X y' H8 k# c4 T" s

9 _, x8 _" A1 f) s$ C6 y8 \& w

---- 程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,

; c% b5 Q* L& q4 L2 w3 V' [5 f7 c2 t3 e5 E" u( i7 _

在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图

' n* n5 h# `3 C% C& x. `( @

放大时两者差别不大,但在位图缩小时,两者差别明显; 使用视频函数时位图失

* P5 g1 b2 z$ i

真小,显示速度快。

+ H' f/ x$ R O* o# U

9 g0 h( _0 W, u/ P# z

---- 还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模

m! O; g, E: g; n8 k+ x

式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可

9 J: @0 n9 i7 j+ W

以体会到使用视频函数的优越性了吧。

4 r% o+ d+ T% @- `9 X" {$ s* x& q

: V" C, J8 V& l

---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示

/ X8 s# V" l {% _+ ^# M- q3 q

程序中加以适当调整即可,读者可自行完成。

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-4-18 10:41 , Processed in 0.443623 second(s), 52 queries .

回顶部