QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

8 P1 }, O! m" `

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

: I9 y5 P+ U" |* X

张义云

0 B. g$ m. m: z& C8 S) L4 {: ]

+ F+ Z; G8 @+ S" K/ D2 Q

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

" [8 h. z( s e6 w- R( e

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

6 i# i6 ?! c& S/ b2 |, {: ]

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

$ U* k7 q4 a: ~( b% _& b0 U' s

, [0 ^3 v$ D- v2 S

---- 一、BMP文件结构

* K! }9 N! H" `! W

" H8 ?. k, d: N, \" }( Z1 d$ P# S

---- 1. BMP文件组成

% C$ x9 X6 ^ \9 H( o6 d. J

; E% T, ~& `$ r' ]* n _. N# B7 R) x$ ]

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

6 q- k8 ?9 f* ?+ P' V4 I

. P# O/ Z/ n2 P

---- 2. BMP文件头

& L! B' ^1 a! k/ ~7 E

* y% C# S* W% W/ S

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

4 L, g E; @9 h8 Z

0 c" ~) }. m# v7 M5 N0 T* f

9 a q% k* F4 K+ M

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

4 w5 m% @6 P7 `& E) a- m$ B

, w u* V; x: O% k$ r |

typedef struct tagBITMAPFILEHEADER

! Y: _) Q; L' i# T' ?" i1 j

{

) c8 ?5 U6 U- f1 E3 s5 m4 X

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

2 n$ Y# J* C8 o' S; Q( A

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

0 \( W, u! w- P& E* g/ Y1 N

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

$ c2 X j! d& R3 `6 X+ n

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

/ d% P9 o0 E. p# W% d) n8 l2 j# Q

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

5 I V8 M( x1 o

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

1 O) ]) {- y# N5 K

} BITMAPFILEHEADER;

" t, K- G- t: E! f$ ]

: s4 m7 d3 b2 i/ d; _0 ?6 s+ u" |

9 u+ R% D5 }, u7 p+ o0 ]2 i- H

---- 3. 位图信息头

$ U- E) J1 A7 \/ E

----

* I5 D3 T. Y: t) C# O& k1 Q

9 C, o5 E: U0 w' A9 B5 a

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

& S+ M8 ~" U1 D5 |0 E" S& J

typedef struct tagBITMAPINFOHEADER{

9 H4 i) R- ^& Y; g# w+ N3 L! [

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

d' `1 y) T; n/ O r- \

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

) B- o% a+ Z* M N

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

' ?, k+ H0 S. x: c

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

9 r) B+ r' a- J$ ^, U6 Y3 m

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

3 v! K% q s3 Y; x$ B

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

9 a7 d, h" Q G9 Z- f1 @& Y+ h3 i6 @

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

6 {( {- ~3 W% j; b2 D

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

- w) b/ W6 i3 G7 }$ I. [# F

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

E% |' q, D1 F. I' {

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

6 Z) q! T7 Y5 X6 S' F

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

& i' _5 `4 s! G8 {; {# G

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

& F, Q; k. [: P8 g8 \. I ~- W

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

" ?( ^, X+ X. p s8 a

} BITMAPINFOHEADER;

3 ~/ g3 a7 f' N

8 i! U' y p C( e( W F

8 ?8 V" Z7 i9 q$ q7 e" {- `3 o* y

---- 4. 颜色表

* C {8 g4 K9 c5 @% g3 Y

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

9 h+ [4 z, v$ U7 F, A" \

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

: H1 H" V1 ~ u( o

. m! w9 s! x0 q

typedef struct tagRGBQUAD {

c4 R5 V, a7 s4 v" r7 B/ `. {

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

P' s1 {$ _2 q8 s. C+ _

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

9 V- B" M. K# b$ e& f5 `$ k

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

5 o; v: R4 p# `% g

BYTErgbReserved;// 保留,必须为0

& H4 j$ Y4 }, }; |

} RGBQUAD;

0 c1 N& k1 {0 f: J9 D9 l( I

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

! ~/ c. e+ c0 W- C3 ]- H. q; T

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

1 w$ m, D1 v' j( a' T/ K/ p8 p( w3 m

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

) L; Q4 |' f0 Y7 m

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

9 s4 \0 H6 M- u1 K' V5 s+ @2 @

typedef struct tagBITMAPINFO {

' N$ v% ~1 v! s/ h( M' J# P2 L

BITMAPINFOHEADER bmiHeader; // 位图信息头

0 w. t1 j! G, T7 G

RGBQUAD bmiColors[1]; // 颜色表

2 a( [- u- H: y6 j% [ k2 P: V# g

} BITMAPINFO;

) r* o9 ~! T& b5 ?& [+ F

+ o% x- P" G K- G5 A

, j2 |' A! H( Z/ S& r& d8 f

3 ~4 v- }% H; P: W. G- ~

---- 5. 位图数据

) O F) @# A4 o

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

' ~6 ^, X }& E" a

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

% n' ~: r9 f$ G8 W# g

) J, t: m( N6 }5 s% o* d

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

. R8 i( Y+ b. ~. T. j- N+ h

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

- S3 n2 `" o( A7 {% _% w

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

+ V% j) ~% y4 }) u' ^) S3 l# E# |

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

4 p9 a8 o( Y8 ~+ O* U) z. A

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

" x. D7 C' r$ e& L% _

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

3 s5 t( f1 G0 A; D% Q/ o

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

2 E- V+ o2 ~* E4 ?

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

) b3 x8 w( F; L' A6 H

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

6 s# Z G. W% U- C' V3 B

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

& P/ A" w" H$ a' m* s

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

3 R# `# l/ |4 u) v# h5 C: p

DataSize= DataSizePerLine* biHeight;

2 p/ A+ |* }/ I/ i e

( W) D& f$ ^: k! {, @+ O' E. i. e

) I$ H0 |3 a* a2 Y/ i! i9 ]

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

( Q6 b$ N8 i9 g3 y0 ^# i1 a

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

. F6 q1 r( z/ i K: I" z% G g4 X

r- o, p9 f$ t* U @ Y

---- GlobalAlloc(GHND,FileLength);

" K2 x) ~! ^7 Y! I* _

- Q, I" S6 }, Y5 O. v

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

3 \% x( v( B% p1 o& l. \1 a

' ~* V" O/ G" W8 {% G6 ~' c

---- LoadFileToMemory( mpBitsSrc,mFileName);

0 u' J, M/ W1 O" {/ B" t

; n; O6 ^7 }" Q) x7 F' d, `

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

6 ]+ D4 e. @; d/ I6 U2 E

$ I" C( s3 y: ~, q

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

" A& p* D/ Q J: a9 e

DC,

% g- Q5 |/ v5 ^* l8 p1 S/ k5 g9 p7 l* ]

5 v* H1 {2 r$ Z( N x7 N- c

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

* W9 P d9 ]* P8 V$ q

& N6 D7 R0 z0 z! C7 D. I' u. ] Y

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

. C3 t2 H' F I5 d0 h& ~& c

7 u5 n! y, F' r+ K% k

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

, \9 e* N% _4 B: V* x. e8 w

6 B+ v9 `8 ^+ K, h% |1 f: h/ m

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

0 h" R; a: x: X* J* C/ o2 \

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

[3 R+ Z2 ]) U5 I% `( A

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

* g2 @& ~4 T. Z q

( n9 U- R" d. q- V

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

2 n5 B- e/ \: P L5 s# r& p

`& V: [, x/ E

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

+ q3 z" g/ }1 O/ |1 z( K" I0 U, i

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

# Q# f/ ~% Z* L3 N7 d& }6 X) C

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

: ]* |5 @! _" F' e. N

: `9 t% U b6 D, r8 f' u& H% O

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

0 N9 S3 L/ x% T# L/ I

# ]. i+ o% _% h! z

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

5 `& Z' A: Y. r7 G3 k9 y* B4 {

& r @8 s) `" X" S4 r

---- GlobalAlloc(GHND,FileLength);

X1 C% R" s" o7 U: z

$ P* s3 ]( F8 K M5 a

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

+ d2 ?# D& n: o3 p. F

! k& k" w1 u) V- R! N4 F% N" w3 P

---- LoadFileToMemory( mpBitsSrc,mFileName);

5 Y B# Z8 C: R. @- ^9 W! x0 N

) S; B8 J6 V( `# n. K$ i" j

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

6 `# ^' z3 k5 T1 Z6 k1 R3 f# G

- e0 {5 D! z& |, a% @! h

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

( y; y2 V; y- c) {9 H

' W- e7 R5 W1 e, a' P- ?5 v9 |4 M; u

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

8 c# b/ D1 U& T9 z2 T

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

2 ^0 i, h8 {7 c4 ]* |

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

. p# C3 Z9 k, q8 k$ z# W. g1 V

4 y$ a+ P! R: p8 @% [

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

; Y7 K p/ m8 q/ o

) ~, w, q" f0 [, A

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

- Z3 I- P. q# F' d( p" r* ^

* @! K# l1 R' d

HDRAWDIB m_hDrawDib; // 视频函数

6 ], t* s3 K5 o+ @( h. }

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

0 R9 B- P" S3 r) E- o

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

# y: O! x# k$ c/ u7 L, N' r7 i

BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头

5 p2 A+ e; |0 T j

! _; b) n, Q& C7 l

" ^0 o% U8 j2 B5 j* @0 f

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

' U' m% r. Y8 f; B2 ]5 o

---- m_hDrawDib= DrawDibOpen();

# e6 d- |- u3 H V

) X! n8 I: v4 w5 S* r4 z

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

+ ~" U0 s. S1 P7 y+ @

8 h% W7 c+ J. u" W% w, z

if( m_hDrawDib != NULL)

0 n$ p. j# w; n5 X) G

{

, _$ }. B1 V& J% N8 u1 E& u

DrawDibClose( m_hDrawDib);

, ~+ E# I* r, h; a

m_hDrawDib = NULL;

# x# `# x3 s' D; p& ^2 e( n

}

) L% o" j( j+ `6 }9 ?/ K' D/ }. H

+ h! B* N/ `! G, o7 H+ T

6 C5 U: [1 z1 ~ b& c9 h

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

5 g7 @. [$ z" U

voidCViewBitmap::OnPaint()

! g' ~. }% |, F8 u

{

, r" j6 S. D- p

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

: g7 D# i9 E7 H+ \ |

GraphicDraw( );

+ e# d s e* H

}

# [, {- k6 l! p' H# h

- ^9 }+ f, N% b! w5 r

voidCViewBitmap::GraphicDraw( void )

7 F2 J' K) b& X5 L$ C" w5 F8 e% R4 U

{

3 _0 R! k0 D! ?+ L- L

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

% M8 B# }" n2 v' r% X, |* S3 W

BITMAPFILEHEADER *pBitmapFileHeader;

$ s- y0 g5 A8 `% l5 O4 i( a

ULONG bfoffBits= 0;

2 F0 A& U- W1 I: j- v4 u

CPoint Wid;

; ~3 T4 H7 ]5 `8 p+ i$ g

; g8 }: h) A( H) D- a

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

8 ]2 y: A2 g2 B- D. E

if( mBitmapFileType < ID_BITMAP_BMP ) return;

2 b# D# ~: H( G' _

8 j7 H( h; O4 _/ G0 ^) y# z! H; [0 {

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

. j) o2 X$ \! F1 p7 M% P7 v) ~" C; P

// 准备显示真彩位图

/ L$ l* m1 D5 W9 c5 r7 o* b

pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;

- k2 D/ t, ]% }" [$ o4 G

bfoffBits= pBitmapFileHeader->bfOffBits;

- A$ d2 _2 b0 {+ w; d

! ]) f/ K5 {6 u j8 i

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

( o1 s2 Y& S' f- u- k6 y+ R

) ]2 a1 X; J4 l" c7 ^9 T

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

+ b6 D P, I' y& J) G, y3 ]! U

{

A5 Y+ R; e/ @2 ]- S

HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,

4 M0 k U0 z* I/ b# m; H

mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,

+ \6 d7 C7 q2 O1 S" h4 `

(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);

9 a7 V. A. r/ l% b- v* k1 z, H

// 建立位图

5 r" w, g/ D3 s5 a) d

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

9 M @# p1 W* S

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

; e G; k6 A W$ s1 P0 I% B& c

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

* n; I7 @4 I' x D* t# T

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

, V3 U/ X& S9 Y& j

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

. ]3 p3 U: s" r6 G) p, U$ S

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

* i2 O- s( F" [+ j/ q! s7 V- ]9 `! ^9 L

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

9 p' |& E' _' e* W

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

! e+ A$ i$ Y# t; |7 q

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

- h/ b( r6 G, I& Z8 L2 R

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

$ w' m" f) q$ B/ ~

+ z0 G0 M1 f4 }4 |8 v& d6 I

if( mFullViewTog == 0)

: @! m, |. \/ J2 t! B

{

; j. D/ ]- J( w0 U" T6 \- a: {

// 显示真彩位图

) @3 X$ C* {0 `1 r3 F

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

+ m. U4 B' o! C3 d

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

* `% S$ \& J' B

} else {

- X* E1 J! A4 L3 t- e7 y. j' s3 k" R

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

4 h2 S& r- C( I7 G' V

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

- P4 n; A7 J' O+ A7 m" z8 s O0 z

>biHeight, SRCCOPY);

% C# P5 a$ d9 c, w. k

}

, P) ]1 F' m, d. A# t

// 结束显示真彩位图

7 M! X+ D, t2 y1 N' R8 Y J

:eleteObject(SelectObject(hMemDC,hBitmapOld));

) f& p. r) T% C+ r

// 删 除 位 图

: ?$ E% w( t! p3 f6 s

} else {

% o& `& X) P2 i' g+ d( q9 a/ W

# Q9 }1 X E8 \1 G3 q

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

+ U( X7 t' Q7 B- V9 l" v8 G8 r

/ S9 \# L0 H! p( q, @

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

5 ?: _; G1 Z+ S: g

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

4 V! }8 V- A3 d2 b: e

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

; B" ~4 e0 ^$ V* z# u3 j

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

/ c4 [4 R* e7 A4 U% g: G+ q4 V

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

1 @; F! G) o0 k% z( m5 Z( l6 z

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

) b; l; z9 n- c( j$ B! a- I

9 [) F* ^: ]$ z d

// 显示真彩位图

4 l* C# D [! V( w* k5 |. G9 \& c

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

! }* F/ x& p9 k) _* F

( e; S" a3 {0 n" W/ d7 ?' P

if( mFullViewTog == 0)

3 c! P2 m( C5 @4 c. U1 Y

{

+ B* d8 z- I1 b5 l& @4 E) `" y

Wid.x= mDispR.Width();

: _# v: q; h* e9 U

Wid.y= mDispR.Height();

, ^1 H# f$ j! ]3 A: Y

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

2 h: z- K/ x( m* M& e1 y

if( Wid.x > mpBitmapInfo- >biWidth )

3 V; {- t: ` d6 I8 S' p2 K/ d) f

Wid.x = mpBitmapInfo- >biWidth;

6 F/ q0 V( l% t5 Y/ d0 d

if( Wid.y > mpBitmapInfo- >biHeight)

5 z/ q8 i$ E# l9 c! I" C

Wid.y = mpBitmapInfo- >biHeight;

/ s! F* h+ G6 T4 O0 q

9 w, A7 K9 F Z# j: f

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()

4 Q) q. {1 L. J

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

: }7 y9 t: V+ T* S6 Z

mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),

- \* B8 K1 ^7 P! a9 u" v$ t1 Q

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

) s* t3 _' f0 c0 Q+ D8 N! M. ?2 S

} else {

5 |4 |2 S0 V7 H- Q+ X8 P- H

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),

5 g! z: Z5 H0 |" I3 o

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

3 t7 R" z* j% B: G/ F

mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),

# I# q- v; F- ~9 V3 e" z5 `

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

* G+ R- ]: f+ P

DDF_BACKGROUNDPAL);

2 y% A; E: F8 x/ g1 p K

}

, i5 l" L* w, E# F+ p# Y

}

. m8 D2 [5 S2 j8 R

return;

$ w; j; x1 ?/ Z. ?, W

}

7 ?8 I- j8 q! u C7 G' a; ~

, [6 j- o% ~; D

/ W7 k# ^7 {# p: Z- \

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

# M, M s5 P* `

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

. z. ?0 C# A- Z# x+ m

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

' ^2 P$ t2 p* f

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

% ~9 e& t+ \: \

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

$ r0 y& N+ b+ D9 f1 A* B

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

2 f) D7 H& E6 Y2 I: w2 U

- I' L5 H. ?7 Y8 x7 ~* m% [: l8 L

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

! Q7 K% e# ^6 h

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

1 f& L1 X+ N# F- a/ F4 `

" R. h( U* R( n1 a8 ]) [# @3 u, }

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

5 h8 R/ R7 u9 E; a. m. z5 i

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

* `8 y! f1 f% n/ I; y$ V, j- ~

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

8 M8 B8 d. O. ~( H

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

2 t% t9 A3 {" r1 ~

。代码如下:

" R1 ?) n% f0 F! b

: h4 ^8 r6 v& c! M' m

void CMainFrame::OnViewBitmap()

( z: v+ B8 b1 t* i `4 z1 E

{

' Q: I) u2 F& V+ @

// TOD Add your command handler code here

( Y1 Q/ b& Z9 p. _* ?$ F6 |

CViewBitmap *pViewBitmap= NULL;

' N( d' a z4 d. O4 p* f, N$ i

( H" ^3 u$ _+ _: c F, V

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

6 c0 R) I: F4 Q* u6 i+ k0 z3 w

pViewBitmap- >ShowWindow( TRUE);

. m( o- [! ]* Z9 R/ \# f

}

7 R7 x$ Z4 w: p- t0 Q

" s# S' @, h4 y4 l: G% B* q9 M

8 R' d3 N" @" n6 g

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

E- q$ b- S6 X* f, S; u

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

" p7 x$ k- Q8 W( o. o) k& G

1 z2 w) K5 m0 \

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

- g% {$ V6 ?8 I2 n5 {: y S7 Q

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

! K' L( q9 ]$ q7 _, p

- f5 v0 {# f9 s1 x5 `4 q

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

2 W: W( S3 ?0 j

/ x) X! K. g9 t5 g; S3 y

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

3 `* M. U+ B) @5 F+ G/ D/ ]( A

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

- c" d. U* ?6 z. `- `& }% O

$ n S5 e7 X$ H7 M6 i* p. G5 B* A

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

1 y! v6 u! r4 G5 q2 A: ?

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

$ @2 K4 }8 Y4 G" G+ t# f

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

7 O& T5 c) Q5 y) x% a

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

2 q' L6 C+ b5 p, k" y+ k

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

# @7 S/ X( T5 ?1 y! ^+ q! {

7 ?8 i4 X6 {2 q% d- p

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

7 q4 b# g0 [, @3 b

就可以显示该位图。

* X& X- G. l; _1 w

4 C4 d- K! p2 W9 z: g

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

3 @- u) [5 K w$ \ 7 T, X4 z% B3 ?9 l2 J

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

6 e v) D* f; v+ p

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

( c0 D. [1 w& V6 z3 `

真小,显示速度快。

' k2 B: k! `0 m6 I2 } _0 ?

: Q) b4 C R+ q

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

3 t: J1 a3 ^( x: j) v- Q

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

4 |5 E" e+ D' X3 O" M

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

2 J, B( u' N+ L0 m- [; S

2 C8 Z0 S/ p7 S1 H1 n

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

1 A6 [& l4 d# x, x7 v8 h4 Q% B- s

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

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-6-15 04:01 , Processed in 0.458708 second(s), 52 queries .

回顶部