QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

1 v, D" K) L0 e ?/ W) K

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

$ ]0 n3 ?) C! F. M( P- w

张义云

) b! ]) S1 d; V' B

8 u6 N- b: x; G( }

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

1 N O& X9 g8 _( |* |* ]

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

V5 |( |. h6 n" N2 E; S3 V& x

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

4 z" P% b6 O6 d/ m, c! H

! ~, G1 F+ a" o1 K, x7 K

---- 一、BMP文件结构

% x; Z* ?7 O$ T1 [5 A7 H N

+ B4 s- x, K- x5 w$ ?

---- 1. BMP文件组成

9 [' a3 F0 P) |5 d0 z! y

* U6 Z7 j: b# _ O6 G4 s0 O; q0 c

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

3 ~# Y6 s2 z" @

$ ?" S3 L9 @" S! ~

---- 2. BMP文件头

$ D# C9 Z& G( t( s4 o

6 R& r5 d1 D# B- W0 q; h) S7 ^/ g

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

. A M+ r- a; o) e" v8 `7 J: U

7 Q; x- R( D, g6 `: \4 P

- A F# {4 m5 k; l

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

2 g" h0 b& N" J4 l- Z) B0 m( d

1 o3 f; B2 u {

typedef struct tagBITMAPFILEHEADER

& v9 n. s: r- u( g+ F2 {; f

{

3 k) c3 Q0 d4 B! y+ e" m o: p

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

; t/ ^9 |2 [# _3 ]

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

% k; W8 M9 h9 J' t2 l6 Z4 c3 O

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

7 M% F+ Y) l% H6 ~; M

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

3 C7 H/ M+ M: \" W0 z2 W

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

. ]9 O# s" W/ z; B, W: U

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

* C, A) V* O& u9 e S

} BITMAPFILEHEADER;

* Y+ Q, ~2 s8 ?

3 D! m4 N2 j8 N# t+ [/ U$ g

2 S/ i/ s; K* j" ]4 l

---- 3. 位图信息头

! K* a5 r# s& `6 W

----

' b1 C( [ j4 S- w

* U. c2 { @0 N3 p7 W1 g

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

% I* J. l3 d% Q

typedef struct tagBITMAPINFOHEADER{

4 |/ @$ j( @! V. Z

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

+ k! [6 P1 L, f

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

/ R/ E: M. T7 S0 @, b

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

0 C) d T, Q J' r4 x1 g

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

( m/ i+ D3 {3 X* W

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

) L; P. [* E; S& `$ ?

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

0 e0 l7 C% r7 P% ^: W( k, x

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

8 ^3 H3 `1 n( C( K6 Y

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

& |* W1 T0 G+ P3 p# [

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

* J2 j7 ?1 n! P/ ?" Y) n

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

1 u M; Q& V6 V) O O$ w- S" h$ Q

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

7 v% y% K* h/ a, S- L) z0 _: t9 H" u

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

0 b! H9 Z/ M8 k4 t$ N; F9 r5 ?$ `4 l

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

: z, p4 Z5 f, K7 o# E# F+ L

} BITMAPINFOHEADER;

: j6 y/ l( ^4 [

1 ?3 W2 k; L" _, `7 R. s2 A

% \1 v2 T+ x! J, [3 g8 }

---- 4. 颜色表

# p9 p0 y! |# T) n

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

0 B. \1 ~9 `8 e$ ^

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

2 M/ y6 n( D# S( N; @9 u1 m- R0 e

6 _, n, w+ v5 b% N

typedef struct tagRGBQUAD {

! }0 c2 e1 }9 o5 S1 d7 T

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

+ p& i# v3 Z, u2 m/ e7 M

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

5 M& e. a& P6 D5 T3 l$ _3 p% B. B

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

% o4 h. e$ P' W% S, I% t' }! y5 d

BYTErgbReserved;// 保留,必须为0

9 |3 t& D6 P' }! w# e

} RGBQUAD;

% N* K( n6 Y7 t3 c1 y! P

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

8 O* Z( d1 r; f d( M8 O9 {! R+ Y

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

/ l" ?8 w2 Z0 Z0 a1 }4 E+ J% P

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

6 i4 L5 M1 K/ ` c1 l l% C* z

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

$ i! o! X# l6 a$ J! i: N, P

typedef struct tagBITMAPINFO {

/ j+ |$ c! q% y

BITMAPINFOHEADER bmiHeader; // 位图信息头

1 S o8 _# \6 Y/ P2 W2 `

RGBQUAD bmiColors[1]; // 颜色表

6 {: G9 |5 D a4 d% \7 y7 v6 H+ n

} BITMAPINFO;

& M% V2 X5 h7 q/ R$ b% w% ^

/ }9 O B2 o8 i

]$ F) ]7 l# J4 g4 n$ f" T

; c0 m% D* h+ k+ R/ K

---- 5. 位图数据

6 E' k0 A5 q2 q* Z% s" R

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

9 Q0 T- h0 v0 }

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

9 W! m3 Z# C. C3 N0 U7 J4 X5 K

: M7 c0 O; R3 E" x$ a D% {8 |

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

9 H0 m5 U6 E+ O. u: [0 S% e6 q

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

8 G8 C7 J1 y& n9 K% G2 w0 e! `

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

. V! ?) A; S# ]) J

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

# T& r7 o! ? ^9 Q, ?: N5 V

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

" ]: \$ Y. F5 D/ T* Z$ R

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

$ @& }2 J% R( y7 w$ s$ Z. @

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

! e+ b; v, _3 M& O2 r# E1 e

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

2 e D% y Q9 u# x5 {7 p% g6 |

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

6 v$ s* t6 b4 e) ^2 p! g( P

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

8 C) V+ H0 u6 y/ a3 `# e, L, T' z

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

3 J/ z2 H* B5 T5 [0 |

DataSize= DataSizePerLine* biHeight;

" n4 R7 U; V' ^7 t4 `

2 g* E% p+ F; P; R" T

. }& [* S! h. ~( p1 j% w3 E3 Z

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

7 b, C+ V+ Q3 b2 r( k4 @# V

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

3 N3 I, O/ ~# Q% R! \9 Q1 ~4 i% c8 h

3 [1 l) K4 V# x5 l, H

---- GlobalAlloc(GHND,FileLength);

2 m3 i0 T ^+ D) f

' h$ T* F* @% S/ l; R

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

3 s3 E( k) z8 P; d7 }

" T$ E" g- u- s6 M6 x/ e4 Q$ p

---- LoadFileToMemory( mpBitsSrc,mFileName);

0 d, C; E3 e6 z( q

" S2 Y9 Q% M6 ^9 i% g

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

* ]% F$ w+ f6 @' ?7 M

% y, q0 b1 g5 r; Q* R

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

) B/ z" |( {5 |7 c3 k3 _ p' B

DC,

& J% p2 W0 ?+ \' U

1 b: O6 a4 j8 k6 W& y

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

# H) `* a+ k) M4 ]' A4 j

/ b& F5 c0 ?5 }& j9 p: ?

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

8 I, L; y8 ?5 H

6 z6 U& p; J1 Y0 U% S* d

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

) [4 A# s9 D6 M

9 O4 U2 y8 ~/ z6 s* o# K9 @. P

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

1 L a! H @% K m. R) v

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

& _3 G) y- l# |& w1 c) ^7 K. _6 Z" x

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

6 z* J+ Z7 s+ r$ a5 T

* f6 i5 W/ v. {, l" {5 f% l

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

& [1 Y/ Z/ V6 e* s5 k3 Y

* L% ?& b% S4 |0 Q

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

2 Y3 p9 I2 ?+ @; ]1 t. a

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

8 g' D P* V' K

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

0 Y3 L" s/ k- ^7 X* s! Y2 E" R

+ S0 R; }8 F- G' o: [; ~ @/ N( j

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

9 Y ]% h1 ?$ t3 H a: g

+ e' K% F! N: F2 M2 j6 f3 H2 k+ d1 F, `

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

# v1 r- M: {* }. b1 Y

7 ?% P* z' t1 M; _% t4 f! b0 s

---- GlobalAlloc(GHND,FileLength);

) w# Z0 m- T6 n( C& ?1 F' W

/ \/ u; a( _& E' ` |9 f+ w

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

x8 b8 | D$ q3 x

. ^) T& m. y" V$ X8 v9 G+ W$ G& U/ M

---- LoadFileToMemory( mpBitsSrc,mFileName);

5 d# u; G% U. r

2 [2 _5 T3 ]# u$ w

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

2 G7 |9 V" ?+ u5 H# I, E6 Q! B

" c$ d" P6 Z _0 P. [! r

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

8 F! d& T5 [. w0 G) D

' ?3 b, f0 x3 r3 C7 y/ R% ~% e. [9 v

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

7 i9 D; Y7 A7 m+ r5 k

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

# c; `- h F- o+ b1 [1 Q' j: s! N7 X

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

/ s# q1 u1 Z7 u/ F% I. t7 S% q

) L2 u7 ]. ?& {& q3 x5 }

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

2 X9 c# X7 S0 v) N

* u8 e; S1 O" M' L

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

3 Q, a2 D4 [, ? o

+ ~% t9 S- r* c0 F. T5 B

HDRAWDIB m_hDrawDib; // 视频函数

* Q+ ?' |$ R5 Q

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

9 }. x+ k) m: Y; |# R- W

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

8 D9 d( I9 U' G4 L, H7 \

BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头

]/ u. m& L) [( w9 l- q! D3 ^9 l

6 w8 a# ^3 k( [

$ W' c; B$ c# |5 V2 f

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

; p6 T0 i7 A- y, t

---- m_hDrawDib= DrawDibOpen();

2 H2 U% }7 a8 a: Y3 W: d1 x

- |2 W# ^7 r: s

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

9 c. ?+ {) A( d4 t% O$ k6 m

2 }; V" L4 ?" g @

if( m_hDrawDib != NULL)

' ?6 {, u+ d" q$ Y7 e$ L

{

! v; @) z" A B

DrawDibClose( m_hDrawDib);

: |- E1 X4 J8 ^: q) i4 B1 ]; \1 R

m_hDrawDib = NULL;

( R1 [& L6 F/ N) m' \

}

N1 R8 I5 y/ U& t" B: E) y- _3 E

, j1 b% F$ ]4 f% S

* u% I1 [$ t5 L! M6 x' n8 K, f: z; z

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

2 N$ S# T+ y, S ^

voidCViewBitmap::OnPaint()

' L2 n V. a% j. y

{

! V; R; M' r+ v9 `1 c

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

- P" l1 O* p: a4 T) x: O. C

GraphicDraw( );

3 \, T: T2 q8 s; S* l( l2 b

}

6 E( j+ J+ T7 E+ ?/ c

3 a$ Z# W' U5 I) ]$ p* M: ?1 Y

voidCViewBitmap::GraphicDraw( void )

1 V5 d1 U6 P* Q' h: G

{

4 [1 F* y% |6 N7 ]; i

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

( ?, L( o5 g9 M- R. e* b+ O, F

BITMAPFILEHEADER *pBitmapFileHeader;

+ o2 ^$ n- J& R ?

ULONG bfoffBits= 0;

( C. `: m$ X5 b5 K7 c& t

CPoint Wid;

6 Q$ j2 Q$ P, i& i/ F! h9 n6 k

2 J e4 B& U+ v1 e* v& D) N( t8 M1 Z

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

) e. |6 |3 r- D7 W

if( mBitmapFileType < ID_BITMAP_BMP ) return;

7 G2 ^! ?2 x- i' w

5 g3 c, G( E& m/ h$ `% W

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

# l3 Q' S K- o6 x* f

// 准备显示真彩位图

( m) [) e. H2 |' i

pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;

5 c! T& g) _0 F8 s* N6 n

bfoffBits= pBitmapFileHeader->bfOffBits;

8 n# L/ H2 \! {0 _+ l

7 y0 M. ]1 p% H0 R+ e

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

& y- {+ q8 E& j2 B8 d+ U* s& y' N

; A! z- z. ^5 _5 c/ U

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

8 J0 x( z8 N7 }; Z# }$ c

{

- y" l% @% x5 e' B Q

HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,

' U6 i# b; \" J+ ~5 Q* R0 w( t

mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,

% R, k: ]" h6 g1 X+ n# ~

(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);

& m/ B, Z i4 B( j

// 建立位图

( R/ C4 I# j6 K& }6 u

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

3 P8 N1 k) Z: k3 o( x

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

9 v7 v, Q2 {- w1 R

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

2 X; a/ t$ \8 c0 X# m, @7 n

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

$ G' T, [- U0 I# B

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

1 O+ [" ?; X4 T7 v' \- Z

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

( F y3 m# j- A3 y1 N2 a

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

. I o4 ?: q/ \) {9 g* `, v g( i* u

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

, |3 p3 g4 o$ V1 I( A( ?+ v$ h( Q& k

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

, A' R& `/ u) F k3 m5 k

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

9 H9 ]0 F$ Z3 @3 S9 i

* `# D7 r" @- H# e: P" J* o( r1 I

if( mFullViewTog == 0)

$ H' t2 k" {4 f! ]7 }

{

. m* u- o" L: d: \- @; F# ?- E6 F; z

// 显示真彩位图

# N; T5 c( a$ [$ W2 _7 y

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

, y" B( l8 |: L+ h. m

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

+ J7 a7 s( q2 d, E; a

} else {

% A' ~4 Q l+ n

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

4 @& F% J% X, R5 T4 \' K# Q

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

% X% X& ]* e4 a# P- ^

>biHeight, SRCCOPY);

2 l" w5 [. L; c) s, f1 ~* v

}

2 Y3 W+ C3 w& H8 B

// 结束显示真彩位图

3 ]6 p) q5 S( ?" ^% N! _+ Z

:eleteObject(SelectObject(hMemDC,hBitmapOld));

! L4 A6 k" C6 t8 L3 l

// 删 除 位 图

: J A2 w. l3 Q6 @

} else {

* S# H5 J; e0 `/ |4 J

3 W6 y0 n+ A# N: F2 o" Z3 K& R

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

0 O9 t- e% X7 m5 ]

- e2 ?$ Y0 }) Y! n

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

9 I8 c1 t8 y/ u3 @

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

- ?( m& k' j" a, x2 m: r: H

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

0 Q ] ]! W2 X

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

% w% ?1 Q) n, B$ ~% R1 y/ C

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

% C K5 z) T. K. J

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

2 a& ^" m6 z" m4 c8 P- f$ R, R# g

/ T- a9 y# y+ H/ F6 c# R

// 显示真彩位图

4 {* R) k7 \2 L4 R: E

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

$ J: L \1 \4 x1 b8 L" p

; [% O3 G" x$ W" a0 b0 d. d( V

if( mFullViewTog == 0)

2 u* ?$ y7 t) n M n

{

$ s! O) |5 Y0 `0 A

Wid.x= mDispR.Width();

3 O1 m/ O; f1 j! `2 u

Wid.y= mDispR.Height();

+ A# X) W' c* B! @3 d

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

9 v5 u/ T: R: R& d* P3 y

if( Wid.x > mpBitmapInfo- >biWidth )

# b2 }- l: H A l" i" ^! E

Wid.x = mpBitmapInfo- >biWidth;

& k- P7 P: T4 D3 U* ^6 `! N7 L

if( Wid.y > mpBitmapInfo- >biHeight)

3 g( @2 D, Y% Z

Wid.y = mpBitmapInfo- >biHeight;

7 P6 h$ M" B: j8 x' ~' K2 _% p

2 C/ k: N/ K0 u- E0 P" P2 M1 Z+ P

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()

" r O2 V! ]0 G" O$ g \

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

; [4 h0 D0 d$ a5 P3 i

mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),

9 A; P1 `; n5 D* p) L: Q- }

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

+ u' p, P8 K: G/ ~9 X

} else {

8 }! a' H6 f. n5 v

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),

. i, E' e# a0 g- W8 Y8 v

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

6 _3 T" R( m: @9 X3 S6 n

mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),

; }( z+ S$ O# ?5 Z- X# Q | T7 O

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

- R% G9 L1 {( C& U8 C* U( w: J

DDF_BACKGROUNDPAL);

7 g& B/ Q& U* {: Q6 ^) A$ X

}

- n, v3 }5 }# [; O

}

9 o) D' C# J: W9 a. z" ?

return;

7 j8 d5 p1 _, l8 M4 Q7 R3 I# V K2 O+ n

}

0 q% L" Q1 f+ L1 Q, @; ^

$ ^ h) B+ y; m8 _

# q8 h! E& p5 D9 }" j( E+ U

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

6 z0 m( T- b# o9 @+ X/ d

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

3 e* t5 N7 _' y, A, G

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

`" n9 n l% V7 C0 d# z* T* d

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

7 E* I# [2 o2 @8 D$ B) I

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

% A1 Q& S h: I3 S* k1 E

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

# ^: M/ K4 K* j

5 {7 u4 t S% Y; L8 L4 W, x% V, n

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

' O0 P9 P& _4 c

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

& @* b' J! h& l! t- {* P. j* r3 c7 Q

6 A9 P3 _" A0 E1 c

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

7 ~" x/ s& T" ?. _

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

5 l' ]7 s# `# r8 t; m ^

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

. N+ A$ L5 ~( n" ~0 e0 T

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

+ c- t8 E [4 l

。代码如下:

( Y% [$ j& C: N3 K/ [9 ]- s# `+ T# g, V% S

# G$ C; v1 r F8 s, m4 E. M# r

void CMainFrame::OnViewBitmap()

; ]# F! q/ o, a* b) v# k& |

{

9 F" W5 S2 _) ~3 u) ]

// TOD Add your command handler code here

: k+ W% m0 l9 I) l6 c4 y

CViewBitmap *pViewBitmap= NULL;

0 b/ S8 N' r8 E

1 I1 z X. F+ }% N# r9 D

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

: k8 _5 Z& T1 N- U) e+ n+ y

pViewBitmap- >ShowWindow( TRUE);

6 ~9 ~- G- O) u2 R, M( X. Z

}

5 P4 H2 h3 i, E6 ~2 i* H7 P! C

* |6 K/ S+ c+ V l# l

8 Z* q& V! z9 }4 c& g

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

6 @" c! \$ j* R2 N

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

& W% Q" T/ ?( k# I4 _

, |+ {& ` j, r/ l+ {

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

2 b4 W) V8 s, X9 C- M2 t

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

- w6 u+ q& ~, a- v6 S9 |: v

, S' G T: \) M: m0 p& \- k7 L+ B

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

3 g8 o- V+ h$ H& i2 K6 I

; ]: Q/ M& @( U7 U8 j; C

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

' p; m# F- `0 F. I: Q i' N

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

" L/ ~8 X( ]3 f D

; h( o) ]2 X& L* u" a: A

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

& K# a `; \" Q

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

: E: S. c/ K% j( V/ d3 X' P" `4 B: P

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

9 m" {# U, I: G2 R' I) B4 Y9 K2 J

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

9 n' P+ n8 D: o. h3 J& Z. a) k

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

3 e( U$ \3 J0 E! p O

+ f6 ? H8 M) T, A( A1 P

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

$ U# R1 M% `) D5 E# d6 v

就可以显示该位图。

& W7 L r1 `( Q; n: c5 a

7 x( y2 z# o8 T6 h7 y# k8 @7 D/ A9 E

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

' M0 Q3 X4 D7 N: q# |4 c * e' {0 [8 a" p' u

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

) ]) g2 z0 K& R- y

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

E7 ?8 \& e! Y9 i; }4 O

真小,显示速度快。

! Y2 T# z& G; b$ X& A2 `

1 P$ h) S6 r" x! ^; u

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

+ {7 T$ T- U2 L6 h9 ]2 F- y

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

. u3 u9 G* H* q- b: q

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

: s% f# j. J8 s9 _& \/ o

) B3 E2 m& S; L6 [% C& d+ V

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

, Z* f! P/ c, 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-8-25 12:58 , Processed in 0.380029 second(s), 52 queries .

回顶部