一、android图片特效处理之模糊效果

这篇将讲到图片特效处理的模糊效果。跟前面一样是对像素点进行处理,算法是通用的,但耗时会更长,至于为什么,看了下面的代码你就会明白。

算法:

一、简单算法:将像素点周围八个点包括自身一共九个点的RGB值分别相加后平均,作为当前像素点的RGB值,即可实现效果。

举例:

ABC

DEF

GHI

假如当前点是E,那么会有:

E.r = (A.r + B.r + C.r + D.r + E.r + F.r + G.r + H.r + I.r) / 9  // r表示的是E像素点RGB值的R值

E像素点的GB值类似。

二、采用高斯模糊

高斯矩阵

int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };

算法是:将九个点的RGB值分别与高斯矩阵中的对应项相乘的和,然后再除以一个相应的值作为当前像素点的RGB值。

举例:(还是上面的九个点)
假如当前点是E,那么会有:

int delta = 16;
E.r =( A.r * gauss[0] + B.r * gauss[1] + C.r * gauss[2] + D.r * gauss[3] + E.r * gauss[4] + F.r * gauss[5] + G.r * gauss[6] + H.r * gauss[7] + I.r * gauss[8]) / delta

E像素点的GB值类似,delta的取值貌似没有规定值,可以自己设置任意值,但要想达到效果,能设的值很少,下面图片是值为16的效果。
处理效果:

原图片:

处理后:

 

两种处理方式的代码:

/**
     * 模糊效果
     * @param bmp
     * @return
     */
    private Bitmap blurImage(Bitmap bmp)
    {
        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        
        int pixColor = 0;
        
        int newR = 0;
        int newG = 0;
        int newB = 0;
        
        int newColor = 0;
        
        int[][] colors = new int[9][3];
        for (int i = 1, length = width - 1; i < length; i++)
        {
            for (int k = 1, len = height - 1; k < len; k++)
            {
                for (int m = 0; m < 9; m++)
                {
                    //(s,p)就是上面的E点,switch语句的0~8共9个分支代表了围绕E(包括E点)的9个点坐标
                    int s = 0;
                    int p = 0;
                    switch(m)
                    {
                    case 0:
                        s = i - 1;
                        p = k - 1;
                        break;
                    case 1:
                        s = i;
                        p = k - 1;
                        break;
                    case 2:
                        s = i + 1;
                        p = k - 1;
                        break;
                    case 3:
                        s = i + 1;
                        p = k;
                        break;
                    case 4:
                        s = i + 1;
                        p = k + 1;
                        break;
                    case 5:
                        s = i;
                        p = k + 1;
                        break;
                    case 6:
                        s = i - 1;
                        p = k + 1;
                        break;
                    case 7:
                        s = i - 1;
                        p = k;
                        break;
                    case 8:
                        s = i;
                        p = k;
                    }
                    pixColor = bmp.getPixel(s, p);
                    //分别取得这些点的R,G,B值
                    colors[m][0] = Color.red(pixColor);
                    colors[m][1] = Color.green(pixColor);
                    colors[m][2] = Color.blue(pixColor);
                }
                //9个点的R,G,B值分别相加
                for (int m = 0; m < 9; m++)
                {
                    newR += colors[m][0];
                    newG += colors[m][1];
                    newB += colors[m][2];
                }
                //再取平均
                newR = (int) (newR / 9F);
                newG = (int) (newG / 9F);
                newB = (int) (newB / 9F);
                //保证每个值的范围在0~255
                newR = Math.min(255, Math.max(0, newR));
                newG = Math.min(255, Math.max(0, newG));
                newB = Math.min(255, Math.max(0, newB));
                
                newColor = Color.argb(255, newR, newG, newB);
                bitmap.setPixel(i, k, newColor);
                
                newR = 0;
                newG = 0;
                newB = 0;
            }
        }
        
        return bitmap;
    }
    
    /**
     * 柔化效果(高斯模糊)(优化后比上面快三倍)
     * @param bmp
     * @return
     */
    private Bitmap blurImageAmeliorate(Bitmap bmp)
    {
        long start = System.currentTimeMillis();
        // 高斯矩阵
        int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
        
        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        
        int pixR = 0;
        int pixG = 0;
        int pixB = 0;
        
        int pixColor = 0;
        
        int newR = 0;
        int newG = 0;
        int newB = 0;
        
        int delta = 16; // 值越小图片会越亮,越大则越暗
        
        int idx = 0;
        int[] pixels = new int[width * height];
        bmp.getPixels(pixels, 0, width, 0, 0, width, height);
        for (int i = 1, length = height - 1; i < length; i++)
        {
            for (int k = 1, len = width - 1; k < len; k++)
            {
                idx = 0;
                for (int m = -1; m <= 1; m++)
                {
                    for (int n = -1; n <= 1; n++)
                    {
                        pixColor = pixels[(i + m) * width + k + n];
                        pixR = Color.red(pixColor);
                        pixG = Color.green(pixColor);
                        pixB = Color.blue(pixColor);
                        
                        newR = newR + (int) (pixR * gauss[idx]);
                        newG = newG + (int) (pixG * gauss[idx]);
                        newB = newB + (int) (pixB * gauss[idx]);
                        idx++;
                    }
                }
                
                newR /= delta;
                newG /= delta;
                newB /= delta;
                
                newR = Math.min(255, Math.max(0, newR));
                newG = Math.min(255, Math.max(0, newG));
                newB = Math.min(255, Math.max(0, newB));
                
                pixels[i * width + k] = Color.argb(255, newR, newG, newB);
                
                newR = 0;
                newG = 0;
                newB = 0;
            }
        }
        
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        long end = System.currentTimeMillis();
        Log.d("may", "used time="+(end - start));
        return bitmap;
    }

在优化后的代码中要注意了,pixels数组不能超过规定的大小,也就是说图片的尺寸不能太大,否则会栈内存溢出

【转】一、android图片特效处理之模糊效果,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。