在做Symbian Camera應用的時候,我們發現, 在某些特殊的手機上. Preview以後拿到的那些Frame也就是位元影像CFbsBitmap是旋轉過的. 比方說N75上, 比方說我在N96的一個原型機上也看到. 碰到這種情況. 我們只能手動的進行旋轉. 旋轉完成後再畫就基本上可以了. 但是旋轉有很多種, 如何旋轉呢?
從Symbian OS v7.0開始就有了CBitmapRotator這樣一個類專門來做這個事情. 函數的原型很簡單:
IMPORT_C void Rotate(TRequestStatus *aRequestStatus, CFbsBitmap &aSrcBitmap, CFbsBitmap &aTgtBitmap, TRotationAngle aAngle);<br />void Rotate(TRequestStatus* aRequestStatus, CFbsBitmap& aSrcBitmap, CFbsBitmap& aTgtBitmap, TRotationAngle aAngle);<br />
從這函數的原型就可以看出需要一個AO來發起這個非同步調用, 可見這個過程的效率不會高到什麼地方去. 現實也是, 確實不快, 尤其如果又再camera view finder這裡不是很合適的.所以放棄.
轉而頭像了DataAddress, 從這裡可以直接拿到raw data. 這樣就好像很和諧了. 說幹就幹, debug了一下, 發現這裡bitmap的displaymode是EColor16MU, 就比較 好辦了
CFbsBitmap* CameraManager::rotateBitmap90 (CFbsBitmap& src)<br />{<br />CFbsBitmap* pDstBmp = new (ELeave) CFbsBitmap ();<br />TSize srcSize = src.SizeInPixels();<br />TDisplayMode mode = src.DisplayMode();<br />User::LeaveIfError(pDstBmp->Create(TSize(srcSize.iHeight,srcSize.iWidth), src.DisplayMode()));</p><p>TBitmapUtil srcUtil ( &src );<br />TBitmapUtil dstUtil ( pDstBmp );</p><p>srcUtil.Begin(TPoint(0,0));<br />dstUtil.Begin(TPoint(0,0));<br />if ( mode == EColor16MU )<br />{<br />TUint32* pDataSrc = src.DataAddress();<br />TUint32* pDataDst = pDstBmp->DataAddress();<br />for (TInt32 j = 0 ; j < srcSize.iWidth ; j++)<br />{<br />for ( TInt32 i = 0; i < srcSize.iHeight; i++ )<br />{<br />pDataDst [ j* srcSize.iHeight + i ] = pDataSrc [ ( srcSize.iHeight - i - 1 ) * srcSize.iWidth + j ];<br />}<br />}<br />}<br />srcUtil.End();<br />dstUtil.End();<br />return pDstBmp;<br />}
就這麼寫了一個直接旋轉90度的函數.從實際的效果看要比CBitmapRotator來的快一些, 明顯畫面更流暢一些!當然還搜尋了些旁的方案, 比如TBitmapUtil來操縱IncXPos, IncYPos做遍曆, 用GetPixel來改寫rgb值, 不過這種辦法頗有捨近求遠的嫌疑, 料想效率也高不到什麼地方去, 不管如何, 現在直接操作記憶體想來是不錯的主意了吧.