WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程Symbian程序开发Graphics(4)

Graphics(4)
作者:剑走偏锋  来源:开发视界  发布时间:2005-12-20 0:13:15
这几天总忙,字体那一部分,翻译了三天,进度实在有点慢.今天大概没啥事情了,暂时决定去杭州了,感觉那面还不错,经理很和蔼,他们的技术也正是我想要的.

    在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文件示例:
include <aknutils.h> // for CompleteWithAppPath()

 

CFbsBitmap* CMyGameView::LoadMyBitmapL()

   {

   // set the name of the multi-bitmap file containing the bitmaps

   _LIT(KMBMFileName,"MyGame.mbm";

   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:raw( const TRect& /*aRect*/  const

   {

   // Get the system graphics context

   CWindowGc& gc = SystemGc();

 

   // Draw the bitmap

   gc.BitBlt( TPoint(10, 10), iMyShipBitmap);

   }

    通常在一些情况下会用到遮挡.遮挡其实就是以遮挡的方法,来显示黑色和白色的图片.默认设置黑色部分是显示部分,白色是遮挡部分.有一些方法也可以实现反相遮挡.遮挡和普通的显示图片其实是一样的,也需要载入.遮挡示例代码:
以下内容为程序代码:

void CMyGameView:raw( const TRect& /*aRect*/  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 

   {

   // Load the original bitmap

   CFbsBitmap* originalBitmap = new ( ELeave  CFbsBitmap();

   CleanupStack::PushL( originalBitmap ;

   User::LeaveIfError( originalBitmap->Load( aFileName, aBitmapId, 

      EFalse  ;

 

   // Create a new bitmap, graphics device and context

   CFbsBitmap* newBitmap = new ( ELeave  CFbsBitmap();

   CleanupStack::PushL( newBitmap ;

   newBitmap->Create( originalBitmap->SizeInPixels(), 

      Window()->DisplayMode() ;

   CFbsBitmapDevice* graphicsDevice = CFbsBitmapDevice::NewL(

      bitmapConverted ;

   CleanupStack::PushL( graphicsDevice ;

   CFbsBitGc* graphicsContext;

   User::LeaveIfError( graphicsDevice->CreateContext(

      graphicsContext  ;

 

   // Blit the loaded bitmap to the new bitmap (the actual 

   // conversion)

   bitmapContext->BitBlt( TPoint(0,0), originalBitmap ;

 

   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:dataAddress来直接存取Bitmap数据区域的头指针(最左上角第一个点).有一点要注意,在程序运行的时候,这个点可能会被移动.所以,在对其使用TBitmapUtil进行存取的时候,要进行锁定.在S60平台2.0里,我们使用CFbsBitmap的LockHeap和UnlockHeap的方法.

    在对Bitmap数据直接访问的时候,你需要知道他们的格式,比如,16比特的Bitmap是5-6-5格式,而12比特的Bitmap是4-4-4的格式.下面示例代码演示了给所有象素加上一个红色部分:
以下内容为程序代码:

void CMyGameView: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) ;

 

   // 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++ ;

      {

      for ( TInt x = 0; x < bitmapSize.iWidth; x++ 

         {

         // Increase colour value of each pixel by one

         *bitmapData = ( *bitmapData & 31  | // blue

                        ( ( *bitmapData >> 5  & 63  | // green

                        ( ( *bitmapData >> 11  & 31 + 1 ; // red

         bitmapData++;

         }

      }

   // Unlock heap

   // For series 60 1.0 use:

   bitmapUtil.End();

   // For series 60 2.0 use:

   // aBitmap->UnlockHeap();

   }

    最后,Hardware Acceleration里面给我们提供了很多好东东.
[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码