-
作者:杨丰盛上一篇我们分析了处理图片特效的原理,通常是将图像数据转换为一个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 channelr = 255 - ((argb & 0x00ff0000) >> 16); // red channelg = 255 - ((argb & 0x0000ff00) >> 8); // green channelb = 255 - (argb & 0x000000ff); // blue channelsrcPixels[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 channelr = ((argb & 0x00ff0000) >> 16); // red channelg = ((argb & 0x0000ff00) >> 8); // green channelb = (argb & 0x000000ff); // blue channeltemp = (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 channelr = ((argb & 0x00ff0000) >> 16); // red channelg = ((argb & 0x0000ff00) >> 8); // green channelb = (argb & 0x000000ff); // blue channelif(i+1 == srcH){r1= 0;g1= 0;b1=0;}else{argb = srcPixels[(i+1)*srcW+ii];r1 = ((argb & 0x00ff0000) >> 16); // red channelg1 = ((argb & 0x0000ff00) >> 8); // green channelb1 = (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 channelg2 = ((argb & 0x0000ff00) >> 8); // green channelb2 = (argb & 0x000000ff); // blue channel}// rr1=(r1-r2)^2 rr2=(r1-r3)^2r = (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 channelg =255-g; // green channelb =255-b; // blue channelsrcPixels[i*srcW+ii] = ((a << 24) | (r << 16) | (g << 8) | b);}}return drawPixels(srcPixels, srcW, srcH);}通过该函数实现的粉笔画效果如下图所示。
JavaME UI设计之图像特效二
发表在 2011.01.25 13:04 GMT+8-
zhangjj
帖子 : 27
加入日期 : 2010.08.04 10:28 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 channelr = ((argb & 0x00ff0000) >> 16); // red channelg = ((argb & 0x0000ff00) >> 8); // green channelb = (argb & 0x000000ff); // blue channelr = (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 channelr = ((argb & 0x00ff0000) >> 16); // red channelg = ((argb & 0x0000ff00) >> 8); // green channelb = (argb & 0x000000ff); // blue channelif(i+1 == srcH){r1= 0;g1= 0;b1=0;}else{argb = srcPixels[(i+1)*srcW+ii];//a1 = ((argb & 0xff000000) >> 24); // alpha channelr1 = ((argb & 0x00ff0000) >> 16); // red channelg1 = ((argb & 0x0000ff00) >> 8); // green channelb1 = (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 channelg2 = ((argb & 0x0000ff00) >> 8); // green channelb2 = (argb & 0x000000ff); // blue channel}// rr1=(r1-r2)^2 rr2=(r1-r3)^2r = (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设计之图像特效二
发表在 2011.01.25 13:07 GMT+8