JavaME UI设计之图像特效二

http://innovator.samsungmobile.com/cn/bbs/discussion/view.do?boardId=912&boardName=pick&messageId=107883&messageNumber=&messageCategoryId=0&startId=zzzzz~&startPage=1&curPage=1&rowsPerPage=10&searchType=title&searchText=&searchDays=0&searchTitleFlag=false&searchContentsFlag=false&searchRegisterNicknameFlag=false&lastPageFlag=&categoryId=621&parentCategoryId=218&platformId=3&selectOrder=REGISTER_DATE&selectOrderDirection=DESC&searchParameters=%2Fcn%2Fbbs%2Fdiscussion%2Fthread.list.do%3FlistLines%3D10|searchType%3Dtitle|curPage%3D1|selectOrder%3DREGISTER_DATE|selectOrderDirection%3DDESC|&startDate=&endDate=&searchTypeForm=&searchTextForm=

JavaME UI设计之图像特效二

发表在 2011.01.25 13:04 GMT+8
    • 评估该帖
作者:杨丰盛
 
上一篇我们分析了处理图片特效的原理,通常是将图像数据转换为一个int[]数组,然后再操作这个int[]数组,最后将操作之后的int[]数组转换为一个Image即可。本文我们接着分析另外几种常用特效的实现原理。
负片特效
要在图像处理软件中将图片处理为负片特效,非常简单,但是这些图像处理软件也是通过程序来实现的,其实现原理通常是用255来减去图像数据的r,g,b值,得到一个新的r,g,b值,再将新的数值合成图片即可,具体实现代码如下:
/*
 * 图片特效负片
 */
public Image effect_negative(Image src) {
       int srcW = src.getWidth();
       int srcH = src.getHeight();
       int[] srcPixels = getPixels(src);
       int r = 0;
       int g = 0;
       int b = 0;
       int a = 0;
       int argb;
       for (int i = 0; i < srcH; i++) {
              for (int ii = 0; ii < srcW; ii++) {
                     argb = srcPixels[i * srcW + ii];
                     a = ((argb & 0xff000000) >> 24); // alpha channel
                     r = 255 - ((argb & 0x00ff0000) >> 16); // red channel
                     g = 255 - ((argb & 0x0000ff00) >> 8); // green channel
                     b = 255 - (argb & 0x000000ff); // blue channel
                     srcPixels[i * srcW + ii] = ((a << 24) | (r << 16) | (g << 8) | b);
              }
       }
       return drawPixels(srcPixels, srcW, srcH);
}
在JavaME中一个像素都是一个int数据,要分别取得其a,r,g,b通道直接使用移位操作即可,如下所示。在其他更复杂的特效处理中夜经常这样来提取一个像素的a,r,g,b数值。
a = ((argb & 0xff000000) >> 24);
r = ((argb & 0x00ff0000) >> 16);
g = ((argb & 0x0000ff00) >> 8);
b = (argb & 0x000000ff);
对于负片特效的演示效果,如下图所示。
 

 
黑白特效
图像的黑白特效实现的原理是将图像的a,r,g,b通道的值都降低一定的比例,因此实现过程即为先取出每个像素的a,r,g,b通道数据,然后分别乘以一个颜色的比例(该比例可以根据实际实现进行调整),然后将个通道数据按照((a << 24) | (r << 16) | (g << 8) | b)方式合成一个int值,具体实现代码如下所示。
/*
 * 图片特效黑白
 */
public Image effect_black_white(Image src) {
       int srcW = src.getWidth();
       int srcH = src.getHeight();
       int[] srcPixels = getPixels(src);
       int r = 0;
       int g = 0;
       int b = 0;
       int a = 0;
       int argb;
       int temp;
       for (int i = 0; i < srcH; i++) {
              for (int ii = 0; ii < srcW; ii++) {
                     argb = srcPixels[i * srcW + ii];
                     a = ((argb & 0xff000000) >> 24); // alpha channel
                     r = ((argb & 0x00ff0000) >> 16); // red channel
                     g = ((argb & 0x0000ff00) >> 8); // green channel
                     b = (argb & 0x000000ff); // blue channel
                     temp = (int) (.299 * (double) r + .587 * (double) g + .114 * (double) b);
                     r = temp;
                     g = temp;
                     b = temp;
                     srcPixels[i * srcW + ii] = ((a << 24) | (r << 16) | (g << 8) | b);
              }
       }
       return drawPixels(srcPixels, srcW, srcH);
}
这里我们对r,g,b通道分别乘了0.299,0.587,0.114,该数值可以进行调整,具体效果如下图所示。
 

 
粉笔画特效
粉笔画大家都见得很多了,这里就不作过多的介绍了,要通过程序实现粉笔画的可以通过以下公式进行实现:
R=255-(Math. sqrt((2*(r-r1)*(r-r1)+(r-r2)*(r-r2))))
G=255-(Math. sqrt((2*(g-g1)*(g-g1)+(g-g2)*(g-g2))))
B=255-(Math. sqrt((2*(b-b1)*(b-b1)+(b-b2)*(b-b2))))
其中r1和r2分别为当前像素的右边一个像素和下边一个像素的r值,g1、g2、b1、b2同理。
有关粉笔画的效果具体实现代码如下:
/*
 * 图片特效粉笔画
 */
public Image effect_crayon(Image src)
{
       int srcW = src.getWidth();
       int srcH = src.getHeight(); 
       int[] srcPixels = getPixels(src);
       int r = 0;
       int g = 0;
       int b = 0;
       int a = 0;
       int argb;  
       int r1 = 0;
       int g1 = 0;
       int b1 = 0;
       int r2 = 0;
       int g2 = 0;
       int b2 = 0;
       for (int i = 0; i < srcH; i++)
       {
              for(int ii=0;ii<srcW;ii++)
              {
                     argb = srcPixels[i*srcW+ii];
                     a = ((argb & 0xff000000) >> 24); // alpha channel
                     r = ((argb & 0x00ff0000) >> 16); // red channel
                     g = ((argb & 0x0000ff00) >> 8); // green channel
                     b = (argb & 0x000000ff); // blue channel
              if(i+1 == srcH)
              {
                     r1= 0;
                     g1= 0;
                     b1=0;
              }
              else
              {
                     argb = srcPixels[(i+1)*srcW+ii];
                     r1 = ((argb & 0x00ff0000) >> 16); // red channel
                     g1 = ((argb & 0x0000ff00) >> 8); // green channel
                     b1 = (argb & 0x000000ff); // blue channel
              }
              if(ii+1 == srcW){
                     r2= 0;
                     g2= 0;
                     b2=0;
              }
              else
              {
                     argb = srcPixels[i*srcW+ii+1];
                     r2 = ((argb & 0x00ff0000) >> 16); // red channel
                     g2 = ((argb & 0x0000ff00) >> 8); // green channel
                     b2 = (argb & 0x000000ff); // blue channel
              }
             // rr1=(r1-r2)^2 rr2=(r1-r3)^2
           r = (int)Math.sqrt((double)(2*(r-r1)*(r-r1)+(r-r2)*(r-r2)));
           g = (int)Math.sqrt((double)(2*(g-g1)*(g-g1)+(g-g2)*(g-g2)));
           b = (int)Math.sqrt((double)(2*(b-b1)*(b-b1)+(b-b2)*(b-b2)));
           r =255-r; // red channel
           g =255-g; // green channel
           b =255-b; // blue channel
           srcPixels[i*srcW+ii] = ((a << 24) | (r << 16) | (g << 8) | b);
           }
    }
    return drawPixels(srcPixels, srcW, srcH);
}
通过该函数实现的粉笔画效果如下图所示。
 

 


举报
引用
 
zhangjj
帖子 : 27
加入日期 : 2010.08.04 10:28 GMT+8
地点 : 中国

JavaME UI设计之图像特效二

发表在 2011.01.25 13:07 GMT+8
    • 评估该帖
蒙版特效
蒙版特效的实现和黑白特效的实现比较类似,都是对r,g,b都乘以一个比例,但是与黑白特效不同的是不用使用255来做被减数了,因此实现过程很简单,下面直接给出代码,如下:
/*
 * 图片特效蒙版
 */
public Image effect_hoodwink(Image src) {
       int srcW = src.getWidth();
       int srcH = src.getHeight();
       int[] srcPixels = getPixels(src);
       int r = 0;
       int g = 0;
       int b = 0;
       int a = 0;
       int argb;
 
       for (int i = 0; i < srcH; i++) {
              for (int ii = 0; ii < srcW; ii++) {
                     argb = srcPixels[i * srcW + ii];
                     a = ((argb & 0xff000000) >> 24); // alpha channel
                     r = ((argb & 0x00ff0000) >> 16); // red channel
                     g = ((argb & 0x0000ff00) >> 8); // green channel
                     b = (argb & 0x000000ff); // blue channel
                     r = (int) (.299 * (double) r);
                     g = (int) (.587 * (double) g);
                     b = (int) (.114 * (double) b);
                     srcPixels[i * srcW + ii] = ((a << 24) | (r << 16) | (g << 8) | b);
              }
       }
       return drawPixels(srcPixels, srcW, srcH);
}
测试运行效果如下图所示。
 

 
当然你也可以更改乘以的比例值来调整蒙版的颜色。
霓虹灯效果
霓虹灯效果,听着名字感觉很不错,那么我们将图片渲染为霓虹灯效果呢?实际上很简单,和粉笔画的特效类似,但是不需要通过255来减去r,g,b的值,使用如下公式即可:
R=(Math. sqrt((2*(r-r1)*(r-r1)+(r-r2)*(r-r2))))
G=(Math. sqrt((2*(g-g1)*(g-g1)+(g-g2)*(g-g2))))
B=(Math. sqrt((2*(b-b1)*(b-b1)+(b-b2)*(b-b2))))
具体实现效果如下代码所示:
/*
 * 图片特霓虹灯
 */
public Image effect_neonLight(Image src)
{
       int srcW = src.getWidth();
       int srcH = src.getHeight(); 
       int[] srcPixels = getPixels(src);
       int r = 0;
       int g = 0;
       int b = 0;
       int a = 0;
       int argb;  
       int r1 = 0;
       int g1 = 0;
       int b1 = 0;
       int a1 = 0;
       int r2 = 0;
       int g2 = 0;
       int b2 = 0;
       int a2 = 0;
       for (int i = 0; i < srcH; i++)
       {
              for(int ii=0;ii<srcW;ii++)
              {
                     argb = srcPixels[i*srcW+ii];
                     a = ((argb & 0xff000000) >> 24); // alpha channel
                     r = ((argb & 0x00ff0000) >> 16); // red channel
                     g = ((argb & 0x0000ff00) >> 8); // green channel
                     b = (argb & 0x000000ff); // blue channel
                     if(i+1 == srcH)
                     {
                            r1= 0;
                            g1= 0;
                            b1=0;
                     }
                     else
                     {
                            argb = srcPixels[(i+1)*srcW+ii];
                            //a1 = ((argb & 0xff000000) >> 24); // alpha channel
                            r1 = ((argb & 0x00ff0000) >> 16); // red channel
                            g1 = ((argb & 0x0000ff00) >> 8); // green channel
                            b1 = (argb & 0x000000ff); // blue channel
                     }
                    if(ii+1 == srcW){
                            r2= 0;
                         g2= 0;
                         b2=0;
                    }
                    else
                     {
                           argb = srcPixels[i*srcW+ii+1];
                           r2 = ((argb & 0x00ff0000) >> 16); // red channel
                           g2 = ((argb & 0x0000ff00) >> 8); // green channel
                           b2 = (argb & 0x000000ff); // blue channel
                    }
                     // rr1=(r1-r2)^2 rr2=(r1-r3)^2
                    r = (int)Math.sqrt((double)(2*(r-r1)*(r-r1)+(r-r2)*(r-r2)));
                    g = (int)Math.sqrt((double)(2*(g-g1)*(g-g1)+(g-g2)*(g-g2)));
                    b = (int)Math.sqrt((double)(2*(b-b1)*(b-b1)+(b-b2)*(b-b2)));
                    srcPixels[i*srcW+ii] = ((a << 24) | (r << 16) | (g << 8) | b);
             }
       }
       return drawPixels(srcPixels, srcW, srcH);
}
霓虹灯效果如下图所示。
 

 
由于这里是通过截图给大家演示效果的,如果在真实设备上测试更能体现这些特效的真实性。
关于JavaME中图像特效的介绍就到这里,仅仅通过对像素的操作就还能实现更多的特效,这里我们主要分析了特效实现的原理,方便大家实现更多符合自己应用的特效。
 

 

你可能感兴趣的:(JavaME UI设计之图像特效二)