这几天总忙,字体那一部分,翻译了三天,进度实在有点慢.今天大概没啥事情了,暂时决定去杭州了,感觉那面还不错,经理很和蔼,他们的技术也正是我想要的.
在Symbian系统中,首选的使用Bitmap的方法是创建一个MBM(Multi-Bitmap file),在程序运行的时候从MBM中载入.一个MBM可以是一个文件存储器,或者只读镜像(ROM image)类型.文件存储器类型的MBM会被压缩,在程序运行的时候需要解压缩,消耗资源,只读镜像类型的MBM不被压缩,直接调用,节省资源.默认的MBM是文件存储器类型.
MBM可以从Windows的Bitmap中创建,使用bmconv工具进行转换.MBM可以直接被命令行所使用,或在mmp文件中定义.在编译的时候,他会被拷贝到相应的目标文件夹下.示例代码:
以下内容为程序代码:
// MyGame.mmp
START BITMAP MyGame.mbm
HEADER
TARGETPATH ..\..\..\..\wins\c\system\apps\MyGame
SOURCEPATH ..\MyBitmaps
// color-depth source-bitmap
SOURCE c12 image1.bmp
SOURCE c12 image2.bmp
SOURCE c12 image3.bmp
END
| |
以下内容为程序代码:
mmp在Bitmap的.h文件里给其一个枚举型的ID的数字,这个ID数字产生在系统文件夹下,(epoc32\include).Bitmap文件可以使用其ID数字在mbm文件中被存取,每一个ID都以下面的格式构造EMbm<MBM file name><bitmap file name>, 例如EMbmMygameImage1.如下存取MBM文件示例: [img]http://images.blogcn.comude <MyGame.mbg> // generated on compilation
[/img]include <aknutils.h> // for CompleteWithAppPath()
CFbsBitmap* CMyGameView::LoadMyBitmapL()
{
// set the name of the multi-bitmap file containing the bitmaps
_LIT(KMBMFileName,"MyGame.mbm"[img]/images/wink.gif[/img];
TFileName mbmFileName(KMBMFileName);
CompleteWithAppPath(mbmFileName);
// load the bitmap from the mbm file
CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
CleanupStack::PushL(bitmap);
// EMbmMygameImage1 is enumerated value from MyGame.mbg file
User::LeaveIfError(bitmap->Load(mbmFileName, EMbmMygameImage1));
CleanupStack::Pop(); // bitmap
return bitmap;
}
当Bitmap被载入以后,他可以被输出显示,如下示例代码: void CMyGameView:[img]/images/biggrin.gif[/img]raw( const TRect& /*aRect*/ [img]/images/wink.gif[/img] const
{
// Get the system graphics context
CWindowGc& gc = SystemGc();
// Draw the bitmap
gc.BitBlt( TPoint(10, 10), iMyShipBitmap);
}
| | 通常在一些情况下会用到遮挡.遮挡其实就是以遮挡的方法,来显示黑色和白色的图片.默认设置黑色部分是显示部分,白色是遮挡部分.有一些方法也可以实现反相遮挡.遮挡和普通的显示图片其实是一样的,也需要载入.遮挡示例代码:
以下内容为程序代码:
void CMyGameView:[img]/images/biggrin.gif[/img]raw( const TRect& /*aRect*/ [img]/images/wink.gif[/img] const
{
// Get the system graphics context
CWindowGc& gc = SystemGc();
// Draw masked bitmap
gc.BitBltMasked( TPoint(10, 10), iMyShipBitmap, iMyShipRect,
iMyShipMask, EFalse);
}
| | 遮挡对于游戏来说是非常有用的,你可以通过遮挡在背景上显示一些不规则的图形或图像.
在图像显示过程中,有时候要同时显示出几张图像来,这样会是一个很消耗系统资源的事情.这就会导致系统在显示图像的情况下比较缓慢,而且图像也是从不完整或者不准确到准确这样的一个显示过程.虽然最后的显示结果是准确的,但是,我们通常使用另外一种方法来避免这种情况.我们通常来建立一个容器类来控制图片的显示,转化和储存. 图片的转化可以使用一个临时的Bitmap来实现,示例代码如下:
以下内容为程序代码:
CFbsBitmap* CMyGameView::LoadAndConvertBitmapL(
Const TDesC& aFileName, TInt aBitmapId [img]/images/wink.gif[/img]
{
// Load the original bitmap
CFbsBitmap* originalBitmap = new ( ELeave [img]/images/wink.gif[/img] CFbsBitmap();
CleanupStack::PushL( originalBitmap [img]/images/wink.gif[/img];
User::LeaveIfError( originalBitmap->Load( aFileName, aBitmapId,
EFalse [img]/images/wink.gif[/img] [img]/images/wink.gif[/img];
// Create a new bitmap, graphics device and context
CFbsBitmap* newBitmap = new ( ELeave [img]/images/wink.gif[/img] CFbsBitmap();
CleanupStack::PushL( newBitmap [img]/images/wink.gif[/img];
newBitmap->Create( originalBitmap->SizeInPixels(),
Window()->DisplayMode() [img]/images/wink.gif[/img];
CFbsBitmapDevice* graphicsDevice = CFbsBitmapDevice::NewL(
bitmapConverted [img]/images/wink.gif[/img];
CleanupStack::PushL( graphicsDevice [img]/images/wink.gif[/img];
CFbsBitGc* graphicsContext;
User::LeaveIfError( graphicsDevice->CreateContext(
graphicsContext [img]/images/wink.gif[/img] [img]/images/wink.gif[/img];
// Blit the loaded bitmap to the new bitmap (the actual
// conversion)
bitmapContext->BitBlt( TPoint(0,0), originalBitmap [img]/images/wink.gif[/img];
CleanupStack::Pop(3);
delete bitmapContext;
delete bitmapDevice;
delete originalBitmap;
return newBitmap;
}
| | 上面的例子通过参数来获得文件名和Bitmap的ID,从MBM文件中载入相应的Bitmap.转化Bitmap为windows的显示模式,使用新的Bitmap来显示.
Bitmap可以旋转和块状化,这也是很有用处的.CMdaBitmapRotator来实现旋转一定的角度,CMdaBitmapScaler来实现块状化.S60平台2.0以前的版本不支持这两种方法,他使用了这两种CbitmapRotator 和CbitmapScaler,实现的功能是一样的.
实际上这两种方法的执行是异步的,通过继承自MMdaImageUtilObserver一个类来通知操作完成.如果你觉得对于Bitmap的操作方法太少,你也可以使用或者定义其他新的.If speed is a critical factor, you can access the bitmap data directly with a pointer and modify it as needed.
你可以使用CFbsBitmap: ataAddress来直接存取Bitmap数据区域的头指针(最左上角第一个点).有一点要注意,在程序运行的时候,这个点可能会被移动.所以,在对其使用TBitmapUtil进行存取的时候,要进行锁定.在S60平台2.0里,我们使用CFbsBitmap的LockHeap和UnlockHeap的方法.
在对Bitmap数据直接访问的时候,你需要知道他们的格式,比如,16比特的Bitmap是5-6-5格式,而12比特的Bitmap是4-4-4的格式.下面示例代码演示了给所有象素加上一个红色部分:
以下内容为程序代码:
void CMyGameView:[img]/images/biggrin.gif[/img]oMyBitmapEffect(CFbsBitmap* aBitmap)
{
// Lock heap
// For series 60 2.0 use:
// aBitmap->LockHeap();
// For series 60 1.0 use:
TBitmapUtil bitmapUtil(aBitmap);
bitmapUtil.Begin( TPoint(0,0) [img]/images/wink.gif[/img];
// Edit bitmap
TSize bitmapSize = aBitmap->SizeInPixels();
// NOTE: TUint16* applies to 16bit bitmaps only; the pointer must
// correspond the bit depth of the bitmap.
TUint16* bitmapData = (TUint16*)aBitmap->DataAddress();
for ( TInt y = 0; y < bitmapSize.iHeight; y++ [img]/images/wink.gif[/img];
{
for ( TInt x = 0; x < bitmapSize.iWidth; x++ [img]/images/wink.gif[/img]
{
// Increase colour value of each pixel by one
*bitmapData = ( *bitmapData & 31 [img]/images/wink.gif[/img] | // blue
( ( *bitmapData >> 5 [img]/images/wink.gif[/img] & 63 [img]/images/wink.gif[/img] | // green
( ( *bitmapData >> 11 [img]/images/wink.gif[/img] & 31 + 1 [img]/images/wink.gif[/img]; // red
bitmapData++;
}
}
// Unlock heap
// For series 60 1.0 use:
bitmapUtil.End();
// For series 60 2.0 use:
// aBitmap->UnlockHeap();
}
| | 最后,Hardware Acceleration里面给我们提供了很多好东东.
|