Symbian学习笔记(3)转载

上次学习的是从MIF和MBM文件中加载图像,一般在程序中出现的图片都可以用这个方法,但有一点点遗憾,它只能使用svg或bmp格式,BREW或J2ME中的资源却多为png格式的。

如果想在symbian中使用jpg或者png图片,则需要用到symbian提供的那个Multimedia ICL库里的类了。其中比较重的是CImageDecoder类,提供了对图像进行解码的功能

来看看如何使用它的吧。先定义两个字串:

_LIT(KJPEGFile,"C:\\Data\\me.jpg");

_LIT(KJPEGType,"image/jpeg");

使用的代码比较简单,如下所示:

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客iDec = CImageDecoder::FileNewL(iRFs,KJPEGFile);

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客    

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客  iParent->iBkImageMask=new (ELeave) CFbsBitmap(); 

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客  iParent->iBkImageMask->Create( iDec-> FrameInfo().iOverallSizeInPixels,iDec-> FrameInfo().iFrameDisplayMode );

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客  iDec->Convert( &iStatus, *(iParent->iBkImageMask) );

 其中的iDec是CImageDecoder的实例,而iRFs是RFs的实例。而iParent->iBkImageMask则是一个CFbsBitmap对象实例。

也就是说,我们先利用CImageDecorder::FileNewL来打开一个图像文件(它会自已判断图像类型,我们也可以提供给它我们指定的图像类型)。然后这个图像的信息就保存在iDec->FrameInfo()中了,利用这个信息可以创建一个CFbsBitmap实例(因为symbian中所有显示的图像都是这种类型)。最后,调用CImageDecorder的异步函数Convert就可以将图像(jpeg 或者png格式的)转换成CFbsBitmap位图了。唯一的麻烦是Convert是一个异步函数,第一个参数是TRequestStatus类型(可以是一个活动对象的iStatus成员)。

除了CImageDecorder::FileNewL以外还有一个CImageDecorder:;DataNewL也可以用来从一个缓冲区的字节内容构造出图像数据,只是它第二个参数是TDesC8&类型的aSourceData。

[补充]

别忘了包括头文件 ImageConversion.h,还有引入库imageconversion.lib。

AO机制包括两个类CActiveScheduler和CActive:

调度器CActiveScheduler:顾名思义它是协调多个活动对象的调度者。既然是非抢占式的,那它的调度原则是什么呢?教材上说法是:

A) 根据活动对象的优先级顺序对已注册的所有活动对象逐个检查。

B) 判断它是否是活动的(IsActive),且它的iStatus是否不为KRequestPending。

C) 满足则执行它的RunL方法

活动对象CActive:这可以理解为一个“线程”,就象Java中的Runable。它受调度器的指挥,它的关键在于类型为TRequestStatus的iStatus成员变量。

一般情况下在CActive中会有一个异步操作(方法形参表中包括一个TReuqestStatus类型参数),如果没有也无所谓(根据上面的调度原则,只要保证它不为KRequestPending即可)。

因为GUI应用自带了CActiveScheduler,所以我们要做的事情就是实现一个派生于CActive的子类,重载方法RunL()、DoCancel()和RunError()。当然还应该有一个类似于Start的方法来启动它。

Start负责启动,一般是在这里去执行一个异步操作(比如加载JPEG的图像,如上篇所言;或者打开一个定时器,如书上例子)。如果没有异步操作的话,也可以在这里啥事都不做。但是无论如何,它的最后一行肯定应该是SetActive(),让自己成为活动状态。

RunL负责具体的工作,如果是刚才Start了一个异步操作,此时应该处理该操作结束后的事务(如上篇中加载了图像以后就可以显示到屏幕上了)。如果刚才没有Start一个异步操作,那现在也得做点事情了。

有一种情况,我们把一个大任务分解成多个小任务,放在RunL中来做,那就得再加一个状态TInt iState来记录此次回调应该做哪一步小任务了(每完成一个小任务就改一个iState的值,并且还得再SetActive,让这个活动对象继续处于活动状态,直到所有任务完成)。

DoCancel提供了用户可以中止活动任务的手段,而RunError则提供了错误处理的机会

另外,在这个CActive的子类中,应该有一个地方(一般是在ConstructL中)将自己放入调度器的队列中,即调用CActiveScheduler::Add(this)。

帖一段代码,就是上篇加载JPEG图像的代码应该放在一个AO中来实现,利用向导生成一个CActive的子类:

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客class CImageLoader : public CActive

{

public:

    ~CImageLoader();

 

    // Two-phased constructor.

    static CImageLoader* NewL(CDemoUIAppView *p);

    static CImageLoader* NewLC(CDemoUIAppView *p);

 

public: // New functions

    void StartL(  );

 

private:

    CImageLoader();

    void ConstructL();

    

private: // From CActive

    void RunL();    

    void DoCancel();

    TInt RunError( TInt aError );

private:

    RFs                    iRFs;

    CDemoUIAppView        *iParent;

    CImageDecoder        *iDec;

};

cpp中的实现更简单了,在StartL中负责刚才的加载jpeg图像(主要是它有一个异步调用),在RunL中负责重绘CDemoUIAppView的界面即可。

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客void CImageLoader::StartL( )

{

    Cancel();                            // Cancel any request, just to be sure

    if(iDec)

        iDec->Cancel();

    delete iDec;

    iDec=NULL;

    

    iDec = CImageDecoder::FileNewL(iRFs,KJPEGFile);

          

     iParent->iBkImageMask=new (ELeave) CFbsBitmap(); 

     iParent->iBkImageMask->Create( iDec-> FrameInfo().iOverallSizeInPixels,iDec-> FrameInfo().iFrameDisplayMode );

     iDec->Convert( &iStatus, *(iParent->iBkImageMask) );

 

    SetActive();                        // Tell scheduler a request is active

}

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客

Symbian学习笔记(3)转载 - jianhai1229 - 水木博客void CImageLoader::RunL()

{

if(iParent)

    iParent->DrawNow();    

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值