Archives
前段时间做了一段时间塞班平台的图像处理研究,想要做出类似于instagram、Q拍那样的滤镜特效,在手机拍完照后可以用我们提供的滤镜对照片进行美化处理(有空再做个ios版的)。看了一些instagram、Q拍、美图秀秀、可牛快拍等软件做出来的效果,对于图像处理零基础的我表示鸭梨很大。从RGB通道、alpha通道、位图结构、灰度图、图层、颜色表等概念看起,然后了解基本的图像处理方法如锐化、柔化、扩散、雕刻、黑白、反色等基本特效的原理,到高斯模糊、图像混合、柏林噪声等进阶的玩法,到最后总结出了一套做图像特效的方法,给我一个.psd的photoshop源文件,我便可以根据里面的拆分步骤用程序去实现该效果。其中参考了不少国外站点的东西,尤其是StackOverflow上找到了很多有用的东东,东拼西凑组成了我图像处理这块的一些心得。先上图吧。 原图如下: a. 基础效果 这里说基础是因为这些效果不涉及图像混合等更加复杂的东东,只是对每个像素的RGB通道做一些处理。 有的算法一行代码就能解决了,有的稍微复杂些,不过基本国内的网上都能找得到。 黑白 浮雕 素描 lomo 马赛克 扫描线 波普 鱼眼 b. 进阶效果 这里仅作了图像混合,并没有用函数去处理每个RGB分量,毕竟不是专门搞ps的,不知道怎么弄算好看.. 不过貌似可牛快拍里有些效果就是做了图像混合,然后稍做了些处理。这种做法比较没技术含量.. 不适合单独作为产品级的效果,可以作为复杂特效的某些步骤。 早晨 星光 这里就放出两张图了,因为做法其实都一样,最多传的参数不同罢了。当然图像混合也是有学问的,可以参考国外一哥们的系列文章:http://jswidget.com/blog/2011/03/11/image-blending-algorithmpart-i/ c.高级特效 下面两个效果挺花时间的,主要要知道怎么做比较费时间,做的过程的话第二个效果也比较复杂,是根据.psd文件的拆分步骤一步步做出来的,所以在移动平台上跑有些慢… 老照片 Nostalgia 做的方法受这个老外的影响很大:http://taptaptap.com/blog/creating-a-camera-plus-fx/ 这是个开发ios上滤镜app的老外设计师写的,而且是夫妻档,貌似老婆是设计师,她将做好的photoshop效果图给源文件给老公,然后老公根据.psd文件做成ios应用放到app store里去卖。我的Nostalgia特效就是模仿的他们的效果。不过老外没有把源代码放上来,就截了段核心函数,然后我自己摸索了好多天,不断的尝试,最后才搞成的效果。里面还涉及到了用Matlab模拟出曲线的函数,竟然用到了四次函数。。不过整个过程还是很享受的,很有乐趣。如果组内有需求,可以帮着搞一下。
客户端(v3版本)原先在处理服务器端传回gzip数据时采用的策略是先将gzip流保存成.gz文件,再用解压文件的方式将数据解压出来。这种方式显然不如直接从内存中实现gzip解压来得高效,但由于Symbian SDK中zlib的版本过低(1.1.3)等原因,网上介绍的很多内存流解压方法并不适用于此: http://apps.hi.baidu.com/share/detail/8355062 http://blog.sina.com.cn/s/blog_4d6f62190100md6k.html http://blog.sina.com.cn/s/blog_65db99840100kwh9.html http://www.devdiv.com/thread-8625-1-1.html http://www.developer.nokia.com/Community/Discussion/showthread.php?155614-GZip-and-RReadStream-problem 在解决过程中遇到了一些困难,开始使用http://apps.hi.baidu.com/share/detail/8355062 中的方法,并且将服务器返回的gzip数据去掉开头的10个gzip header,但程序始终卡在第13行: CBufFlat* CETNetOperator::DeCompressMemL(const TDesC8& aData) { TInt nBufferSize = 128; HBufC8* nSrc = NULL; HBufC8* nTemp = aData.Mid(10).Alloc(); //去掉开头10个字节 nSrc = nTemp; CleanupStack::PushL(nSrc); CBufFlat* nBufFlat = CBufFlat::NewL(nBufferSize); CleanupStack::PushL(nBufFlat); CBufferManager* nBufferManager = CBufferManager::NewLC(*nSrc, *nBufFlat, nBufferSize); CEZDecompressor* decompressor = CEZDecompressor::NewLC(*nBufferManager); while (decompressor->InflateL()) {// loop here until the file is compressed } // nBufFlat->Ptr(0); CleanupStack::PopAndDestroy(3); return nBufFlat; } 然后尝试使用Symbian SDK自带的zlib库,include <ezlib.h>,代码如下: int ungzip(char* source, int len, char* des) { int ret, have; [...]
本文内容非原创,属于网上资源的整理。 ======================================== 二阶段构造 问题1:为什么需要二阶段构造? 首先考虑如下的语句: CClassName* ptr = new (ELeave) CClassName(); 在内存有足够空间的情况下,代码首先在堆上分配一个CClassName类型的对象,并将地址赋给ptr指针,然后调用类的构造函数初始化这个对象。 这样,如果类的构造函数出现了异常,则会发生问题,这种异常发生时没有任何指针指向成功分配给CClassName对象的内存区域,因此这些内存成为孤立内存,发生内存泄漏。这就引出了symbian内存处理的一个重要规则:构造函数绝对不能异常退出。 问题2:为什么二阶段函数能够避免内存泄漏? 二阶段构造函数,顾名思义就是将一个对象的构造分为两个阶段: 第一个阶段是常规的的构造函数,在该构造函数中,没有可能导致异常退出的代码; 第二个阶段是可能会产生异常的构造阶段,实现为函数ConstructL(); 这样,对象的构造过程就应当包括了如下的代码: CClassName* self = new (ELeave) CClassName(); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(self); 这样的构造方式为什么就能够避免内存泄漏呢?下面我们来逐行分析代码: CClassName* self = new (ELeave) CClassName(); 重载的运算符new首先将内存分配给新的self实例,如果分配失败,那么程序异常退出,如果成功给新的对象分配了内存,那么接着执行不会异常退出的第一阶段构造函数; CleanupStack::PushL(self); 接着我们将本地指针self推入清除栈,因为下面要调用可能发生异常的退出函数。 self->ConstructL(); 如果该二阶段构造函数在执行时异常退出,那么新的CClassName的指针由清楚栈负责清楚,避免了内存泄漏;另外,如果该函数没有异常退出,则拥有了一个完全构造的CClassName实例。 CleanupStack::Pop(self); 安全的将本地指针从清除栈中弹出; 每实例化一个对象就要写上述代码确实有些啰嗦了,Symbian OS为了简化实例化的步骤,又引入了NewL(),NewLC()两个函数(其实也可以写成一个NewL(),然而大家都比较推崇同时创建NewL()和NewLC()),其具体的实现方式见问题3; 问题3:如何在新的类中创建二阶段构造函数? .h头文件: Class CClassName : public CBase { public: static CClassName* NewL(); static CClassName* NewlC(); ~CClassName(); private: CClassName(); //第一阶段构造 void ConstructL(); //第二阶段构造 …… } cpp源文件: [...]
本文内容非原创,属于网上资源的整理。 ======================================== 8位:(TDesC8),用于二进制数据或者ASCII字符串 16位:(TDesC16),默认,Unicode 描述符可以分为五类: 抽象类(Abstract):(TDes、TDesC、Tdes8、TdesC8),其他描述符的基类,仅提供接口和基本功能,不能被实例化,一般只用作函数的参数。 文字常量(Literal):(TlitC、_LIT()),用于存储文字字符串(literal string),即C中字符串常量,通常使用_LIT()这种方式(当然还有_L()和_L8()的描述方式,但都不提倡用)。 栈类(Buffer):(Tbuf、TbufC、 Tbuf8、TbufC8),数据存储于栈上,最基本的描述符变量类型,大小在编译时确定,包含描述符本身数据,使用最为普遍 堆类(Heap):(HbufC、HbufC8),数据存储于堆上,大小在运行时确定,也就是是用来处理动态申请的描述符类。 指针类(Pointer):(TPtr、TPtrC、TPtr8、TPtrC8),本身不包含描述符数据,但是包含长度数据,而且还包含一个指向位于描述符之外数据的指针。 1、 文字描述符常量 LIT(KMyFile, “c:\System\Apps\MyApp\MyFile.jpg”); _L()可以生成一个指向字符值的地址(TPtrC),它经常被用来传递字符串到函数中(包括描述符的构造函数和格式化函数);同理_L8()则可以生成一个指向二进制数据的地址(TPtrC8)举例如下: NEikonEnvironment::MessageBox(_L(“Error: init file not found!”)); //数字转字符串 TBuf16<20> buf; TInt iNum = 20; buf.Format( _L( “%d” ) , iNum ); 2、 栈描述符 LIT(Ktext , “Test Text”); _LIT(Ktext1 , “Test1 Text”); _LIT(KXtraText , “New:”); _LIT(NewText , “New1″); _LIT(NewText1 , “New2″); TBufC<10> Buf1 ( Ktext );//Buf1长度为9 内容 “Test Text” TBufC<10> Buf2 ( Ktext1 );//Buf2长度为10 内容 “Test1 Text” // 通过赋值的方式改变数据 Buf2 = Buf1; //Buf2长度变为9 内容 “Test Text” //通过使用Des()生成指针改变TBufC的数据 TPtr Pointer = Buf1.Des(); // 删除后四个字符 Pointer.Delete(Pointer.Length()-4, 4 ); //Buf1长度变为5 内容“Test ”//但是内存应该没变 // 增加新的数据 [...]
本文内容非原创,属于网上资源的整理。 ======================================== 基本数据类型 在Symbian中,很多C++基本类型都被重新定义了,最好使用Symbian的,理由如下: 所有Symbian API都是用的Symbianc重定义的 将来Symbian OS由32位转为64位时,支持性更好 这本身就是Symbian C++ Coding Standards所要求的 1. Integers typedef signed int TInt; C++中的signed int,32位,基本用法类似。 typedef unsigned int TUint; 一般用于计数器(Counter)或者标记(Flags)。 其他Int类型:TInt64, TInt32, TInt16,TInt8; 同时有一份TUint的版本。 2. Text text类型在Symbian编程中基本不用,而一般采用描述符(descriptor)。TText默认是16位的。 3. Boolean typedef int TBool;有两个枚举值:ETrue和EFalse。TBool变量最好不要直接和ETure和EFalse比较。如下: TBool flag = ETrue; if (flag) // if (!flag) { flag = EFalse; [...]
12213123 123 12 3 _LIT(KHello, “Hello!”); _LIT(KWorld, “World!”); HBufC* heapBuf = HBufC::NewL(KHello().Length()); *heapBuf = KHello; //buf holds ”Hello!” heapBuf = heapBuf->ReAllocL(KHello().Length() + KWorld().Length()); CleanupStack::PushL(heapBuf); TPtr ptr (heapBuf->Des()); //DON’T use TPtr ptr = heapBuf->Des(); this will set maxlen to 6 but not 12… ptr[KHello().Length() - 1] = ’ ’; ptr += KWorld; iTopLabel -> SetTextL(ptr); CleanupStack::PopAndDestroy(); DrawNow();
Recent Comments