写点什么

内存优化(二),kotlin 协程原理

用户头像
Android架构
关注
发布于: 刚刚

}


options.inJustDecodeBounds = false;


options.inSampleSize = inSampleSize;


return BitmapFactory.decodeFile(filePath, options);


}


  • 方式二 (效率高于方式一)


/**


  • 获取缩放后的本地图片

  • @param filePath 文件路径

  • @param width 宽

  • @param height 高

  • @return


*/


public static Bitmap readBitmapFromFileDescriptor(String filePath, int width, int height) {


try {


FileInputStream fis = new FileInputStream(filePath);


BitmapFactory.Options options = new BitmapFactory.Options();


options.inJustDecodeBounds = true;


BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options);


float srcWidth = options.outWidth;


float srcHeight = options.outHeight;


int inSampleSize = 1;


if (srcHeight > height || srcWidth > width) {


if (srcWidth > srcHeight) {


inSampleSize = Math.round(srcHeight / height);


} else {


inSampleSize = Math.round(srcWidth / width);


}


}


options.inJustDecodeBounds = false;


options.inSampleSize = inSampleSize;


return BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options);


} catch (Exception ex) {


}


return null;


}

2. 从输入流中读取文件(网络加载)

/**


  • 获取缩放后的本地图片

  • @param ins 输入流

  • @param width 宽

  • @param height 高

  • @return


*/


public static Bitmap readBitmapFromInputStream(InputStream ins, int width, int height) {


BitmapFactory.Options options = new BitmapFactory.Options();


options.inJustDecodeBounds = true;


BitmapFactory.decodeStream(ins, null, options);


float srcWidth = options.outWidth;


float srcHeight = options.outHeight;


int inSampleSize = 1;


if (srcHeight > height || srcWidth > width) {


if (srcWidth > srcHeight) {


inSampleSize = Math.round(srcHeight / height);


} else {


inSampleSize = Math.round(srcWidth / width);


}


}


options.inJustDecodeBounds = false;


options.inSampleSize = inSampleSize;


return BitmapFactory.decodeStream(ins, null, options);


}

3.Resource 资源加载

  1. Res 资源加载方式:


public static Bitmap readBitmapFromResource(Resources resources, int resourcesId, int width, int height) {


BitmapFactory.Options options = new BitmapFactory.Options();


options.inJustDecodeBounds = true;


BitmapFactory.decodeResource(resources, resourcesId, options);


float srcWidth = options.outWidth;


float srcHeight = options.outHeight;


int inSampleSize = 1;


if (srcHeight > height || srcWidth > width) {


if (srcWidth > srcHeight) {


inSampleSize = Math.round(srcHeight / height);


} else {


inSampleSize = Math.round(srcWidth / width);


}


}


options.inJustDecodeBounds = false;


options.inSampleSize = inSampleSize;


return BitmapFactory.decodeResource(resources, resourcesId, options);


}


此种方式相当的耗费内存 建议采用 decodeStream 代替 decodeResource 可以如下形式:


public static Bitmap readBitmapFromResource(Resources resources, int resourcesId, int width, int height) {


InputStream ins = resources.openRawResource(resourcesId);


BitmapFactory.Options options = new BitmapFactory.Options();


options.inJustDecodeBounds = true;


BitmapFactory.decodeStream(ins, null, options);


float srcWidth = options.outWidth;


float srcHeight = options.outHeight;


int inSampleSize = 1;


if (srcHeight > height || srcWidth > width) {


if (srcWidth > srcHeight) {


inSampleSize = Math.round(srcHeight / height);


} else {


inSampleSize = Math.round(srcWidth / width);


}


}


options.inJustDecodeBounds = false;


options.inSampleSize = inSampleSize;


return BitmapFactory.decod


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


eStream(ins, null, options);


}


BitmapFactory.decodeResource 加载的图片可能会经过缩放,该缩放目前是放在 java 层做的,效率比较低,而且需要消耗 java 层的内存。因此,如果大量使用该接口加载图片,容易导致 OOM 错误


BitmapFactory.decodeStream 不会对所加载的图片进行缩放,相比之下占用内存少,效率更高。


这两个接口各有用处,如果对性能要求较高,则应该使用 decodeStream;如果对性能要求不高,且需要 Android 自带的图片自适应缩放功能,则可以使用 decodeResource。


  1. Assets 资源加载方式:


/**


  • 获取缩放后的本地图片

  • @param filePath 文件路径,即文件名称

  • @return


*/


public static Bitmap readBitmapFromAssetsFile(Context context, String filePath) {


Bitmap image = null;


AssetManager am = context.getResources().getAssets();


try {


InputStream is = am.open(filePath);


image = BitmapFactory.decodeStream(is);


is.close();


} catch (IOException e) {


e.printStackTrace();


}


return image;


}

4.从二进制数据读取图片

public static Bitmap readBitmapFromByteArray(byte[] data, int width, int height) {


BitmapFactory.Options options = new BitmapFactory.Options();


options.inJustDecodeBounds = true;


BitmapFactory.decodeByteArray(data, 0, data.length, options);


float srcWidth = options.outWidth;


float srcHeight = options.outHeight;


int inSampleSize = 1;


if (srcHeight > height || srcWidth > width) {


if (srcWidth > srcHeight) {


inSampleSize = Math.round(srcHeight / height);


} else {


inSampleSize = Math.round(srcWidth / width);


}


}


options.inJustDecodeBounds = false;


options.inSampleSize = inSampleSize;


return BitmapFactory.decodeByteArray(data, 0, data.length, options);


}




四、Bitmap | Drawable | InputStream | Byte[ ] 之间进行转换




  1. Drawable 转化成 Bitmap


public static Bitmap drawableToBitmap(Drawable drawable) {


Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);


Canvas canvas = new Canvas(bitmap);


drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());


drawable.draw(canvas);


return bitmap;


}


drawable 的获取方式:Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);


  1. Bitmap 转换成 Drawable


public static Drawable bitmapToDrawable(Resources resources, Bitmap bm) {


Drawable drawable = new BitmapDrawable(resources, bm);


return drawable;


}


  1. Bitmap 转换成 byte[]


public byte[] bitmap2Bytes(Bitmap bm) {


ByteArrayOutputStream baos = new ByteArrayOutputStream();


bm.compress(Bitmap.CompressFormat.PNG, 100, baos);


return baos.toByteArray();


}


  1. byte[]转换成 Bitmap


Bitmap bitmap = BitmapFactory.decodeByteArray(byte, 0, b.length);


  1. InputStream 转换成 Bitmap


InputStream is = getResources().openRawResource(id);


Bitmap bitmap = BitmaoFactory.decodeStream(is);


  1. InputStream 转换成 byte[]


InputStream is = getResources().openRawResource(id);//也可以通过其他方式接收一个 InputStream 对象


ByteArrayOutputStream baos = new ByteArrayOutputStream();


byte[] b = new byte[1024*2];


int len = 0;


while ((len = is.read(b, 0, b.length)) != -1)


{


baos.write(b, 0, len);


baos.flush();


}


byte[] bytes = baos.toByteArray();


五、Bitmap 简单操作




  1. 将 Bitmap 保存为本地文件:


public static void writeBitmapToFile(String filePath, Bitmap b, int quality) {


try {


File desFile = new File(filePath);


FileOutputStream fos = new FileOutputStream(desFile);


BufferedOutputStream bos = new BufferedOutputStream(fos);


b.compress(Bitmap.CompressFormat.JPEG, quality, bos);


bos.flush();


bos.close();


} catch (IOException e) {


e.printStackTrace();


}


}


  1. 图片压缩:


private static Bitmap compressImage(Bitmap image) {


if (image == null) {


return null;


}


ByteArrayOutputStream baos = null;


try {


baos = new ByteArrayOutputStream();


image.compress(Bitmap.CompressFormat.JPEG, 100, baos);


byte[] bytes = baos.toByteArray();


ByteArrayInputStream isBm = new ByteArrayInputStream(bytes);


Bitmap bitmap = BitmapFactory.decodeStream(isBm);


return bitmap;


} catch (OutOfMemoryError e) {


} finally {


try {


if (baos != null) {


baos.close();


}


} catch (IOException e) {


}


}


return null;


}


  1. 图片缩放:


/**


  • 根据 scale 生成一张图片

  • @param bitmap

  • @param scale 等比缩放值

  • @return


*/


public static Bitmap bitmapScale(Bitmap bitmap, float scale) {


Matrix matrix = new Matrix();


matrix.postScale(scale, scale); // 长和宽放大缩小的比例


Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);


return resizeBmp;


}


  1. 获取图片旋转角度:


/**


  • 读取照片 exif 信息中的旋转角度

  • @param path 照片路径

  • @return 角度


*/


private static int readPictureDegree(String path) {


if (TextUtils.isEmpty(path)) {


return 0;


}


int degree = 0;


try {


ExifInterface exifInterface = new ExifInterface(path);


int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);


switch (orientation) {


case ExifInterface.ORIENTATION_ROTATE_90:


degree = 90;


break;


case ExifInterface.ORIENTATION_ROTATE_180:


degree = 180;


break;


case ExifInterface.ORIENTATION_ROTATE_270:


degree = 270;


break;


}


} catch (Exception e) {


}


return degree;


}


  1. 设置图片旋转角度


private static Bitmap rotateBitmap(Bitmap b, float rotateDegree) {


if (b == null) {


return null;


}


Matrix matrix = new Matrix();


matrix.postRotate(rotateDegree);


Bitmap rotaBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);


return rotaBitmap;


}


  1. 通过图片 id 获得 Bitmap:


Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);


  1. 通过 assest 获取 获得 Drawable bitmap:


InputStream in = this.getAssets().open("ic_launcher");


Drawable da = Drawable.createFromStream(in, null);


Bitmap mm = BitmapFactory.decodeStream(in);


  1. 通过 sdcard 获得 bitmap


Bitmap bit = BitmapFactory.decodeFile("/sdcard/android.jpg");


  1. view 转 Bitmap


public static Bitmap convertViewToBitmap(View view, int bitmapWidth, int bitmapHeight){


Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);


view.draw(new Canvas(bitmap));


return bitmap;


}


  1. 将控件转换为 bitmap

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
内存优化(二),kotlin协程原理