图像显示

来源:互联网 发布:淘宝极速退款的条件 编辑:程序博客网 时间:2024/04/30 02:48
VC学习笔记:图像显示


VC学习笔记:图像显示


 SkySeraph OCT.30th 2010  HQU


Email-zgzhaobo@gmail.com  QQ-452728574


Latest Modified Date:OCT.30th 2010 HQU


原理方法


显示资源中的图片
(1)从资源中装入位图


● 定义位图对象数据成员CBitmap m_Bitmap;


● 调用CBitmap成员函数LoadBitmap(),如m_Bitmap.LoadBitmap(IDB_BITMAP1);


● 传入LoadBitmap的参数是位图在图形编辑器中生成或从位图文件中引入时赋予的识别符。


(2)生成与位图相联系的内存设备情境对象


CDC MemDC;


MemDC.CreateCompatibleDC(NULL);


MemDC.SelectObject(&m_Bitmap);


(3)显示位图


CClientDC ClientDC(this);


BITMAP BM;


m_Bitmap.GetObject(sizeof(BM),&BM);


ClientDC.BitBlt ( X,Y, //目标设备逻辑横、纵坐标


BM.bmWidth, BM.bmHeight, //显示位图的像素宽、高度


&MemDC, //待显示位图数据的设备情境对象


0,0, //源数据中的横、纵坐标


SRCCOPY); //位操作方式


特点:这种方法显示位图速度快,但不是很灵活,而且会使可执行文件增大。


 


显示磁盘中的图片
步骤:


HBITMAP *hBitmap; //定义位图对象句柄


BITMAP BM;


CDC MemDC;


CClientDC ClientDC(this);


MemDC.CreateCompatibleDC(&ClientDC);


hBitmap=(HBITMAP*):: LoadImage ( AfxGetInstanceHandle(), //取得应用程序句柄


“demo1.bmp”, //位图文件名


IMAGE_BITMAP, //类型为Windows位图


0,0, LR_LOADFROMFILE); //从文件中取位图数据


MemDC.SelectObject(hBitmap);


:: GetObject(hBitmap,sizeof(BM),&BM);


ClientDC.BitBlt(……) //使用格式与方法一同


特点:这种方法显示位图速度较之前一种慢了一点,但其灵活性较大,可以任意变换位图文件,而无需重新编译源程序, 也减小了可执行文件的大小。


 


 


程序模板


显示资源中的图片/在设备上下文中绘制图像[1]
法一


void COutputBmpView::OnDraw(CDC* pDC)


{


COutputBmpDoc* pDoc = GetDocument();


ASSERT_VALID(pDoc);


CDC memDC;//定义一个设备上下文


memDC.CreateCompatibleDC(pDC);//获取兼容的设备上下文


CBitmap bmp;


bmp.LoadBitmap(IDB_BKBITMAP);


memDC.SelectObject(&bmp);//选中位图对象


pDC->BitBlt(30,20,180,180,&memDC,1,1,SRCCOPY);//绘制位图


CRect rc(30,20,210,200);


CBrush brush(RGB(0,0,0));


pDC->FrameRect(rc,&brush);//绘制矩形边框


rc.OffsetRect(220,0);//移动区域


BITMAP BitInfo;


bmp.GetBitmap(&BitInfo);


int x = BitInfo.bmWidth;


int y = BitInfo.bmHeight;


pDC->StretchBlt(rc.left,rc.top,rc.Width(),rc.Height(),&memDC,0,0,x,y,SRCCOPY);//绘制位图


pDC->FrameRect(rc,&brush);


brush.DeleteObject();


memDC.DeleteDC();//释放设备上下文


bmp.DeleteObject();//释放文图对象


}


 


在磁盘中加载图像到窗口中[1]
CLoadBmpView::CLoadBmpView()//构造函数中


{


m_hBmp = LoadImage(NULL,"Demo.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);//加载位图


}


void CLoadBmpView::OnDraw(CDC* pDC)


{


CLoadBmpDoc* pDoc = GetDocument();


ASSERT_VALID(pDoc);


CBitmap bmp;


bmp.Attach(m_hBmp);//将位图关联到位图句柄上


CDC memDC;


memDC.CreateCompatibleDC(pDC);//创建兼容的设备上下文


memDC.SelectObject(&bmp);//选中位图对象


BITMAP BitInfo;                                                                        //定义位图结构


bmp.GetBitmap(&BitInfo);                                                                //获取位图信息


int x = BitInfo.bmWidth;                                                                //获取位图宽度


int y = BitInfo.bmHeight;                                                                //获取位图高度


pDC->BitBlt(0,0,x,y,&memDC,0,0,SRCCOPY);//向窗口中绘制位图


bmp.Detach();//分离位图句柄


memDC.DeleteDC();//释放设备上下文


}


根据位图数据直接绘图[1]
char *m_pBmpData;//①在视图类中定义一个缓冲区


COutputStreamView::COutputStreamView()//②构造函数中读取文件到数据流中


{


CFile file;//定义文件对象


file.Open("bk.bmp",CFile::modeReadWrite);


int len = file.GetLength();


file.Seek(14,CFile::begin);        //*过位图文件头


m_pBmpData = new char[len-14];//为缓冲区分配空间


file.Read(m_pBmpData,len-14);//读取文件数据到缓冲区


file.Close();


}


COutputStreamView::~COutputStreamView()//③析构函数中释放缓冲区


{


delete [] m_pBmpData;


}


void COutputStreamView::OutputStream(char *pStream)//④添加的成员函数,用来根据数据流输出图像


{


char *pHeader =pStream ;//定义临时缓冲区


BITMAPINFO BitInfo;


memset(&BitInfo,0,sizeof(BITMAPINFO));//初始化位图信息对象


memcpy(&BitInfo,pHeader,sizeof(BITMAPINFO));//为位图信息对象赋值


int x = BitInfo.bmiHeader.biWidth;


int y = BitInfo.bmiHeader.biHeight;


pHeader+=40;//指向位图数据


StretchDIBits(GetDC()->m_hDC,0,0,x,y,0,0,x,y,pHeader,&BitInfo,DIB_RGB_COLORS,SRCCOPY);


}


void COutputStreamView::OnDraw(CDC* pDC)//⑥绘制图像


{


COutputStreamDoc* pDoc = GetDocument();


ASSERT_VALID(pDoc);


OutputStream(m_pBmpData);//输出位图


}


 


显示JPEG图像[1]
①向视图类添加成员变量


IStream *m_pStream;                                        //定义流对象


IPicture *m_pPicture;                                //定义接口对象


OLE_XSIZE_HIMETRIC m_JPGWidth;                //图像宽度


OLE_YSIZE_HIMETRIC m_JPGHeight;                //图像高度


HGLOBAL hMem;                                                //堆句柄


CShowJPEGView::CShowJPEGView()//②构造函数:从磁盘中加载IPEG位图到流中


{


CFile file;


file.Open("angell.jpg",CFile::modeReadWrite);


DWORD len = file.GetLength();


hMem = GlobalAlloc(GMEM_MOVEABLE,len);//在堆中分配内存


LPVOID pData = NULL; //定义一个指针对象


pData = GlobalLock(hMem);//锁定内存区域


file.ReadHuge(pData,len);//读取图像数据到堆中


file.Close();//


GlobalUnlock(hMem);//解除对堆得锁定


CreateStreamOnHGlobal(hMem,TRUE,&m_pStream);//在堆中创建流


OleLoadPicture(m_pStream,len,TRUE,IID_IPicture,(LPVOID*)&m_pPicture);//加载图像


m_pPicture->get_Height(&m_JPGHeight);//获取图像高度


m_pPicture->get_Width(&m_JPGWidth);


}


void CShowJPEGView::OnDraw(CDC* pDC)//③绘制JPEG图像


{


CShowJPEGDoc* pDoc = GetDocument();


ASSERT_VALID(pDoc);


m_pPicture->Render(pDC->m_hDC,0,0,(int)(m_JPGWidth/26.45),(int)(m_JPGHeight/26.45)


              ,0,m_JPGHeight,m_JPGWidth,-m_JPGHeight,NULL);        //绘制JPEG图像


}


 


相关说明


位图文件最大的缺点


压缩比较小,占用空间大,因此网页等均采用IPEG或GIF格式显示


VC中显示JPEG图像方法


通过流操作来实现。具体思路:将JPEG文件加载到堆中,然后在堆中创建一个数据流,接着调用OleLoadPicture函数加载流中的数据到IPictrue接口中,最后调用IPicture接口中 的Render方法输出图像信息。


 


Author:         SKySeraph


Email/GTalk: zgzhaobo@gmail.com    QQ:452728574


From:         http://www.cnblogs.com/skyseraph/
0 0