symbian 同步解码透明图片

原理可以参考

http://wiki.forum.nokia.com/index.php/%E5%A6%82%E4%BD%95%E5%90%8C%E6%AD%A5%E8%A7%A3%E7%A0%81%E5%9B%BE%E5%83%8F

他这里只有解码非透明图,稍改一下

 

/*

 * 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, &param);

		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);

	}

你可能感兴趣的:(Symbian)