图像编程的若干常用操作(旋转,透明等)

本文介绍了图像编程中的一些常见操作,包括如何在Windows NT下旋转位图,实现透明背景的位图显示,以及位图的保存方法。提供了详细函数示例,如使用GetRotatedBitmap进行位图旋转,DrawTransparentBmp实现透明背景,以及创建和保存位图文件的函数。此外,还提及了渐变填充和GDI+的双缓冲技术以及PrintWindow函数在窗口截图中的应用。
摘要由CSDN通过智能技术生成

 

void  DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap,  short  xStart,
short  yStart, COLORREF cTransparentColor)
{
    BITMAP bm;
    COLORREF cColor;
    HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
    HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
    HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
    POINT ptSize;
    hdcTemp 
= CreateCompatibleDC(hdc);
    SelectObject(hdcTemp, hBitmap); 
// Select the bitmap
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
    ptSize.x 
= bm.bmWidth; // Get width of bitmap
    ptSize.y = bm.bmHeight; // Get height of bitmap
    DPtoLP(hdcTemp, &ptSize, 1); // Convert from device
    
// to logical points
    
// Create some DCs to hold temporary data.
    hdcBack = CreateCompatibleDC(hdc);
    hdcObject 
= CreateCompatibleDC(hdc);
    hdcMem 
= CreateCompatibleDC(hdc);
    hdcSave 
= CreateCompatibleDC(hdc);
    
// Create a bitmap for each DC. DCs are required for a number of
    
// GDI functions.
    
// Monochrome DC
    bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 11, NULL);
    
// Monochrome DC
    bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 11, NULL);
    bmAndMem 
= CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
    bmSave 
= CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
    
// Each DC must select a bitmap object to store pixel data.
    bmBackOld = (HBITMAP)::SelectObject(hdcBack, bmAndBack);
    bmObjectOld 
= (HBITMAP)::SelectObject(hdcObject, bmAndObject);
    bmMemOld 
= (HBITMAP)::SelectObject(hdcMem, bmAndMem);
    bmSaveOld 
= (HBITMAP)::SelectObject(hdcSave, bmSave);
    
// Set proper mapping mode.
    SetMapMode(hdcTemp, GetMapMode(hdc));
    
// Save the bitmap sent here, because it will be overwritten.
    BitBlt(hdcSave, 00, ptSize.x, ptSize.y, hdcTemp, 00, SRCCOPY);
    
// Set the background color of the source DC to the color.
    
// contained in the parts of the bitmap that should be transparent
    cColor = SetBkColor(hdcTemp, cTransparentColor);
    
// Create the object mask for the bitmap by performing a BitBlt
    
// from the source bitmap to a monochrome bitmap.
    BitBlt(hdcObject, 00, ptSize.x, ptSize.y, hdcTemp, 00,
    SRCCOPY);
    
// Set the background color of the source DC back to the original
    
// color.
    SetBkColor(hdcTemp, cColor);
    
// Create the inverse of the object mask.
    BitBlt(hdcBack, 00, ptSize.x, ptSize.y, hdcObject, 00,
    NOTSRCCOPY);
    
// Copy the background of the main DC to the destination.
    BitBlt(hdcMem, 00, ptSize.x, ptSize.y, hdc, xStart, yStart,
    SRCCOPY);
    
// Mask out the places where the bitmap will be placed.
    BitBlt(hdcMem, 00, ptSize.x, ptSize.y, hdcObject, 00, SRCAND);
    
// Mask out the transparent colored pixels on the bitmap.
    BitBlt(hdcTemp, 00, ptSize.x, ptSize.y, hdcBack, 00, SRCAND);
    
// XOR the bitmap with the background on the destination DC.
    BitBlt(hdcMem, 00, ptSize.x, ptSize.y, hdcTemp, 00, SRCPAINT);
    
// Copy the destination to the screen.
    BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 00,
    SRCCOPY);
    
// Place the original bitmap back into the bitmap sent here.
    BitBlt(hdcTemp, 00, ptSize.x, ptSize.y, hdcSave, 00, SRCCOPY);
    
// Delete the memory bitmaps.
    DeleteObject(SelectObject(hdcBack, bmBackOld));
    DeleteObject(SelectObject(hdcObject, bmObjectOld));
    DeleteObject(SelectObject(hdcMem, bmMemOld));
    DeleteObject(SelectObject(hdcSave, bmSaveOld));
    
// Delete the memory DCs.
    DeleteDC(hdcMem);
    DeleteDC(hdcBack);
    DeleteDC(hdcObject);
    DeleteDC(hdcSave);
    DeleteDC(hdcTemp);
}

1.位图的旋转
如果你的应用程序仅工作在Windows NT下,那么你可以通过API函数旋转你的位图。
你或者使用world transformation和BitBlt()或者使用PlgBlt()旋转位图。一个
使用第一种方法的函数显示在下面。

如果你的目标是多平台的,那么你的任务变得非常困难。你只能通过旋转源位图中
每个象素或者直接操作DIB字节得到旋转位图。第一种方法通过每个点的处理是非
常慢的,第二种方法是很复杂的,但它有足够快的速度。注:下面的所有函数旋转
后产生新的位图,如果你需要直接绘制位图,请自已修改函数。 其中函数1仅工作
在NT环境下,它是最简单也是最快的,可惜它不支持Windows95。

所有的函数所接受的角度单位是弧度,如果是角度单位是度请用下面的公式转换。

radian = (2*pi *degree)/360

旋转步骤:

创建一对与设备兼容的显示设备。一个用于源位图,一个用于旋转后的目标位图。

预计算正弦和余弦函数值,这样可以避免重复计算。

用下面的公式计算旋转图像后的矩形
newx = x.cos(angle) + y.sin(angle)
newy = y.cos(angle) - x.sin(angle)

旋转后的位图将不能占用整个新位图,我们将用背景色填充它。

点阵转换公式
newx = x * eM11 + y * eM21 + eDx
newy = x * eM12 + y * eM22 + eDy
其中eM11和eM22是角度的余弦值,eM21是角度的正弦,eM12是eM21的负值。 eDx & eDy
目的是旋转后的位图在新的位图不被剪切。

函数一:适用于NT

 

//  GetRotatedBitmapNT - Create a new bitmap with rotated image
//  Returns - Returns new bitmap with rotated image
//  hBitmap - Bitmap to rotate
//  radians - Angle of rotation in radians
//  clrBack - Color of pixels in the resulting bitmap that do
//  not get covered by source pixels
HBITMAP GetRotatedBitmapNT( HBITMAP hBitmap,  float  radians, COLORREF clrBack )
{
    
// Create a memory DC compatible with the display
    CDC sourceDC, destDC;
    sourceDC.CreateCompatibleDC( NULL );
    destDC.CreateCompatibleDC( NULL );
    
// Get logical coordinates
    BITMAP bm;
    GetObject( hBitmap, 
sizeof( bm ), &bm );
    
float cosine = (float)cos(radians);
    
float sine = (float)sin(radians);
    
// Compute dimensions of the resulting bitmap
    
// First get the coordinates of the 3 corners other than origin
    int x1 = (int)(bm.bmHeight * sine);
    
int y1 = (int)(bm.bmHeight * cosine);
    
int x2 = (int)(bm.bmWidth * cosine + bm.bmHeight * sine);
    
int y2 = (int)(bm.bmHeight * cosine - bm.bmWidth * sine);
    
int x3 = (int)(bm.bmWidth * cosine);
    
int y3 = (int)(-bm.bmWidth * sine);
    
int minx = min(0,min(x1, min(x2,x3)));
    
int miny = min(0,min(y1, min(y2,y3)));
    
int maxx = max(0,max(x1, max(x2,x3)));
    
int maxy = max(0,max(y1, max(y2,y3)));
    
int w = maxx - minx;
    
int h = maxy - miny;
    
// Create a bitmap to hold the result
    HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), w, h);
    HBITMAP hbmOldSource 
= (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap );
    HBITMAP hbmOldDest 
= (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult );
    
// Draw the background color before we change mapping mode
    HBRUSH hbrBack = CreateSolidBrush( clrBack );
    HBRUSH hbrOld 
= (HBRUSH)::SelectObject( destDC.m_hDC, hbrBack );
    destDC.PatBlt( 
00, w, h, PATCOPY );
    ::DeleteObject( ::SelectObject( destDC.m_hDC, hbrOld ) );
    
// We will use world transform to rotate the bitmap
    SetGraphicsMode(destDC.m_hDC, GM_ADVANCED);
    XFORM xform;
    xform.eM11 
= cosine;
    xform.eM12 
= -sine;
    xform.eM21 
= sine;
    xform.eM22 
= cosine;
    xform.eDx 
= (float)-minx;
    xform.eDy 
= (float)-miny;
    SetWorldTra
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值