如何把位图拷贝到剪贴板中

来源:互联网 发布:人教版课本同步软件 编辑:程序博客网 时间:2024/05/02 01:09

DDB与DIB的区别

DDB(设备相关位图)

DDB依赖于具体设备:
DDB的颜色模式必需与输出设备相一致。例如,如果当前的显示设备是256色模式,那么DDB必然也是256色的。
在256色以下的位图中存储的像素值是系统调色板的索引,其颜色依赖于系统调色板。
由于DDB高度依赖输出设备,所以DDB只能存在于内存中,它要么在视频内存中,要么在系统内存中

DIB的与设备无关性主要体现在以下两个方面:
DIB的颜色模式与设备无关。例如,一个256色的DIB即可以在真彩色显示模式下使用,也可以在16色模式下使用。
256色以下(包括256色)的DIB拥有自己的颜色表,像素的颜色独立于系统调色板。
由于DIB不依赖于具体设备,因此可以用来永久性地保存图象。DIB一般是以*.BMP文件的形式保存在磁盘中的,有时也会保存在*.DIB文件中。运行在不同输出设备下的应用程序可以通过DIB来交换图象

DDB的创建
MFC的CBitmap类封装了DDB。该类提供了几个函数用来创建DDB:
BOOL LoadBitmap( LPCTSTR lpszResourceName );
BOOL LoadBitmap( UINT nIDResource );
该函数从资源中载入一幅位图,若载入成功则返回TRUE。资源位图实际上是一个DIB,该函数在载入时把它转换成了DDB。

BOOL CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitcount, const void* lpBits );
该函数用来创建一幅空白的DDB。参数nWidth和nHeight以像素为单位说明了位图的宽度和高度。nPlanes是DDB的色平面数,nBitcount是每个色平面的颜色位数。一般来说,nPlanes为1,而nBitcount代表DDB中每个像素值所占的位数,但在创建16色DDB时,nPlanes为4,而nBitcount为1。参数lpBits指向存储像素阵列的数组,该数组应该逐行存储位图的每个像素值。注意,数组中每行像素的数目必需是偶数个字节,如果是奇数,则应该用0补足。若创建成功函数返回TRUE。

BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );
该函数创建一个与指定设备上下文兼容的DDB。参数pDC指向一个设备上下文,nWidth和nHeight是DDB的尺寸。若创建成功函数返回TRUE

DIB(设备无关位图)

至于DIB,MFC未提供现成的类来封装DIB。要想使用DIB,首先应该了解DIB的结构。这个你可以
到任何一本图像处理资料中找到详细说明。

DIB的颜色信息储存在自己的颜色表中,程序一般要根据颜色表为DIB创建逻辑调色板。在输出一幅DIB之前,程序应该将其逻辑调色板选入到相关的设备上下文中并实现到系统调色板中,然后再调用相关的GDI函数(如::SetDIBitsToDevice或::StretchDIBits)输出DIB。在输出过程中,GDI函数会把DIB转换成DDB,这项工作主要包括以下两步:

将DIB的颜色格式转换成与输出设备相同的颜色格式。例如,在真彩色的显示模式下要显示一个256色的DIB,则应该将其转换成24位的颜色格式。

将DIB像素的逻辑颜色索引转换成系统调色板索引。

把位图拷贝到剪贴板中是比较简单的,但是有件事情你可别忘记了,如果位图有调色板的话,你也要把调色板一起拷贝过去,否则的话位图就不能正确显示了。

函数1:拷贝一个DDB到剪贴板中

    copybitmaptoclipboard()函数能把一个DDB拷贝到剪贴板中去,如果有调色板它也一起拷贝过去。最后,注意调用detach()函数。这是非常重要的,因为GDI(图形设备接口)对象已经转移到了剪贴板中了。

//copybitmaptoclipboard         -拷贝DDB到剪贴板中
//pwnd                          -打开剪贴板窗口的指针
//bitmap                        -DDB
//ppal                          -逻辑调色板的指针,它可能是空的
//note                          -位图被拷贝后,剪贴板拥有的bitmap和ppal,它应该被分离
//
void copybitmaptoclipboard( const cwnd *pwnd, cbitmap& bitmap, cpalette* ppal )
{
    ::openclipboard(pwnd->getsafehwnd());
    ::emptyclipboard() ;
    if( ppal )
        ::setclipboarddata (cf_palette, ppal->getsafehandle() ) ;
    ::setclipboarddata (cf_bitmap, bitmap.getsafehandle() ) ;
    ::closeclipboard () ;
    bitmap.detach();
    if( ppal )
        ppal->detach();
}

//函数2:拷贝一个DIB到剪贴板中

    函数copydibtoclipboard()与函数copybitmaptoclipboard()很相似,内存句柄应该包括bitmapinfo和bitmap bits,可以使用函数globalalloc()来实现。一旦DIB被拷贝到剪贴板中,内存句柄就会被剪贴板所拥有,而且不会被你的应用程序给释放掉。

// copydibtoclipboard    -拷贝一个DIB到剪贴板中
// pwnd            -剪贴板的指针
// hdib            -包含bitmapinfo和bitmap bits内存句柄
// ppal            -逻辑调色板指针,可能是空的
// note            -位图被拷贝后,剪贴板拥有的bitmap和ppal,它应该被分离
//
void copydibtoclipboard( const cwnd *pwnd, hglobal hdib, cpalette* ppal )
{
    ::openclipboard(pwnd->getsafehwnd());
    ::emptyclipboard();
    if( ppal )
        ::setclipboarddata (cf_palette, ppal->getsafehandle() ) ;
    ::setclipboarddata (cf_dib, hdib ) ;
    ::closeclipboard () ;
    bitmap.detach();
    if( ppal )
        ppal->detach();
}

//函数3:拷贝一个图象到剪贴板中去

函数copywndtoclipboard()功能是拷贝一个图象到剪贴板中去

void copywndtoclipboard( cwnd *pwnd )
{
    cbitmap     bitmap;
    cclientdc    dc(pwnd);
    cdc         memdc;
    crect        rect;

    memdc.createcompatibledc(&dc); 

    pwnd->getwindowrect(rect);

    bitmap.createcompatiblebitmap(&dc, rect.width(),rect.height() );
    
    cbitmap* poldbitmap = memdc.selectobject(&bitmap);
    memdc.bitblt(0, 0, rect.width(),rect.height(), &dc, 0, 0, srccopy); 

    pwnd->openclipboard() ;
    emptyclipboard() ;
    setclipboarddata (cf_bitmap, bitmap.getsafehandle() ) ;
    closeclipboard () ;

    memdc.selectobject(poldbitmap);
    bitmap.detach();
}



原创粉丝点击