1-MI-Android多媒体之Bitmap

零、前言

[1].Bitmap是关于图象的类,也就是位图
[2].生成Bitmap对象的方式
[3].BitmapFactory.Options
[4].模糊处理
[5].给一个Bitmap添加倒影
[6].将一个View转换成Bitmap
[7].保存bitmap


一、生成Bitmap对象的方式

1.从文件获取(运行时权限自己处理)
//通过文件绝对路径加载图片
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/DCIM/Camera/iv_500x400.png");
//设置图片到ImageView
mIdIv.setImageBitmap(bitmap);
2.通过res资源加载图片
//通过res资源加载图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.iv_500x400);
mIdIv.setImageBitmap(bitmap);
3.通过流生成bitmap(也可以从网络获取图片流)
try {
    FileInputStream fis = new FileInputStream("/mnt/sdcard/DCIM/Camera/iv_500x400.png");
    Bitmap bitmap = BitmapFactory.decodeStream(fis);
    mIdIv.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

二、BitmapFactory.Options

inJustDecodeBounds=true 只获取信息,不分配内存,防止OOM

测试:用一张76M的图片,分别测试inJustDecodeBounds为true和false
默认值:false 虚拟机直接卡死....
true时图片不显示 可以获取信息

BitmapFactory.Options o = new BitmapFactory.Options();//获取对象
o.inJustDecodeBounds = true;//只获取信息,不分配内存
//通过文件绝对路径加载图片
String pathName = "/sdcard/DCIM/Camera/iv_500x400.bmp";
Bitmap bitmap = BitmapFactory.decodeFile(pathName,o);
L.d(o.outWidth+":" +o.outHeight + L.l());// 5000:4000

inSampleSize 压缩图片
BitmapFactory.Options o = new BitmapFactory.Options();//实例化一个对象
o.inJustDecodeBounds = true;
//通过文件绝对路径加载图片
String pathName = "/sdcard/DCIM/Camera/iv_500x400.bmp";
Bitmap bitmap = BitmapFactory.decodeFile(pathName, o);
int scale;//定义缩放比
if (o.outWidth > 2000) {//可以根据获取的宽高自定义缩放比,这里只是简单处理一下
    scale = 15;
} else {
    scale = 1;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;   //对这张图片设置一个缩放值
bitmap = BitmapFactory.decodeFile(pathName, o2);
mIdIv.setImageBitmap(bitmap);
缩小15倍.png
inPreferredConfig:设置色彩模式
默认值是ARGB_8888,一个像素点占用4bytes空间
一般对透明度不做要求的话,RGB_565模式,一个像素点占用2bytes。

还有几个参数就了解了,一般这几个就够用了


下面是我收集的一些Bitmap使用函数

三、模糊处理

模糊.png
使用:
String pathName = "/sdcard/DCIM/Camera/iv_500x400.png";
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
bitmap = BMUtils.blurBitmap(this, bitmap,12f);
mIdIv.setImageBitmap(bitmap);
函数:注意radius在0~25直接,不然会崩
/**
 * @param ctx    上下文
 * @param bitmap 图片
 * @param radius 0 < r <= 25
 * @return 图片
 */
public static Bitmap blurBitmap(Context ctx, Bitmap bitmap, float radius) {
    Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(),
            bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    RenderScript rs = RenderScript.create(ctx);
    ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs,
            Element.U8_4(rs));
    Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
    Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
    blurScript.setRadius(radius);
    blurScript.setInput(allIn);
    blurScript.forEach(allOut);
    allOut.copyTo(outBitmap);
    bitmap.recycle();
    rs.destroy();
    return outBitmap;

四、给一个Bitmap添加倒影

倒影.png
使用:
String pathName = "/sdcard/DCIM/Camera/iv_500x400.png";
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
bitmap = BMUtils.createReflectedBitmap(bitmap);
mIdIv.setImageBitmap(bitmap);

方法:
/**
 * 给一个Bitmap添加倒影
 *
 * @param originalImage 初始Bitmap
 * @return 添加倒影后的Bitmap
 */
public static Bitmap createReflectedBitmap(Bitmap originalImage) {
    final int reflectionGap = 4;//倒影间距
    int width = originalImage.getWidth();
    int height = originalImage.getHeight();
    // 沿Y轴镜像矩阵
    Matrix matrix = new Matrix();
    matrix.preScale(1, -1);
    Bitmap reflectionImage = Bitmap.createBitmap(
            originalImage, 0, height / 2, width, height / 2, matrix, false);
    Bitmap bitmapWithReflection = Bitmap.createBitmap(
            width, (height + height / 2), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmapWithReflection);
    canvas.drawBitmap(originalImage, 0, 0, null);
    Paint defPaint = new Paint();
    canvas.drawRect(0, height, width, height + reflectionGap, defPaint);
    canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(
            0, originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
            + reflectionGap, 0x70B6BEEE, 0x00ffffff, Shader.TileMode.CLAMP);
    paint.setShader(shader);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);
    return bitmapWithReflection;
}

五、将一个View转换成Bitmap

view转Bitmap.png
用法:这里将一个按钮转换成Bitmap设置给ImageView
bitmap = BMUtils.createBitmapFromView(mBtnLoadBitmap);
mIdIv.setImageBitmap(bitmap);
方法
 private static final Canvas sCanvas = new Canvas();
 /**
  * 通过一个View获取Bitmap
  *
  * @param view view
  * @return Bitmap
  */
 public static Bitmap createBitmapFromView(View view) {
     if (view instanceof ImageView) {
         Drawable drawable = ((ImageView) view).getDrawable();
         if (drawable != null && drawable instanceof BitmapDrawable) {
             return ((BitmapDrawable) drawable).getBitmap();
         }
     }
     view.clearFocus();
     Bitmap bitmap = createBitmapSafely(view.getWidth(),
             view.getHeight(), Bitmap.Config.ARGB_8888, 1);
     if (bitmap != null) {
         synchronized (sCanvas) {
             Canvas canvas = sCanvas;
             canvas.setBitmap(bitmap);
             view.draw(canvas);
             canvas.setBitmap(null);
         }
     }
     return bitmap;
 }
 private static Bitmap createBitmapSafely(int width, int height, Bitmap.Config config, int retryCount) {
     try {
         return Bitmap.createBitmap(width, height, config);
     } catch (OutOfMemoryError e) {
         e.printStackTrace();
         if (retryCount > 0) {
             System.gc();
             return createBitmapSafely(width, height, config, retryCount - 1);
         }
         return null;
     }
 }

六、保存bitmap

注意写入权限
使用了文件保存封装类,详见:SD卡存储

保存Bitmap.png
BMUtils.saveBitmap("bitmap/button", bitmap);

方法:

/**
 * 保存bitmap到本地
 *
 * @param path    路径
 * @param mBitmap 图片
 * @return 路径
 */
public static String saveBitmap(String path, Bitmap mBitmap) {
    File filePic = FileHelper.get().createFile(path + ".png");
    try {
        FileOutputStream fos = new FileOutputStream(filePic);
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    return filePic.getAbsolutePath();
}

后记、

1.声明:

[1]本文由张风捷特烈原创,转载请注明
[2]欢迎广大编程爱好者共同交流
[3]个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
[4]你的喜欢与支持将是我最大的动力

2.连接传送门:

更多安卓技术欢迎访问:安卓技术栈
我的github地址:欢迎star
简书首发,腾讯云+社区同步更新
张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com

3.联系我

QQ:1981462002
邮箱:1981462002@qq.com
微信:zdl1994328

4.欢迎关注我的微信公众号,最新精彩文章,及时送达:
公众号.jpg

我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。

上一篇:floating IP 原理分析 - 每天5分钟玩转 OpenStack(107)


下一篇:《大数据分析原理与实践》——3.3 相关分析