BitmapUtil+高斯模糊算法

public class BitmapUtil {
private static final String TAG = “BitmapUtil”;

// private Bitmap resultBitmap = null;

/**
 * bitmap转byte[]
 *
 * @param bm
 * @return
 */
public byte[] Bitmap2Bytes(Bitmap bm) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
    return baos.toByteArray();
}

/**
 * byte[]转bitmap
 *
 * @param b
 * @return
 */
public Bitmap Bytes2Bimap(byte[] b) {
    if (b.length != 0) {
        return BitmapFactory.decodeByteArray(b, 0, b.length);
    } else {
        return null;
    }
}

/**
 * bitmap的缩放
 *
 * @param bitmap
 * @param width
 * @param height
 * @return
 */
public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Matrix matrix = new Matrix();
    float scaleWidth = ((float) width / w);
    float scaleHeight = ((float) height / h);
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
    return newbmp;
}

/**
 * drawable转bitmap
 *
 * @param drawable
 * @return
 */
public static Bitmap drawableToBitmap(Drawable drawable) {
    // 取 drawable 的长宽
    int w = drawable.getIntrinsicWidth();
    int h = drawable.getIntrinsicHeight();

    // 取 drawable 的颜色格式
    Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
            : Bitmap.Config.RGB_565;
    // 建立对应 bitmap
    Bitmap bitmap = Bitmap.createBitmap(w, h, config);
    // 建立对应 bitmap 的画布
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, w, h);
    // 把 drawable 内容画到画布中
    drawable.draw(canvas);
    return bitmap;
}

/**
 * 获得圆角图片
 *
 * @param bitmap
 * @param roundPx
 * @return
 */
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, w, h);
    final RectF rectF = new RectF(rect);
    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;
}

/**
 * 获得带倒影的图片
 *
 * @param bitmap
 * @return
 */
public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
    final int reflectionGap = 4;
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    Matrix matrix = new Matrix();
    matrix.preScale(1, -1);

    Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w,
            h / 2, matrix, false);

    Bitmap bitmapWithReflection = Bitmap.createBitmap(w, (h + h / 2),
            Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bitmapWithReflection);
    canvas.drawBitmap(bitmap, 0, 0, null);
    Paint deafalutPaint = new Paint();
    canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint);

    canvas.drawBitmap(reflectionImage, 0, h + reflectionGap, null);

    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
            bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
            0x00ffffff, Shader.TileMode.CLAMP);
    paint.setShader(shader);
    // Set the Transfer mode to be porter duff and destination in
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    // Draw a rectangle using the paint with our linear gradient
    canvas.drawRect(0, h, w, bitmapWithReflection.getHeight()
            + reflectionGap, paint);

    return bitmapWithReflection;
}

/**
 * bitmap转drawable
 *
 * @param bitmap
 * @return
 */
public static Drawable bitmapToDrawable(Bitmap bitmap) {
    BitmapDrawable bd = new BitmapDrawable(bitmap);
    return bd;
}

/**
 * drawable的缩放
 *
 * @param drawable
 * @param w
 * @param h
 * @return
 */
public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
    int width = drawable.getIntrinsicWidth();
    int height = drawable.getIntrinsicHeight();
    // drawable转换成bitmap
    Bitmap oldbmp = drawableToBitmap(drawable);
    // 创建操作图片用的Matrix对象
    Matrix matrix = new Matrix();
    // 计算缩放比例
    float sx = ((float) w / width);
    float sy = ((float) h / height);
    // 设置缩放比例
    matrix.postScale(sx, sy);
    // 建立新的bitmap,其内容是对原bitmap的缩放后的图
    Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,
            matrix, true);
    return new BitmapDrawable(newbmp);
}

/**
 * 根据view来生成bitmap图片,可用于截图功能
 */

public static Bitmap getViewBitmap(View v) {
    v.clearFocus(); //
    v.setPressed(false); //
    // 能画缓存就返回false
    boolean willNotCache = v.willNotCacheDrawing();
    v.setWillNotCacheDrawing(false);
    int color = v.getDrawingCacheBackgroundColor();
    v.setDrawingCacheBackgroundColor(0);
    if (color != 0) {
        v.destroyDrawingCache();
    }
    v.buildDrawingCache();
    Bitmap cacheBitmap = v.getDrawingCache();
    if (cacheBitmap == null) {
        return null;
    }
    Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
    // Restore the view
    v.destroyDrawingCache();
    v.setWillNotCacheDrawing(willNotCache);
    v.setDrawingCacheBackgroundColor(color);
    return bitmap;
}

/**
 * 保存Bitmap图片为本地文件
 */
public static void saveFile(Bitmap bitmap, String filename) {
    FileOutputStream fileOutputStream = null;
    try {
        fileOutputStream = new FileOutputStream(filename);
        if (fileOutputStream != null) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        }
    } catch (FileNotFoundException e) {
        ZnzLog.d(TAG, "Exception:FileNotFoundException");
        e.printStackTrace();
    } catch (IOException e) {
        ZnzLog.d(TAG, "IOException:IOException");
        e.printStackTrace();
    }
}

/**
 * 将资源转成drawbale
 *
 * @param context
 * @param resId
 * @return
 */
public static Drawable getResourceDrawable(Context context, int resId) {
    Resources resources = context.getResources();
    return resources.getDrawable(resId);
}

/**
 * 从资源中获取bitmap
 *
 * @param resId
 * @return
 */
public static Bitmap getResourceBitmap(Context context, int resId) {
    InputStream is = context.getResources().openRawResource(resId);
    return BitmapFactory.decodeStream(is);
}

/**
 * bitmap转uri
 *
 * @param bitmap
 * @param context
 * @return
 */
public static Uri bitmapToUri(Bitmap bitmap, Context context) {
    Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, null, null));
    return uri;
}

/**
 * uri转bitmap
 *
 * @param uri
 * @param context
 * @return
 */
public static Bitmap uriToBitmap(Uri uri, Context context) {
    Bitmap bitmap = null;
    try {
        bitmap = zoomBitmap(MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri), 200, 200);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bitmap;
}

public static boolean saveBitmap2file(Bitmap bmp, String filename) {
    Bitmap.CompressFormat format = Bitmap.CompressFormat.PNG;
    int quality = 90;
    OutputStream stream = null;
    try {
        stream = new FileOutputStream("/sdcard/" + filename);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return bmp.compress(format, quality, stream);
}

private static Bitmap big(Bitmap bitmap) {
    Matrix matrix = new Matrix();
    matrix.postScale(1.5f, 1.5f); //长和宽放大缩小的比例
    Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    return resizeBmp;
}

public static File small(File file) {
    Bitmap bitmap = null;
    File resultFile = file;

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true; //不把图片读到内存中
    bitmap = BitmapFactory.decodeFile(resultFile.getPath(), options);
    int height = options.outHeight;
    int width = options.outWidth;

    int scale = 1;
    if (height > 1000 || width > 1000)
        scale = 2;
    if (height > 2000 || width > 2000)
        scale = 3;
    if (height > 300 || width > 3000)
        scale = 4;

    // 开始压缩
    options.inSampleSize = scale;
    options.inJustDecodeBounds = false;
    Bitmap bitmap2 = BitmapFactory.decodeFile(resultFile.getPath(), options);

    try {
        FileOutputStream out = new FileOutputStream(resultFile, false);
        bitmap2.compress(Bitmap.CompressFormat.PNG, 30, out);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    return resultFile;
}

/**
 * 转换图片成圆形
 *
 * @param bitmap 传入Bitmap对象
 * @return
 */
public static Bitmap toRoundBitmap(Bitmap bitmap) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    float roundPx;
    float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
    if (width <= height) {
        roundPx = width / 2;
        left = 0;
        top = 0;
        right = width;
        bottom = width;
        height = width;
        dst_left = 0;
        dst_top = 0;
        dst_right = width;
        dst_bottom = width;
    } else {
        roundPx = height / 2;
        float clip = (width - height) / 2;
        left = clip;
        right = width - clip;
        top = 0;
        bottom = height;
        width = height;
        dst_left = 0;
        dst_top = 0;
        dst_right = height;
        dst_bottom = height;
    }

    Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
    final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
    final RectF rectF = new RectF(dst);

    paint.setAntiAlias(true);// 设置画笔无锯齿

    canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas
    paint.setColor(color);

    // 以下有两种方法画圆,drawRounRect和drawCircle
    // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// 画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。
    canvas.drawCircle(roundPx, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 设置两张图片相交时的模式,参考http://trylovecatch.iteye.com/blog/1189452
    canvas.drawBitmap(bitmap, src, dst, paint); //以Mode.SRC_IN模式合并bitmap和已经draw了的Circle

    return output;
}

}
//
//
//
public class FastBlur {

/**
 * 高斯模糊逻辑处理
 *
 * @param ivShowBlur // 用于显示高斯模糊的图层
 * @param frame      // 需要进行高斯模糊的布局
 * @param isShowBlur // 是否显示高斯模糊图层
 */
public static void showBlur(ImageView ivShowBlur, ViewGroup frame, boolean isShowBlur) {
    if (!isShowBlur) {
        ivShowBlur.setVisibility(View.GONE);
        return;
    }
    frame.setDrawingCacheEnabled(true);
    frame.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    frame.buildDrawingCache();
    Bitmap bitmap = frame.getDrawingCache(); // 对frame截屏作为高斯模糊原图

    float radius = 2; // 高斯模糊程度,为radius/scaleFactor 既20/10 = 2
    float scaleFactor = 10; // 缩小图片比例,使其丢失一些像素点,提高高斯模糊算法效率

    Bitmap overlay = Bitmap.createBitmap((int) (bitmap.getWidth() / scaleFactor), (int) (bitmap.getHeight() / scaleFactor), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(overlay);
    canvas.scale(1 / scaleFactor, 1 / scaleFactor);

    canvas.drawBitmap(bitmap, 0, 0, null);

    overlay = FastBlur.doBlur(overlay, (int) radius, true); // 高斯模糊计算获取新bitmap
    ivShowBlur.setVisibility(View.VISIBLE); // 显示覆盖在frame上的一层图片
    ivShowBlur.setImageBitmap(overlay);
}


/**
 * 高斯模糊算法
 *
 * @param sentBitmap
 * @param radius
 * @param canReuseInBitmap
 * @return
 */
public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
    Bitmap bitmap = null;
    try {
        if (canReuseInBitmap) {
            bitmap = sentBitmap;
        } else {
            bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        }

        if (radius < 1) {
            return (null);
        }

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);

        int wm = w - 1;
        int hm = h - 1;
        int wh = w * h;
        int div = radius + radius + 1;

        int r[] = new int[wh];
        int g[] = new int[wh];
        int b[] = new int[wh];
        int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        int vmin[] = new int[Math.max(w, h)];

        int divsum = (div + 1) >> 1;
        divsum *= divsum;
        int dv[] = new int[256 * divsum];
        for (i = 0; i < 256 * divsum; i++) {
            dv[i] = (i / divsum);
        }

        yw = yi = 0;

        int[][] stack = new int[div][3];
        int stackpointer;
        int stackstart;
        int[] sir;
        int rbs;
        int r1 = radius + 1;
        int routsum, goutsum, boutsum;
        int rinsum, ginsum, binsum;

        for (y = 0; y < h; y++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            for (i = -radius; i <= radius; i++) {
                p = pix[yi + Math.min(wm, Math.max(i, 0))];
                sir = stack[i + radius];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rbs = r1 - Math.abs(i);
                rsum += sir[0] * rbs;
                gsum += sir[1] * rbs;
                bsum += sir[2] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
            }
            stackpointer = radius;

            for (x = 0; x < w; x++) {

                r[yi] = dv[rsum];
                g[yi] = dv[gsum];
                b[yi] = dv[bsum];

                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;

                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];

                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];

                if (y == 0) {
                    vmin[x] = Math.min(x + radius + 1, wm);
                }
                p = pix[yw + vmin[x]];

                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);

                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];

                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;

                stackpointer = (stackpointer + 1) % div;
                sir = stack[(stackpointer) % div];

                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];

                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];

                yi++;
            }
            yw += w;
        }
        for (x = 0; x < w; x++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            yp = -radius * w;
            for (i = -radius; i <= radius; i++) {
                yi = Math.max(0, yp) + x;

                sir = stack[i + radius];

                sir[0] = r[yi];
                sir[1] = g[yi];
                sir[2] = b[yi];

                rbs = r1 - Math.abs(i);

                rsum += r[yi] * rbs;
                gsum += g[yi] * rbs;
                bsum += b[yi] * rbs;

                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }

                if (i < hm) {
                    yp += w;
                }
            }
            yi = x;
            stackpointer = radius;
            for (y = 0; y < h; y++) {
                // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];

                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;

                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];

                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];

                if (x == 0) {
                    vmin[y] = Math.min(y + r1, hm) * w;
                }
                p = x + vmin[y];

                sir[0] = r[p];
                sir[1] = g[p];
                sir[2] = b[p];

                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];

                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;

                stackpointer = (stackpointer + 1) % div;
                sir = stack[stackpointer];

                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];

                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];

                yi += w;
            }
        }

        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
    } catch (Exception e) {
        e.printStackTrace();
        bitmap = BitmapUtil.getResourceBitmap(ZnzApplication.getContext(), R.mipmap.default_header);
    }

    return bitmap;
}


@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
public static Bitmap blurBitmap(Bitmap bitmap, Context context) {

    //Let's create an empty bitmap with the same size of the bitmap we want to blur
    Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

    //Instantiate a new Renderscript
    RenderScript rs = RenderScript.create(context);

    //Create an Intrinsic Blur Script using the Renderscript
    ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

    //Create the Allocations (in/out) with the Renderscript and the in/out bitmaps
    Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
    Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);

    //Set the radius of the blur: 0 < radius <= 25
    blurScript.setRadius(25.0f);

    //Perform the Renderscript
    blurScript.setInput(allIn);
    blurScript.forEach(allOut);

    //Copy the final bitmap created by the out Allocation to the outBitmap
    allOut.copyTo(outBitmap);

    //recycle the original bitmap
    bitmap.recycle();

    //After finishing everything, we destroy the Renderscript.
    rs.destroy();

    return outBitmap;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值