原理可以参考
他这里只有解码非透明图,稍改一下
/* * PictureCtr.h * * Created on: 2010-5-14 * Author: huangxiaoguang * Company: 湖南拓维 */ #ifndef _PICTURECTR_H_ #define _PICTURECTR_H_ #include "ImageConversion.h" #include "Global.h" class CPictureCtr { public: enum DecodeStatus { DECODE_NONE, DECODING, DECODE_SUCCESS, DECODE_FAIL }; private: RMutex iMutex; public: CFbsBitmap* iBitmapBack; CFbsBitmap* iBitmapBackMask; DecodeStatus iDecodeStatus; CBufferedImageDecoder *imageDecoder; TSize m_iImageSize; jstring iFileName; private: CPictureCtr(); public: static CPictureCtr * NewL(); virtual ~CPictureCtr(); static TBool CheckImage(const TDesC8 & aData); public: TInt LoadPicture(const jstring& afilepath); TInt LoadPicture(const CString8& aData); TInt CreatePicture(TInt width, TInt height, TInt displayMode = ERgb); TInt getRGB(TInt x, TInt y) { TRgb rgb; iBitmapBack->GetPixel(rgb, TPoint(x, y)); return rgb.Value(); } void Draw(TPoint aPoint, jpgraphics g,TPoint aPoint1,TSize aSize); // void Draw(TPoint aPoint, TRect aSize, jpgraphics g); CPictureCtr & operator =(const CPictureCtr & pictureCtrl ); void copy(const CPictureCtr & pictureCtrl ); TInt GetWidth() { return m_iImageSize.iWidth; } TInt GetHeight() { return m_iImageSize.iHeight; } void setSize(jint aWidth,jint aHeight) { m_iImageSize.SetSize(aWidth,aHeight); } }; #endif /* PICTURECTR_H_ */
/* * PictureCtr.cpp * * Created on: 2010-5-14 * Author: huangxiaoguang * Company: 湖南拓维 */ #include "PictureCtr.h" #include "Header.h" #include "StreamUtil.h" #include "MyImageLoader.h" CPictureCtr::CPictureCtr() { imageDecoder = NULL; iBitmapBack = new (ELeave) CFbsBitmap(); iBitmapBackMask = new (ELeave) CFbsBitmap(); m_iImageSize.iHeight = 0; m_iImageSize.iWidth = 0; iDecodeStatus = DECODE_NONE; iMutex.CreateLocal(); } CPictureCtr::~CPictureCtr() { //TODO GB->gpvImages.removeElement(this); DEL(imageDecoder); DEL(iBitmapBack); DEL(iBitmapBackMask); } CPictureCtr * CPictureCtr::NewL() { return new CPictureCtr(); } void ThreadMainL(ThreadParameters* aParam) { CMyImageLoader* loader = CMyImageLoader::NewLC(); loader->LoadL(aParam); // send the decoding request CActiveScheduler::Start(); // and then start the message loop User::LeaveIfError(loader->iStatus.Int()); CleanupStack::PopAndDestroy(loader); } TInt ThreadFunc(TAny* aParam) { TInt err = KErrNone; ThreadParameters* param = reinterpret_cast<ThreadParameters*> (aParam); CTrapCleanup *cs = CTrapCleanup::New(); // create infrastructures like cleanup stack and active scheduler for the thread if (cs) { CActiveScheduler *s = new CActiveScheduler; if (s) { CActiveScheduler::Install(s); TRAP(err, ThreadMainL(param)); delete s; } delete cs; } else { err = KErrNoMemory; } return err; } TInt CPictureCtr::LoadPicture(const CString8& aData) { iMutex.Wait(); TInt result = KErrNone; if (aData.Length() > 0) { if (imageDecoder == NULL) imageDecoder = CBufferedImageDecoder::NewL(GB->aFs); imageDecoder->OpenL((TDesC8 &) aData, CImageDecoder::EOptionAlwaysThread); TFrameInfo frameInfo = imageDecoder->FrameInfo(0); DEL( imageDecoder ); m_iImageSize = frameInfo.iOverallSizeInPixels; iBitmapBack->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode /*was EColor4K*/); iBitmapBackMask->Create(frameInfo.iOverallSizeInPixels, EGray256 /*was EGray2*/); iDecodeStatus = DECODING; //imageDecoder->Convert(&iStatus, *iBitmapBack, *iBitmapBackMask); //SetActive(); //iWait->Start(); RThread thread; _LIT(KThreadName, "thread1" ); ThreadParameters param; param.iBuffer = aData.m_iBuf; param.iHandle = iBitmapBack->Handle(); param.iBackHandle = iBitmapBackMask->Handle(); TInt err = thread.Create(KThreadName, ThreadFunc, KDefaultStackSize, NULL, ¶m); User::LeaveIfError(err); CleanupClosePushL(thread); thread.Resume(); // then let the thread do the job TRequestStatus status = KRequestPending; thread.Logon(status); User::WaitForRequest(status); // and then wait until the thread exits User::LeaveIfError(status.Int()); CleanupStack::PopAndDestroy(&thread); iDecodeStatus = DECODE_SUCCESS; } iMutex.Signal(); return result; } TInt CPictureCtr::LoadPicture(const jstring& afilepath) { //iMutex.Wait(); iFileName = afilepath; jstring filepath = afilepath; filepath.Replace(_L("/"), _L("\\")); filepath.Replace(_L("\\\\"), _L("\\")); RFile fp; if (KErrNone != fp.Open(GB->aFs, (TDesC &) filepath, 0)) { fp.Close(); iDecodeStatus = DECODE_FAIL; DEL( imageDecoder ); return -1; } fp.Close(); const CImageDecoder::TOptions options = CImageDecoder::EOptionAlwaysThread; CImageDecoder *decoder = NULL; decoder = CImageDecoder::FileNewL(GB->aFs, (TDesC&) filepath, options); CleanupStack::PushL(decoder); TFrameInfo frameInfo = decoder->FrameInfo(0); m_iImageSize = frameInfo.iOverallSizeInPixels; iBitmapBack->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode /*was EColor4K*/); iBitmapBackMask->Create(frameInfo.iOverallSizeInPixels, EGray256 /*was EGray2*/); iDecodeStatus = DECODING; TRequestStatus status = KRequestPending; decoder->Convert(&status, *iBitmapBack, *iBitmapBackMask); User::WaitForRequest(status); CleanupStack::PopAndDestroy(decoder); iDecodeStatus = DECODE_SUCCESS; return 0; } TInt CPictureCtr::CreatePicture(TInt width, TInt height, TInt displayMode) { m_iImageSize.iWidth = width; m_iImageSize.iHeight = height; TInt result = KErrNone; result = iBitmapBack->Create(m_iImageSize, TDisplayMode(displayMode)); result = iBitmapBackMask->Create(m_iImageSize, EGray256); iDecodeStatus = DECODING; iDecodeStatus = DECODE_SUCCESS; return result; } void CPictureCtr::Draw(TPoint aPoint, jpgraphics g, TPoint aPoint1, TSize aSize) { if (iDecodeStatus == DECODE_SUCCESS) { g->SetBrushStyle(CGraphicsContext::ENullBrush); TRect bmpEmaPieceRect(aPoint1, aSize); g->BitBltMasked(aPoint, iBitmapBack, bmpEmaPieceRect, iBitmapBackMask, ETrue); } } CPictureCtr & CPictureCtr::operator =(const CPictureCtr & pictureCtrl) { DEL(imageDecoder); iDecodeStatus = pictureCtrl.iDecodeStatus; m_iImageSize = pictureCtrl.m_iImageSize; iFileName = pictureCtrl.iFileName; TSize TargetSize = pictureCtrl.iBitmapBack->SizeInPixels(); User::LeaveIfError(iBitmapBack->Create(TSize(TargetSize.iWidth, TargetSize.iHeight), pictureCtrl.iBitmapBack->DisplayMode())); User::LeaveIfError(iBitmapBackMask->Create(TSize(TargetSize.iWidth, TargetSize.iHeight), pictureCtrl.iBitmapBackMask->DisplayMode())); CFbsBitGc *maskGC = NULL; CFbsBitmapDevice *maskGD = NULL; maskGD = CFbsBitmapDevice::NewL(iBitmapBack); CleanupStack::PushL(maskGD); User::LeaveIfError(maskGD->CreateContext(maskGC)); maskGC->BitBlt(TPoint(0, 0), pictureCtrl.iBitmapBack); CleanupStack::PopAndDestroy(maskGD); DEL(maskGC); maskGD = CFbsBitmapDevice::NewL(iBitmapBackMask); CleanupStack::PushL(maskGD); User::LeaveIfError(maskGD->CreateContext(maskGC)); maskGC->BitBlt(TPoint(0, 0), pictureCtrl.iBitmapBackMask); CleanupStack::PopAndDestroy(maskGD); DEL(maskGC); return *this; } void CPictureCtr::copy(const CPictureCtr & pictureCtrl) { DEL(imageDecoder); iDecodeStatus = pictureCtrl.iDecodeStatus; m_iImageSize = pictureCtrl.m_iImageSize; iFileName = pictureCtrl.iFileName; }
#ifndef __MYIMAGELOADER_H__ #define __MYIMAGELOADER_H__ #include <f32file.h> #include <e32base.h> // CActive class CFbsBitmap; class CBufferedImageDecoder; struct ThreadParameters { const TDesC8* iBuffer; // input TInt iHandle; // handle of the decoded bitmap object TInt iBackHandle; // handle of the decoded bitmap object }; class CMyImageLoader : public CActive { public: // constructors like NewL, NewLC, destructor static CMyImageLoader* NewLC(); static CMyImageLoader* NewL(); ~CMyImageLoader(); public: void RunL(); void DoCancel(); public: void LoadL(const ThreadParameters* aParam); private: // constructors and ConstructL() CMyImageLoader(); void ConstructL(); private: RFs iFs; RFbsSession iFbs; CBufferedImageDecoder* iDecoder; CFbsBitmap* iBitmap; CFbsBitmap* iBackBitmap; ThreadParameters* iParam; }; #endif #include <ImageConversion.h> // CImageDecoder #include "MyImageLoader.h" CMyImageLoader* CMyImageLoader::NewLC() { CMyImageLoader* self = new(ELeave) CMyImageLoader; CleanupStack::PushL(self); self->ConstructL(); return self; } CMyImageLoader* CMyImageLoader::NewL() { CMyImageLoader* self = NewLC(); CleanupStack::Pop(self); return self; } CMyImageLoader::~CMyImageLoader() { delete iDecoder; REComSession::FinalClose(); // fix a memory leak issue of the CImageDecoder delete iBitmap; delete iBackBitmap; iFbs.Disconnect(); iFs.Close(); } void CMyImageLoader::RunL() { CActiveScheduler::Stop(); // stop the message loop so that the CActiveScheduler::Start() can return } void CMyImageLoader::DoCancel() { // no implementation needed because we will never cancel the operation } void CMyImageLoader::LoadL(const ThreadParameters* aParam) { iParam = (ThreadParameters*)aParam; iBitmap = new(ELeave) CFbsBitmap; TInt err = iBitmap->Duplicate(iParam->iHandle); User::LeaveIfError(err); iBackBitmap = new(ELeave) CFbsBitmap; err = iBackBitmap->Duplicate(iParam->iBackHandle); User::LeaveIfError(err); iDecoder = CBufferedImageDecoder::NewL( iFs ); iDecoder->OpenL(*(aParam->iBuffer), CImageDecoder::EOptionAlwaysThread ); iStatus = KRequestPending; iDecoder->Convert(&iStatus, *iBitmap, *iBackBitmap); SetActive(); } CMyImageLoader::CMyImageLoader() : CActive(CActive::EPriorityStandard) { iParam = NULL; CActiveScheduler::Add(this); } void CMyImageLoader::ConstructL() { TInt err = iFs.Connect(); User::LeaveIfError(err); err = iFbs.Connect(iFs); User::LeaveIfError(err); }