zoukankan      html  css  js  c++  java
  • 【转】一、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数组不能超过规定的大小,也就是说图片的尺寸不能太大,否则会栈内存溢出

  • 相关阅读:
    matlablib安装Helvetica字体
    word插入矢量图的方法
    字体对应关系
    MySQL8.0.15基于mycat读写分离(windows环境)
    2.MySQL8.0.15主从同步(windows环境)
    1.MySQL8.0.15安装步骤(windows环境)
    mysql自带的压力测试工具
    FreeFileSync + Windows任务计划程序 实现自动备份功能
    FreeFileSync 设置服务器文件自动备份,同时可做本地代码程序同步软件
    dokcer镜像添加ssh服务
  • 原文地址:https://www.cnblogs.com/Couch-potato/p/3774390.html
Copyright © 2011-2022 走看看