利用位图实现大数据量绘图的快速显示

更新时间:2023-08-14 08:49:01 阅读量: IT计算机 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

位图 矢量图 计算机图像

GRAP秘萋

淹秘甩经营实默数据薰绘雷的快速显示

未黎黧麓嚣黧警

,?i萋≤器i

。繁曩I!i“

簿曩擘。

f。

牵目

摘要本文利用自绘位图实现大数据量计算绘图的快速显示、保存与打印,尤其对绘制灰度和伪彩色图像的显示、保存和打

印有重要意义。

关键词

自绘位图,大数据量计算绘图,显示,保存,打印,灰度图像,伪彩色图像

int

m』eight://位图高度

一、刖昌

在Vc++编程时,对于绘制矢量图来说,只须在视类的onDraw()函数中编制绘图代码就能够轻松地显示,而不用编写任何打印程序就能利用Vc自带的文档一视结构中的缺省打印功能打印矢量图。这对于大多数绘制不需实时计算而且计算量不大的矢量图来说是没有问题的,但是当我们绘图时,如果所绘的图形需要实时计算,并且计算量很大,图形超过视图区,我们需要拖动滑块移动图像浏览时,问题就会显现出来了。尤其是绘制灰度和伪彩色图像,它们由于需要逐点计算各像素点的灰度值,计算量大,又由于VC自身的绘图机制的原因,拖动视图滑块时,程序又要调用OnD残哪()把图像重新绘制一遍,这不仅显示慢,而且打印机也不支持用setPixelV()函数写点在0nDr洲()函数中绘制的灰度和伪彩色图像的打印。

下面介绍一种在拖动滑块时能够快速显示、保存和打印灰度和伪彩色图像等大数据量计算的方法,它的原理是,从位图中用GetDc()得到设备环境指针,再利用SetPixelV()函数绘制灰度和伪彩色图像,这样灰度和伪彩色图像就被绘制到内存设备环境中,然后把位图粘贴到视图区就可显示位图,或把位图转移到打印机设备环境就可实现位图的打印。

DriVate:

CDCdcScreen://屏幕设备环境CDCdcMem://位图内存设备环境CSizebitmapSize://位图大小

2)为该类添加voidcreateBitm印Ex(csizesize)公有成员函数。函数主要代码为:

bitmaDSIze=引ze:

dcScreen.Attach(::GetDC(NULL))://把桌面的一个设备环境封装到CDC类的一个实例中

dcMem.CreateCom∞t.bIeDC(&dcScreen}://用桌面特征初始化内存设备环境

CreateCompatjbJeBjtmap(&dcScreen,sjze.cx,size.cy):

//创建空位图

dcMem.SeIectObject(this):

3)为该类添加CDC。GetDC()公有成员函数,用来返回内存指针供绘图之用。主要代码:

retum&dcMem;

4)为该类添加voidPrepareBitmap()公有成员函数,用来保存系统调色板到位图调色板,删除和释放设备环境。在绘图后立即调用。主要代码为:

int

nCoIors=(1<<(dcScreen.GetDeviceCaps(BITSPlXEL)冰

dcScreen.GetDeviceCaps(PLANES))):

LOGPALETTE术pLogPaI=(LOGPALETTE术)newBYTE【sizeof(LOGPALETTE)+InColors木sizeof(PALETTEENTRY))l:

pLOgPaJ一>paJVersiOn=Ox300;

二、实现

1.利用MFc完成基本应用程序框架,采用多文档滚动视图结构,程序名任取。程序能够自己读绘制图像时的数据文件,数据部分放在文档中,以便绘图时调用。

2.用MFc向导添加一个从cbitmap类继承的新类cwzd—Bitm印类,头文件名和执行文件名为wzdbtm印.h和

Wzdbtm印.cpp。

pLogPaI一>paINumEntries=nCoIors:

::GetSvstemPaIetteEntries(dcScreen.m-hDC,0.nCoIors,(LPPALETTEENTRY)(pLogPaI一>paIPaIEntry)):mpF)aJette=newCPaJette:

mj)Palette一>CreatePaIette(pLogPa”:delete【lpLogPal:

//删除和释放设备环境

dcMem.DeleteDC():

::ReIeaseDC(NULL,dcScreen.Detach()):mWidth=bitmapSize.cx:m—Hejght=bjtmapSjze.cy:

1)该类添加以下成员变量:

Public:

5)为该类添加HANDLECreateDIB(int

pbmData)公有成

CRectm上itRect:

//用来保存位图大小范围

CPaIette¥m-pPaIette://保存位图调色板intm—WIdth://位图宽度

员函数,用来生成DIB位图,返回DIB句柄。主要代码如下:

//create‘Dl

Bheaderfrom

our

BITMAPheader

BlTMAPlNFOHEADERbi:

万方数据 

位图 矢量图 计算机图像

1i,。|。i、.,。≯j。

:襄薷囊。蠢麓麓4繁”’譬

强一.皤鬏ApHl£S

!”?

。:’。“’i譬弼

i,Il

≠、F

-㈡

i。“匿黪臻辍

//returnhandIetOtheDlB

return

G疑APHlCS

她7箍

7一

memset(&bi,O,sizeof(bi)):

bi.biSize=sizeof(BITMAPINFOHEADER):bi.biPlanes=1:

bi.biComDression=BLRGB:

//qetandstOredimensiOnsofbitmapBITMAPbm:

GetObiect(sizeof(bm),(LPSTR)&bm):

hDIB:

6)给该类添加void蹦nt(cDc。pDc)公有成员函数,用来

实现位图到打印机的打印。主要代码为:

.ntbmData:

//pDC为打印机设备环境指针

HANDLEhDIB=CreateDlB(&bmData):

//get

bi.biWidth=bm.bmWidth:

bi.biHeight=bm.bmHeight;

//getnumberOfbitsrequiredperpi×el

intbits=bm.bmPlanes¥bm.bmBitsPjxeI:_f(bits<=1)bi.biB.tCount=1:else.f(bits<兰4)bi.b_B_tCount=4:else-f(b.ts<=8)bi.biBitCount=8:

eJse

memOrypointerstOtheDlB’sheaderanddatabits

LPBn。MAPlNFOHEADERIDDlBHdr=APlNFOHEADER)::

GIobalLock(hDIB):

LPSTRfpDIBBjts=《LPSTR)lpDIBHdr+bmData:DDC一>SetStretchBItMode(COLORONCOLOR):CRect

rect《0,O,m—yVidth,m—Height):

DDC一>DPtoLP(&rect):

::StretchDIBits(pDC一>m-hDC,

//打印机设备环境

0,O,mjitRect.Width(),一m_BjtRect.Height(),//此

//

source

处用用逻辑坐标

0,O,m—j~idth,mj_{eight,

sions(useaIlofbitmap)(LPBITMAPINFO)IpDIBHdr.

bitmap

dimen

bi.biBitCount=24://caIculatecoIorint

tabIesize

lpDIBBits,//bitmappicturedata

//bitmapheaderinfo

DlB』GB』OLORS,//specifycoIortabIehasRGBVafues

SRCCOPY//sirnpIesourcetodestinationcOpy

):

biColorSize=0:

.f(bi.biBitCount!=24)biCoIorSize=(1<<bi.biBjtCount):

bjCoIorSize木=sizeof(RGBQUAD):

//calculateDicturedata

size

bi.biSizeImage=(DWORD).bm.bmWidth

bi.biBitCount://bitsperrOw

bi.biSizeImage=(((bi.biSizeImage)

+31)/32)

//cIeanuD

::GlobaIUnlock(hDIB):

4://DWORD

aligned

::GfobalFree(hDlB):

retum:

bi.biSizeImage水=bm.bmHeight://bytesrequiredfor

whOIebitmaD

//retumsizetOcafer{ncasetheVwanttOsavetOfiIe

.f(pbmD8ta)

7)最后为该类添加voidsaveBitmap(cstringsFile)公共成员函数,用来保存位图。

实现代码主要为:

//create

int

DbmData=bibiSize+biCoIOrSize:

cOIOr

DIBbjtmaD

////getDIBc0IortabIeandpicturedata

//a|JOcateahunkOfmemOrVtOhOIdheader,

tabIeandDicturedata

HANDLE

bmData:

hDIB=CreateDlB(&bmData):

memOrypOintertOit

HANDLE//getLPBYTE

hDIB=::GlobafA||oc(GHND.bi.biSize+bi-memOrypOintertOthishunkbyIOcking.t

LPBlTMAPlNFOHEADERfDbi=

headerstructureintOhunk

ColorSjze+bi.biSizeImage):

//get

IpBitmap=(LPBYTE)::GIobalLock(hDlB);

intbmSjze=::GlobaISize(hDlB):

//createfile

CFi{ef¨e:

flIe.Open(sFi『e,CFi|e::modeCreateCFife::modeWrite)://writethebItmaDheaderBITMAPFILEHEADERbmfh:

(LPBITMAPINFOHEADER)::GIobaILock(hDIB):

//cOpy

Our

¥Ipbi=bi:

//get

deviceCOntextandselectCDCdc:

Our

bitmap

paIetteintoit

bmfh.bfTYpe=’MB7://(actuaIIy7BM’forbItmap)

bmfh.bfSize=sizeof(BITMAPFlLEHEADER)+bmSize:bmfh.bfReservedl=O:bmfh.bfReserved2=O:bmfh.bfoffBits=bmData:

dc.Attach(::GetDC(NULL)):

CPalette水pPal=dc.Se|ectPaIette(mJ3PaIette,FALSE):

dc.RealizePaIette():

//Ioad

Oicturedata

our

memorvhunkwjththecoIortableand

fiIe.Write(&bmfh,sizeof(BfTMAPFJLEHEADER)):

//writethebitmapbOdV

::GetDlBjts(dc.m_hDC,(HBITMAP)m_hObject,O,

f¨e.Write(IpBitmap,bmSize):

//cleanuD

(UINT)bi.biHeight,(LPSTR)Ipbi+(WORD)lpbi一>biSize+biColorSize,(LPBITMAPINFO)Ipbi,DIB上GB』OLORS):

//clean

uD

俐e.CIose():

GJobaIUnIock(hD旧):GIobalFree(hDIB):

::GlobaIUnlock(hDIB):、

dc.SelectPaIette(pPaI。FALSE):dc.ReaIizePaIette():

3.在视图中实现绘图,为视类添加一个cwzdBitm印类型

万方数据 

爹奠粤警篓囊攀碧粤蹲势、{黼豢囊鬟i

位图 矢量图 计算机图像

二磐÷≮。,;,。≯i≥。≯、’‘争∥臻囊镒誉警整纂_

霎酩躅像囊蛩翟;

”.,

一.:■

、,

,,S

-r

r、+‘。ph、~

‘jj!+~二…….÷:i、“。x_:。

_

G疑Ap娃ieS虿I:

¨.

G辍ApHlCS

的成员变量bb,在0nDmw()中实现绘图。主要代码为:

pDC一>SetMapMode(MM上OMETRIC):

CRectrectl:

BEGIN—MESSAGE—MAP(CRadarVlew,CScro||View)

//设置映射模式

//ffAF)<—MSG—MAP(CRadarVjew)

ON上OMMAND《lD-FILE-PRINT.OnF¨e刚nt)ON工OMMAND(1D.FILE_PRlNT—PREVIEW,

view)

rectl=bb.m上itRect;

pDC一>LPtoDP(&rectl):

CSizesize(rectl.Width(),一rectl.Height()):

On剐e刚ntPre—

州m』BjtmapIsNone==true)//如果位图未创建则创建位图

//))AFX_MSG』AP

//Standardprintingcommands

//ONjOMMAND(1D-FILE_PRINT,CScro||View::0n—

Fi|ePrint)

//创建空位图

bb.CreateBitmapE×(size)://仓l建位图

CBrushbrush:

brush.CreateSoIidBrush(m—BkColor):

bb

ON』OMMAND(ID_FlLE_PRINT上lRECT,CSc删View::On一

剐ePrjnt)

GetDC()一>F…Rect(CRect(0,0.size.c×,

//ON』OMMAND(ID_FILE_PRINT.PREVlEW,

1Vlew::OnFilePrintPreview)

CScro|.

size.cy),&brush)://为位图//设置背景

bb.GetDC()一>SetMapMode(MM-LOMETRJC):CPenPen(NULL1,m—yvaveCoJor):bb.GetDC()一>SelectObiect(&Pen):

END—MESSAGE—MAP()

填充0nFile蹦nt()和OnFile蹦ntPrevjew()函数以实现打印

预览和打印:

vojdCRadarVjew::OnFjIePrjntf){

CScro||View::OnFi|ePrint():

voidCRadarView::OnFiIePrintPreview(){

CScro||View::OnFiIePr.ntPreview():

//自画位图

switch(m_para.m_page4.m』ispIaySefect)

case

0:

1:2:

ShowWave(bb.GetDC()):break;//画波形图

casecase

ShowGrav(bb.GetDC()):break://画画灰度图

ShowColor(bb.GetDC()):break://画伪彩色图

重载0n蹦nt()函数实现位图的打印:

vojdCRadarVjew::OnPr|nt{CDC丰pDC,CPrintInfo爿=pInfo)

.f(!m上BitmaplsNone)

pDC一>SetMapMode(MM_LOMETRIC):

bb.Print(pDC):

bb.PrepareBitmap():

m_bBitmapIsNone=faIse://位图完成则不再创建

//设置打印机设备环境的映射模式

CScro|IVIew::OnPrint(pDC.pInfo):)

//粘贴位图到视图区

CDCdcComp:

dcComp.CreateCompatibleDC(pDC);

dcComp.SeIectObject(&bb):

//drawbitmaD

pDC一>DPtoLP(&rect2):

CRectrect2(O.O.bb.m—yv{dth.bb.m』eight):

这样,整个功能就基本实现了。大家在运行应用程序的时候就会发现,位图绘制时会稍微用一点时间,这个时间跟直接在0nDraw()下初始绘图的时间是几乎一样的。但是,当我们拖动滑块时,我们会发现,图像就象在平滑移动,丝毫没有滞留不动

0n—

pDC一>StretchBIt(O,0,rect2.Widthf).rect2.Height(),&

dcCOmp,

0,0,size.cx,size.cv,SRCCOPY):

4.实现图像的保存。在视图类中添加成员函数voidlmagesave()用来保存图像。代码为:

CStrinqSaveF¨e:

CfiIeDiaIog

0FN

的感觉,更不会有在onDraw()下绘图时重新绘制的现象,预览速度和打印速度也比直接利用0nDmw()的设备环境绘图要快得多,这是因为图像已经在位图中绘制好了的缘故。

dIg(faIse.“}”,”m.bmp。.

OFNOVERWRlTEPROMPT,”

data

HIDEREADONLY

三、结论

本方法利用位图设备环境,能在位图中自由绘制自己的图像,尤其是大数据量的计算绘图,在拖动时能快速地实现显示、预览和打印,特别解决了利用setPixelV()函数绘制的灰度和伪彩色图像的保存和打印(这在onDraw()下直接绘制并利用缺省打印是不能实现的)问题。

(收稿日期:2004年4月25日)

FiIes({.bmp)I{.bmpII。):

if(!m—bBitmapIsNone){}f(dIg.DoModaI()==IDOK)f

SaveFiIe=dlg.GetPathName():

bb

SaveBhmap(SaveF¨e);

5.在视图中实现打印。在视类执行文件中注释掉缺省的ID-FILE_PRINT和ID-FILE』RINTjREVIEw命令处理函数并使用CIasswizard来添加自己的命令处理函数。

2004.6

技鹰与肇护≯‰曛万方数据 

;:蠢冀差辫{氅繁警蒜霾毯笺缀帮

位图 矢量图 计算机图像

利用位图实现大数据量绘图的快速显示

作者:作者单位:刊名:英文刊名:年,卷(期):被引用次数:

李月

电脑编程技巧与维护

COMPUTER PROGRAMMING SKILLS & MAINTENANCE2004,(6)0次

相似文献(1条)

1.期刊论文 黄伟 在VC++6.0应用程序中利用位图实现大数据量计算绘图的快速显示、保存与打印 -电脑编程技巧与维护2002(3)

本文利用自绘位图实现大数据量计算绘图的快速显示、保存与打印,尤其对绘制灰度和伪彩色图像的显示、保存和打印有重要意义.

本文链接:/Periodical_dnbcjqywh200406026.aspx

授权使用:广东工业大学图书馆(gdgydxtsg),授权号:537a517c-3d19-4b3c-9d85-9ebc0149576a

下载时间:2011年4月5日

本文来源:https://www.bwwdw.com/article/w7dj.html

Top