java实现Android高斯模糊思路
博客专区 > march_kk 的博客 > 博客详情
java实现Android高斯模糊思路
march_kk 发表于8个月前
java实现Android高斯模糊思路
  • 发表于 8个月前
  • 阅读 13
  • 收藏 0
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

public class GaussFilterTask extends AsyncTask<Void, Double, Void> {

    private Bitmap bitmap;
    private Bitmap target;
    private Context context;
    private View imageTarget;

    public GaussFilterTask(Context context, ImageView imageTarget) {
        super();
        this.context = context;
        Drawable drawable = imageTarget.getDrawable();
        this.imageTarget = imageTarget;
        bitmap = ((BitmapDrawable) drawable).getBitmap();
        bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 20, bitmap.getHeight() / 20, false);
    }


    public GaussFilterTask(Context context, View imageTarget, Bitmap bitmap) {
        super();
        this.context = context;
        this.imageTarget = imageTarget;
        this.bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 20, bitmap.getHeight() / 20, false);
    }

    @Override
    protected Void doInBackground(Void... params) {
        gaussBlur(bitmap, target);//调用高斯模糊方法
        return null;
    }


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        target = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
    }


    @Override
    protected void onProgressUpdate(Double... values) {
        super.onProgressUpdate(values);
    }

    @TargetApi(Build.VERSION_CODES.DONUT)
    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        if (imageTarget instanceof ImageView) {
            ((ImageView) imageTarget).setImageDrawable(new BitmapDrawable(context.getResources(), target));
        } else {
            imageTarget.setBackgroundDrawable(new BitmapDrawable(context.getResources(), target));
        }

    }


    private void gaussBlur(Bitmap src, Bitmap target) {
        if (src.getConfig() != Bitmap.Config.ARGB_8888) {//简化考虑,只支持ARGB8888格式的Bitmap,即 透明、红、绿、蓝四个通道各占一个字节
            return;
        }

        int boxWidth = 7;//盒子大小为7x7
        int boxHeight = 7;
        GaussFilter filter = new GaussFilter(boxHeight, boxWidth);//实例化GaussFilter,并传递给filter()方法

        for (int i = 0; i < src.getHeight(); i++) {
            for (int j = 0; j < src.getWidth(); j++) {
                int meanPixel = filter(boxWidth, boxHeight, i, j, src, filter);

                target.setPixel(j, i, meanPixel);

            }

        }

    }


    /**
     * 根据滤波模板进行滤波
     *
     * @param boxWidth  盒子宽度(此处为3)
     * @param boxHeight 盒子高度(此处为3)
     * @param rowIndex  targetBitmap的目标像素点在第xx行
     * @param colIndex  targetBitmap的目标像素点在第xx列
     * @param src       源Bitmap
     * @param filter    滤波模板
     * @return
     */
    private int filter(int boxWidth, int boxHeight, int rowIndex, int colIndex, Bitmap src, Filter filter) {
        if (boxWidth % 2 == 0 || boxHeight % 2 == 0)
            return 0;

        int targetPixel = 0xff000000;//计算的结果
        int redSum = 0;
        int greenSum = 0;
        int blueSum = 0;
        int temp;

        for (int i = rowIndex - boxHeight / 2, boxRow = 0; i <= rowIndex + boxHeight / 2; i++, boxRow++) {
            for (int j = colIndex - boxWidth / 2, boxCol = 0; j <= colIndex + boxWidth / 2; j++, boxCol++) {
                if (i < 0 || i >= src.getHeight() || j < 0 || j >= src.getWidth()) //越界
                    temp = src.getPixel(colIndex, rowIndex);
                else
                    temp = src.getPixel(j, i);//依次取出盒子内的像素点
                redSum += ((temp & 0x00ff0000) >> 16) * filter.weight(boxRow, boxCol);//求均值,先计算sum,对于 均值模糊, 这里的weight为1
                greenSum += ((temp & 0x0000ff00) >> 8) * filter.weight(boxRow, boxCol);//求均值,先计算sum,对于 均值模糊, 这里的weight为1
                blueSum += (temp & 0x000000ff) * filter.weight(boxRow, boxCol);//求均值,先计算sum,对于 均值模糊, 这里的weight为1
            }
        }

        int meanRed = ((int) (redSum * 1.0 / filter.total())) << 16;//ARGB red通道需要左移16bit归位,对于 均值模糊, 这里的total为9
        int meanGreen = ((int) (greenSum * 1.0 / filter.total())) << 8;//ARGB green通道需要左移8bit归位,对于 均值模糊, 这里的total为9
        int meanBlue = ((int) (blueSum * 1.0 / filter.total()));//,对于 均值模糊, 这里的total为9
        targetPixel = (targetPixel | meanRed | meanGreen | meanBlue);//或运算 将3个求均值的结果合一
        return targetPixel;
    }


    /**
     * Created by zjl on 2016/12/13.
     * 使用二项式分布逼近的高斯滤波器
     */
    private class GaussFilter implements Filter {

        private int width;
        private int height;

        public GaussFilter(int boxHeight, int boxWidth) {
            this.height = boxHeight;
            this.width = boxWidth;

        }

        @Override
        public int weight(int rowIndex, int colIndex) {
            int me = C(width - 1, colIndex);
            return me * C(height - 1, rowIndex);
        }

        @Override
        public int total() {
            int result = (int) Math.pow(2, width + height - 2);
            return result;
        }

        private int C(int n, int k) { //n次二项展开式,第k项
            if (k <= 0)
                return 1;
            if (k > n / 2)
                return C(n, n - k);

            int result = 1;
            for (int i = 1; i <= k; i++)
                result *= (n - i + 1);
            for (int i = 1; i <= k; i++)
                result /= i;

            return result;
        }


    }


    public interface Filter {
        int weight(int rowIndex, int colIndex);//盒子元素与滤波模板元素做乘积最后求平均,在均值模糊中,这里的weight为1

        int total();//前面求出sum然后除以total求出最后的平均颜色值
    }

}

 

标签: Android 高斯模糊
共有 人打赏支持
粉丝 0
博文 15
码字总数 2826
评论 (0)
×
march_kk
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: