Symbian S60位图处理那些事 BitBlt DrawBitmap

来源:互联网 发布:骚扰电话软件下载 编辑:程序博客网 时间:2024/05/16 18:42

1:做过的人都知道,对于一张图,在Symbian中表示为CFbsBitmap的对象,如果是有Mask的画就是两张,一个叫做bitmap一个叫做mask,一般我们是这样命名的。你可以在控件的draw方法里面取systemgc来描画它,为了得到mask透明就用如下的方法。

iBitmap = new(ELeave) CFbsBitmap();
iMask = new(ELeave) CFbsBitmap();
gc.BitBltMasked(TPoint(0, 0), iBitmap, TRect(iBitmap()->SizeInPixels()), iMask, EFalse);


2:现在我们把这个有mask的图不直接描画到window上,而是用double-buffer的方法来描画到一个offscreen的bitmap上,如果我们现在这个offscreen的bitmap上先画个红色,而且像让我们后来描画的图片不覆盖offscreen的底图颜色,即要求他仍然后mask的透明效果我们就需要这么做:

    iBackGround = new(ELeave) CFbsBitmap;
User::LeaveIfError(iBackGround->Create(iGulIcon->Bitmap()->SizeInPixels(), iGulIcon->Bitmap()->DisplayMode()));
CFbsBitmapDevice *backgroundDevice = CFbsBitmapDevice::NewL(iBackGround);
CFbsBitGc* backgroundGc(NULL);
User::LeaveIfError(backgroundDevice->CreateContext(backgroundGc));

backgroundGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
backgroundGc->SetBrushColor(KRgbRed);
backgroundGc->DrawRect(TRect(iGulIcon->Bitmap()->SizeInPixels()));
backgroundGc->SetBrushStyle(CGraphicsContext::ENullBrush);

backgroundGc->BitBltMasked(TPoint(0, 0), iGulIcon->Bitmap(), iGulIcon->Bitmap()->SizeInPixels(), iGulIcon->Mask(), EFalse);
delete backgroundGc;
delete backgroundDevice;

当我们在用systemgc的如下方法描画时就得到一个方红图上一个图标:
   gc.BitBlt(TPoint(50, 0), iBackGround);

3.  如果我们把这个图片进行拉伸,就可以用gc的drawbitmap来做。此处有两种不同的效果,如果我们想拉伸后的图在新的doublebuffer上是mask透明的,还有就是整个doublebuffer的bitmap在window上是透明的。这是两种不同的效果,需要区分,实现的时候也是不一样的。

先说拉伸,我们可以通过以下调用得到:
backgroundGc2->DrawBitmap(rect2, iGulIcon->Bitmap());
很简单,但是这用拉伸或是缩放是有损耗的,如果不是纯色的图是看的出来差异的。

如果想让图片在doublebuffer的bitmap上是透明的就用此doublebuffer的gc的bitbltmasked的方法:
backgroundGc2->DrawBitmapMasked(rect2, iGulIcon->Bitmap(), TRect(iGulIcon->Bitmap()->SizeInPixels()), iGulIcon->Mask(), EFalse);
然后在sysmtemgc中用bitblt即可:
gc.BitBlt(TPoint(100, 0), iBackGround2);
此时的得到的效果是一个有mask的图片画到一个有背景色的bitmap上然后在把这个bitmap描画到window上,其实这个效果在上面我们已经得到了。

现在如果我们想真个offscreen的bitmap在window透明怎么弄呢?这里需要两个offscreen的bitmap,我们可以先把bitmap用drawbitmap画到bitmap的offscreen上,然后在把mask画到mask的offscreen上,最后用systemgc的bitbltmask方法把这个图片画到window上。代码如下:
  iBackGround2 = new (ELeave) CFbsBitmap;
User::LeaveIfError(iBackGround2->Create(TSize(40, 40), iGulIcon->Bitmap()->DisplayMode()));
CFbsBitmapDevice *backgroundDevice2 = CFbsBitmapDevice::NewL(iBackGround2);
CFbsBitGc* backgroundGc2(NULL);
User::LeaveIfError(backgroundDevice2->CreateContext(backgroundGc2));

iBackGround2Mask = new (ELeave) CFbsBitmap;
User::LeaveIfError(iBackGround2Mask->Create(TSize(40, 40), iGulIcon->Mask()->DisplayMode()));
CFbsBitmapDevice *backgroundDevice2Mask = CFbsBitmapDevice::NewL(iBackGround2Mask);
CFbsBitGc* backgroundGc2Mask(NULL);
User::LeaveIfError(backgroundDevice2Mask->CreateContext(backgroundGc2Mask));

TRect rect2(TPoint(0, 0), TSize(40, 40));
backgroundGc2->SetBrushStyle(CGraphicsContext::ESolidBrush);
backgroundGc2->SetBrushColor(KRgbGreen);
backgroundGc2->DrawRect(rect2);
backgroundGc2->SetBrushStyle(CGraphicsContext::ENullBrush);
backgroundGc2Mask->SetBrushStyle(CGraphicsContext::ENullBrush);
backgroundGc2->DrawBitmap(rect2, iGulIcon->Bitmap());
backgroundGc2Mask->DrawBitmap(rect2, iGulIcon->Mask());
delete backgroundGc2;
delete backgroundDevice2;
delete backgroundGc2Mask;
delete backgroundDevice2Mask;

Draw()方法中如下调用:
gc.BitBlt(TPoint(100, 0), iBackGround2);
gc.BitBltMasked(TPoint(150, 0), iBackGround2, TRect(iBackGround2->SizeInPixels()), iBackGround2Mask, EFalse);