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

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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Samego开发资源

简单快捷的退出APP应用

1867
来自专栏项勇

笔记13 | 练习Volley(二)加载网络图片的三种方法

1354
来自专栏QQ音乐技术团队的专栏

yoga 初探

yoga 本是 Facebook 在 React Native 里引入的一种跨平台的基于 CSS 的布局系统,它实现了 Flexbox 规范,随着该系统不断完...

2K0
来自专栏developerHaoz 的安卓之旅

Android Volley 源码解析(三),图片加载的实现

在上一篇文章中,我们一起深入探究了 Volley 的缓存机制,通过源码分析对缓存的工作原理进行了了解,这篇文章将带大家一起探究「Volley 图片加载的实现」,...

1002
来自专栏李蔚蓬的专栏

Android实战_note1(MyMirror_一款小型摄像处理的App)

1.1 Activity.java全文: 注意代码中的注释,其中 handler.sendEmptyMessageDelayed(1,3000);...

962
来自专栏Android研究院

一款强大的文件选择器-PrimPicker

PrimPicker is a load local image and video selector for Android。

1323
来自专栏郭霖

Android ListView异步加载图片乱序问题,原因分析及解决方案

在Android所有系统自带的控件当中,ListView这个控件算是用法比较复杂的了,关键是用法复杂也就算了,它还经常会出现一些稀奇古怪的问题,让人非常头疼。比...

41210
来自专栏向治洪

android bitmap的内存分配和优化

首先Bitmap在Android虚拟机中的内存分配,在Google的网站上给出了下面的一段话  ? 大致的意思也就是说,在Android3.0之前,Bitmap...

3556
来自专栏everhad

札记:android手势识别,MotionEvent

摘要 本文是手势识别输入事件处理的完整学习记录。内容包括输入事件InputEvent响应方式,触摸事件MotionEvent的概念和使用,触摸事件的动作分类、多...

3687
来自专栏Android干货园

【PageLayout】非常简单的一键切换加载-空数据-错误页,支持自定义

Android中经常使用一个空白页和网络错误页用来提高用户体验,给用户一个较好的感官,如果获取到的数据为空,那么会显示一个空白数据页,如果在获取数据的过程中网络...

1223

扫码关注云+社区

领取腾讯云代金券