原理可以参考

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);
	}
posted on 2010-12-02 12:56  杂草丛  阅读(472)  评论(0编辑  收藏  举报