symbian 同步解码透明图片

本文介绍了一个用于解码和绘制图像的类CPictureCtr。该类支持从文件路径或二进制数据加载图像,并能够创建指定尺寸的空白图像。文章详细展示了如何使用线程进行图像解码,并提供了图像绘制到指定位置的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理可以参考

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
 
   (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 
 
  
#include 
   
   // 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 
    
    // 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);
	}

   
  
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值