DrawImage与TextBrush使用
在使用GDI+过程中,常常需要在对话框或者控件上贴图片,大多数时候,我们都是使用DrawImage函数,这个函数非常好用,当目的区域比图片大时,图片可以拉伸,但是当图片是渐变色的时候,会发现拉伸后,颜色会有所变化,这是在使用DrawImage时,需要设置一个参数,如:
ImageAttributes ia; ia.SetWrapMode( WrapModeTileFlipXY ); graphic.DrawImage(pImg, grect, 0, 0, (REAL)pImg ->GetWidth(), (REAL)pImg ->GetHeight(), UnitPixel, &ia );
关于WrapModeTileFlipXY它还有其他枚举值,可以查看msdn具体的含义。
GDI+除了可以使用DrawImage来贴图片外,还有一个函数FillRectangle,它可以在某一个矩形区域填充一个纯色;如果使用一个TextBrush来FillRectangle的话,就可以用一副图片填充某个矩形区域,如:
CRect rc( 10, 10,15, 15); TextureBrush textBrush( Image::FromFile( _T(\\res\\picture.png) ), WrapModeTile ); graphic.FillRectangle( &textBrush, rc.right - 4, rc.top, 4, 5 );
但是我们在实际使用过程中,可能会出现用FillRectangle贴图片的时候,出现图片错位的现象,原因主要是FillRectangle不是用图片直接填充目的矩形区域,它是先用图片填充当前dc所包含的区域,然后在dc包含的区域内裁减与目的区域一样大小的矩形区域去填充目的区域,这样,当由于图片比dc包含的区域小,在填充dc包含的矩形区域时,就会一块接一块的重复平铺,这样当从dc包含的区域的right开始截取与目的区域一样大小的矩形区域时,图片样式就不可控了,于是效果就会出现错位现象。
解决这个问题有两个办法,一个就是将dc的绘制区域设置和目的dc相同。如:(我们一般都会使用双缓冲技术贴图,这样图片不会闪烁)
CRect destRect(10,10,15,15); HDC hmemDC = ::CreateCompatibleDC( hdc ); //创建和目的区域一样大小的兼容bitmap HBITMAP hBmp = ::CreateCompatibleBitmap( hdc, destRect.Width(),destRect.Height() ); HANDLE hOld = ::SelectObject(hmemDC, hBmp); Graphics graphic( hmemDC ); TextureBrush textBrush( Image::FromFile( _T(\\res\\picture.png) ), WrapModeTile ); graphic.FillRectangle( &textBrush, destRect.left, rc.top, 5, 5 ); ::BitBlt( hdc, destRect.left, destRect.top, rc.Width(), rc.Height() , hmemDC, 0, 0, SRCCOPY ); ::SelectObject( hmemDC, hOld ); ::DeleteObject( hBmp ); ::DeleteDC( hmemDC );
但是,有的时候,我们的dc区域没办法做到和目的区域一样大小,因为可能需要画一张大的底图,然后修改上面很小一个区域,贴上另外一张图片,这时就可以使用另外一种方法,就是平移坐标,如:
……………………………… CRect dcRect( 10,10,20,20); CRect destRect(15,15,20,20); TextureBrush textBrush(Image::FromFile( _T(\\res\\picture.png) ), WrapModeTile ); //移动坐标 textBrush.TranslateTransform( ( REAL )( dcRect.right - 5 ), ( REAL )( dcRect.bottom - 5 ) ); graphic.FillRectangle( &textBrush, destRect.left, destRect.top, 5, 5 ); ………………