Symbian 位圖處理

在Symbian中,位圖的管理由字體位圖服務器負責,該服務器提供了專門處理位圖的CFbsBitmap類。 應用程序中所有的位圖信息都放在一個叫做多位圖文件的包中(後綴爲.mbm),在mbm文件中對每一個位圖都有一個枚舉類型的值來引用,這個枚舉值在.mbg文件中定義。Symbian對位圖的操作包括構建多位圖文件、位圖的創建、裝載和位圖處理等。下面介紹詳細步驟。 1.生成多位圖文件 如果應用程序要使用多位圖文件,通常的做法是將所有的位圖添加到多位圖文件中,然後通過引用每一個位圖的枚舉來使用位圖。 首先需要在應用程序的mmp文件中把要使用的位圖列舉出來。 START BITMAP samplecontrol.mbm // (1) HEADER // (2) SOURCEPATH ../bmp // (3) TARGETPATH /system/apps/samplecontrol // (4) SOURCE c12 girl.bmp // (5) END 在mmp文件中(1)句定義多位圖文件必須以START BITMAP開頭。後面是多位圖文件的文件名,注意多位圖文件的文件名應該和應用程序的名稱一致,只是擴展名爲.mbm。接下來(2)句是一個 HEADER字段,表示定義位圖文件開始。(3)句SOURCEPATH字段指出位圖文件的存放位置,這裏應該使用相對路徑。(4)句 TARGETPATH是多位圖文件,也就是samplecontrol.mbm存放的位置,通常放在"/system/apps/應用程序名"這個路徑下面。(5)句的SOURCE字段列出每一個位圖文件,一個位圖文件使用一個SOURCE字段。c12用來指定該位圖文件的色深。指定色深的語法格式爲 c[depth]。c表示彩色圖片,depth用一個整數值表示深度,這裏爲12。最後以END表示結束。 定義好mmp文件後,應用程序會產生一個對應的.mbg文件。應用程序在需要使用位圖的文件中必須加上對.mbg文件的包含。生成的mbg文件是一個文本文件,它包含了位圖枚舉的定義。定義如下所示。 enum TMbmSamplecontrol { EMbmSamplecontrolGirl }; EMbmSamplecontrolGirl是程序要用到的位圖的枚舉值。枚舉值的格式爲EMbm+應用程序名+位圖文件名。應用程序就是使用這些枚舉值來使用位圖文件的。 2.創建並加載位圖 位圖枚舉值可以直接使用。但是如果要對位圖進行處理,那麼就應該創建位圖對象。 void CSampleControlContainer::LoadBitMap() { iBitmap = new (ELeave) CFbsBitmap(); // (1) _LIT(KMBMFILE, "//system//apps//samplecontrol//samplecontrol.mbm"); TFileName file(KMBMFILE); User::LeaveIfError(CompleteWithAppPath(file)); User::LeaveIfError(iBitmap->Load(file, EMbmSamplecontrolGirl)); } (1)句中iBitmap是CFbsBitmap類的指針,函數首先創建了CFbsBitmap類的對象,並將該對象賦給iBitmap。接下來就可以調用CFbsBitmap的Load()函數裝載位圖。Load()函數需要多位圖文件的路徑以及裝載位圖的枚舉值,指定裝載的是哪個位圖;mbm文件的路徑由_LIT文字給出,該文件用於初始化TFileName對象。ComplateWithAppPath()函數用於給路徑添加上諸如驅動器等信息。最後將mbm路徑和位圖枚舉值傳遞給Load()函數就實現了位圖的裝載。 3.顯示視圖 顯示視圖是在容器的Draw()函數中實現。CWindowGc提供了兩個函數DrawBitMap()和Bitblt()來實現位圖的繪製,這兩個函數的原型爲。 virtual void DrawBitmap(const TPoint& aTopLeft, const CFbsBitmap* aSource); virtual void Bitblt(const TPoint& aPos, const CFbsBitmap* aDevice); 除了參數不一樣外,它們的效率也不相同。DrawBitmap()的效率要低一些,因爲它要執行位圖的縮放,而Bitblt()只需要進行位圖塊的傳輸,效率較高。因此在顯示位圖時儘量使用Bitblt()。 void CSampleControlContainer::Draw(const TRect& aRect) const { CWindowGc& gc = SystemGc(); TPoint topLeft(30, 30); gc.BitBlt(topLeft, iBitmap); } 此程序運行的結果如下圖所示。 4.位圖處理 位圖處理包括位圖的旋轉、縮放、各式轉換、編碼和解碼等處理方式。這會涉及到字體位圖服務器的許多類的使用以及活動對象的知識。處理位圖的旋轉有很多方法,可以使用API函數,但這需要使用活動對象,也可以在像素的基礎上進行操作。 函數RotateBitmap()給出了位圖旋轉的代碼。 void CSampleControlContainer::RotateBitMap() { iTargetBitmap = new (ELeave) CFbsBitmap(); TSize targetSize = iBitmap->SizeInPixels(); User::LeaveIfError(iTargetBitmap->Create(TSize(targetSize.iHeight, targetSize.iWidth), iBitmap->DisplayMode())); TBitmapUtil srcBitmapUtil(iBitmap); TBitmapUtil targetBitmapUtil(iTargetBitmap); srcBitmapUtil.Begin(TPoint(30, 30)); targetBitmapUtil.Begin(TPoint(30, 30), srcBitmapUtil); TInt xPos; for (TInt yPos = 0; yPos < targetSize.iHeight; yPos++) { srcBitmapUtil.SetPos(TPoint(0, yPos)); targetBitmapUtil.SetPos(TPoint(yPos, 0)); for (xPos = 0; xPos < targetSize.iWidth; xPos++) { targetBitmapUtil.SetPixel(srcBitmapUtil); srcBitmapUtil.IncXPos(); targetBitmapUtil.IncYPos(); } } srcBitmapUtil.End(); targetBitmapUtil.End(); iBitmap->Duplicate(iTargetBitmap->Handle()); } 在這段代碼中,位圖的旋轉採用了在像素級別上進行操作。首先需要定義兩個位圖對象,一個是源位圖,另一個是目標位圖,目標位圖是源位圖的旋轉。 爲了確定目標位圖的尺寸,必須獲得原位圖的尺寸,將源位圖旋轉後的尺寸以及源位圖的顯示模式傳遞給Create()函數,就建了目標位圖對象。獲取源位圖的顯示模式是調用DisplayMode()函數。 爲了能夠在像素級別上操作位圖,需要用到TBitmapUtil類,該類提供了在像素級別上操作的函數,源位圖和目標位圖都要用到TBitmapUtil 類,因此用這兩個位圖初始化TBitmapUtil的對象。然後分別調用兩個TBitmapUtil對象的Begin()函數。在位圖操作完畢後要調用 End()函數。這樣做的目的是爲了鎖定位圖使用的堆。 接下來的代碼是位圖旋轉的操作。它的基本思想是從源位圖中獲取像素屬性,再將旋轉後該像素應該所在的位置上設置目標位圖像素的值。這裏用到TBitmapUtil的幾個成員函數。 SetPos。確定要進行操作的像素點。 SetPixel。該函數有多個版本。這裏傳遞了源位圖的指針,其含義是將源位圖的像素值讀取出來再將其設置爲目標位圖的像素值。 IncYPos和IncXPos。以像素爲單位在X或Y方向上增量。 爲了讓其旋轉之後能夠復原,程序將目標位圖拷貝給源位圖,爲的是再一次旋轉時能夠復原。複製位圖的函數是Duplicate,它需要位圖的句柄作爲參數。CFbsBitmap的Handle()函數可以獲取位圖的句柄。 旋轉後的效果如下圖所示。 http://hi.baidu.com/bupt_gang/blog/item/36ffbbdf33dbbfd38d102911.html http://www.forum.nokia.com/info/sw.nokia.com/id/567330dd-130f-4f1d-9380-fac5aec5a6a9/S60_Platform_Image_Converter_Example.html
發佈了17 篇原創文章 · 獲贊 1 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章