Android 图片相关整理
目录介绍
- 0.思考问题及解决方案
- 1.加载图片的压缩处理技术
2.网络url图片转换Bitmap保存到本地
- 2.1 直接通过http请求网络图片通过流转化成Bitmap
- 2.2 使用第三方库glide将网络图片转化为Bitmap
- 3.保存bitmap图片到本地文件夹
4.实现带有圆角的图片
- 4.1 使用glide处理图片圆角的逻辑
- 4.2 自定义带有圆角的ImageView
5.毫无满仓轮播图背景做高斯模糊
- 5.1 高斯模糊实现原理
- 5.2 高斯模糊实现的代码
- 5.3 高斯模糊可能会造成的崩溃
- 5.4 高斯模糊参考案例
关于链接
- 1.技术博客汇总
- 2.开源项目汇总
- 3.生活博客汇总
- 4.喜马拉雅音频汇总
- 5.程序员聊天笔记汇总
- 5.其他汇总
0.思考问题及解决方案
- 0.1.0 图片压缩的技术是什么,原理如何理解?
- 0.1.1 为什么保存图片,切割图片圆角需要将图片转化成bitmap?
- 0.1.2 对于从网络下载图片,可以采用什么方式?为什么glide相比从网络直接请求更加高效?
- 0.1.3 图片背景滑动高斯模糊的原理是什么,是否影响性能?
- 0.1.4 bitmap如何避免被回收?如果回收了,怎么避免出现使用bitmap崩溃
- 0.1.5 为什么设置高斯模糊需要放在子线程中处理,不这样做会有什么影响?
1.加载图片的压缩处理技术
1.1 压缩技术步骤
- 1.1.1 科学计算图片所需的采样比例
- 1.1.2 设置图片加载的渲染模式为Config.RGB_565,能降低一半内存
- 1.1.3 对bitmap进行质量压缩
1.2 代码如下所示
/*** 根据路径获得突破并压缩返回bitmap用于显示* @return Bitmap*/
public static Bitmap getSmallBitmap(String filePath, int newWidth, int newHeight) {final BitmapFactory.Options options = new BitmapFactory.Options();//设置只解析图片的边界参数,即宽高options.inJustDecodeBounds = true;//options.inSampleSize = 2;BitmapFactory.decodeFile(filePath, options);// Calculate inSampleSize//科学计算图片所需的采样比例options.inSampleSize = calculateInSampleSize(options, newWidth, newHeight);//设置图片加载的渲染模式为Config.RGB_565,能降低一半内存,但是会影响图片质量options.inPreferredConfig = Bitmap.Config.RGB_565;// Decode bitmap with inSampleSize set//关闭标记,解析真实的图片options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);//质量压缩Bitmap newBitmap = compressImage(bitmap, 500);if (bitmap != null){bitmap.recycle();}return newBitmap;
}/*** 计算图片的缩放值*/
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {// Raw height and width of imagefinal int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {// Calculate ratios of height and width to requested height and// widthfinal int heightRatio = Math.round((float) height / (float) reqHeight);final int widthRatio = Math.round((float) width / (float) reqWidth);// Choose the smallest ratio as inSampleSize value, this will// guarantee// a final image with both dimensions larger than or equal to the// requested height and width.inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;}return inSampleSize;
}/*** 质量压缩* @param image* @param maxSize*/
private static Bitmap compressImage(Bitmap image, int maxSize){ByteArrayOutputStream os = new ByteArrayOutputStream();// scaleint options = 80;// Store the bitmap into output stream(no compress)image.compress(Bitmap.CompressFormat.JPEG, options, os);// Compress by loopwhile ( os.toByteArray().length / 1024 > maxSize) {// Clean up osos.reset();// interval 10options -= 10;image.compress(Bitmap.CompressFormat.JPEG, options, os);}Bitmap bitmap = null;byte[] b = os.toByteArray();if (b.length != 0) {bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);}return bitmap;
}
2.网络url图片转换Bitmap保存到本地
2.1 直接通过http请求网络图片通过流转化成Bitmap
2.1.1 直接通过网络请求将网络图片转化成bitmap
- 经过测试,请求8张图片,耗时毫秒值174
- 如果是服务器响应速度一般,耗时需要2秒【正式接口】
/*** 请求网络图片转化成bitmap* @param url url* @return 将url图片转化成bitmap对象*/
private static long time = 0;
public static Bitmap returnBitMap(String url) {long l1 = System.currentTimeMillis();URL myFileUrl = null;Bitmap bitmap = null;HttpURLConnection conn = null;InputStream is = null;try {myFileUrl = new URL(url);} catch (MalformedURLException e) {e.printStackTrace();}try {conn = (HttpURLConnection) myFileUrl.openConnection();conn.setConnectTimeout(10000);conn.setReadTimeout(5000);conn.setDoInput(true);conn.connect();is = conn.getInputStream();bitmap = BitmapFactory.decodeStream(is);} catch (IOException e) {e.printStackTrace();} finally {try {if (is != null) {is.close();conn.disconnect();}} catch (IOException e) {e.printStackTrace();}long l2 = System.currentTimeMillis();time = (l2-l1) + time;LogUtils.e("毫秒值"+time);//保存}return bitmap;
}
2.2 使用第三方库glide将网络图片转化为Bitmap
/*** 请求网络图片转化成bitmap*/
private static long times = 0;
public static void glideBitmap(Context context,String url){final long l1 = System.currentTimeMillis();Glide.with(context).load(url).asBitmap()//设置缓存.diskCacheStrategy(DiskCacheStrategy.ALL).into(new SimpleTarget<Bitmap>() {@Overridepublic void onResourceReady(Bitmap resource,GlideAnimation<? super Bitmap> glideAnimation) {long l2 = System.currentTimeMillis();times = (l2-l1) + times;LogUtils.e("毫秒值"+times);//请求8张图片,耗时毫秒值98}});
}
3.保存bitmap图片到本地文件夹
/*** 保存图片至自定义路径,刷新相册*/
public static void saveImageToFile(Context context, Bitmap bmp) {// 首先保存图片,这个路径可以自定义File appDir = new File(Environment.getExternalStorageDirectory(), "yc");// 测试由此抽象路径名表示的文件或目录是否存在if (!appDir.exists()) {//如果不存在,则创建由此抽象路径名命名的目录//noinspection ResultOfMethodCallIgnoredappDir.mkdir();}// 然后自定义图片的文件名称String fileName = System.currentTimeMillis() + ".jpg";// 创建file对象File file = new File(appDir, fileName);try {FileOutputStream fos = new FileOutputStream(file);bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);fos.flush();fos.close();} catch (IOException e) {e.printStackTrace();}// 其次把文件插入到系统图库try {MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(), fileName, null);} catch (FileNotFoundException e) {e.printStackTrace();}// 最后通知图库更新Intent intent = new Intent();intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);intent.setData(Uri.parse("file://" + file.getAbsoluteFile()));context.sendBroadcast(intent);
}
4.实现带有圆角的图片
4.1 使用glide处理图片圆角的逻辑
/*** 加载带有圆角的矩形图片 用glide处理** @param path 路径* @param round 圆角半径* @param resId 加载失败时的图片* @param target 控件*/
public static void loadImgByPicassoWithRound(final Context activity, String path,final int round, int resId, final ImageView target) {if (path != null && path.length() > 0) {Glide.with(activity).load(path).asBitmap().placeholder(resId).error(resId)//设置缓存.diskCacheStrategy(DiskCacheStrategy.ALL).into(new BitmapImageViewTarget(target) {@Overrideprotected void setResource(Bitmap resource) {super.setResource(resource);RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);//设置绘制位图时要应用的角半径circularBitmapDrawable.setCornerRadius(round);target.setImageDrawable(circularBitmapDrawable);}});}
}
4.2 自定义带有圆角的ImageView
- 使用BitmapShader实现圆形、圆角图片
- 具体看:https://github.com/yangchong2... 中的libimage自定义imageView
5.毫无满仓轮播图背景做高斯模糊
5.1 高斯模糊实现原理
- 前沿【摘自网络】:在Android平台上进行模糊渲染是一个相当耗CPU也相当耗时的操作,一旦处理不好,卡顿是在所难免的。考虑到效率,渲染一张图片最好的方法是使用OpenGL,其次是使用C++/C,使用Java代码是最慢的。但是Android推出RenderScript之后,我们就有了新的选择,测试表明,使用RenderScript的渲染效率和使用C/C++不相上下,但是使用RenderScript却比使用JNI简单地多!
原理步骤如下所示:
- a.压缩图片,可以质量压缩,也可以宽高压缩
- b.创建RenderScript内核对象
- c.创建一个模糊效果的RenderScript的工具对象
- d.设置相关参数,具体看代码……
- 实现思路:先将图片进行最大程度的模糊处理,再将原图放置在模糊后的图片上面,通过不断改变原图的透明度(Alpha值)来实现动态模糊效果。
5.2 高斯模糊实现的代码
- 5.2.1 设置高斯模糊代码
/*** 设置模糊背景*/
private void setBlurBackground(int pos) {//获取轮播图索引pos处的图片Integer integer = pagerAdapter.getBitmapHashMap().get(pos);Resources res = this.getResources();Bitmap bitmap= BitmapFactory.decodeResource(res, integer);//压缩图片final Bitmap image = BitmapUtils.compressImage(bitmap);if (bitmap != null) {if (mBlurRunnable != null) {mIvBlurBackground.removeCallbacks(mBlurRunnable);}mBlurRunnable = new Runnable() {@Overridepublic void run() {//压缩图片,宽高缩放Bitmap blurBitmap = BlurBitmapUtils.getBlurBitmap(mIvBlurBackground.getContext(), image, 15);ViewSwitchUtils.startSwitchBackgroundAnim(mIvBlurBackground, blurBitmap);}};mIvBlurBackground.postDelayed(mBlurRunnable, 100);}
}
- 5.2.2 RenderScript图片高斯模糊
/*** RenderScript图片高斯模糊*/
public class BlurBitmapUtils {/*** 建议模糊度(在0.0到25.0之间)*/private static final int SCALED_WIDTH = 100;private static final int SCALED_HEIGHT = 100;/*** 得到模糊后的bitmap* @param context 上下文* @param bitmap bitmap* @param radius 半径* @return*/public static Bitmap getBlurBitmap(Context context, Bitmap bitmap, int radius) {// 将缩小后的图片做为预渲染的图片。Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, SCALED_WIDTH, SCALED_HEIGHT, false);// 创建一张渲染后的输出图片。Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);// 创建RenderScript内核对象RenderScript rs = RenderScript.create(context);// 创建一个模糊效果的RenderScript的工具对象ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);// 设置渲染的模糊程度, 25f是最大模糊度blurScript.setRadius(radius);// 设置blurScript对象的输入内存blurScript.setInput(tmpIn);// 将输出数据保存到输出内存中blurScript.forEach(tmpOut);// 将数据填充到Allocation中tmpOut.copyTo(outputBitmap);return outputBitmap;}}
- 5.2.3 设置高斯模糊背景View动画过渡效果
/*** 图片背景切换动画帮助类,设置View动画*/
public class ViewSwitchUtils {static void startSwitchBackgroundAnim(ImageView view, Bitmap bitmap) {Drawable oldDrawable = view.getDrawable();Drawable oldBitmapDrawable ;TransitionDrawable oldTransitionDrawable = null;if (oldDrawable instanceof TransitionDrawable) {oldTransitionDrawable = (TransitionDrawable) oldDrawable;oldBitmapDrawable = oldTransitionDrawable.findDrawableByLayerId(oldTransitionDrawable.getId(1));} else if (oldDrawable instanceof BitmapDrawable) {oldBitmapDrawable = oldDrawable;} else {oldBitmapDrawable = new ColorDrawable(0xffc2c2c2);}if (oldTransitionDrawable == null) {oldTransitionDrawable = new TransitionDrawable(new Drawable[]{oldBitmapDrawable, new BitmapDrawable(bitmap)});oldTransitionDrawable.setId(0, 0);oldTransitionDrawable.setId(1, 1);oldTransitionDrawable.setCrossFadeEnabled(true);view.setImageDrawable(oldTransitionDrawable);} else {oldTransitionDrawable.setDrawableByLayerId(oldTransitionDrawable.getId(0), oldBitmapDrawable);oldTransitionDrawable.setDrawableByLayerId(oldTransitionDrawable.getId(1), new BitmapDrawable(bitmap));}oldTransitionDrawable.startTransition(1000);}
}
5.3 高斯模糊可能会造成的崩溃
5.3.1 崩溃日志
- 开发回收bitmap引发Canvas: trying to use a recycled bitmap错误处理
5.3.2 抛该异常的原因分析
- 如果代码已经不再需要使用Bitmap对象了,就可以释放了。释放内存以后,就不能再使用该Bitmap对象了,如果再次使用,就会抛出异常。所以一定要保证不再使用的时候释放。
5.3.3 解决该问题的办法
- 使用缓存
5.4 高斯模糊参考案例
- Android 图片高斯模糊解决方案:https://www.jianshu.com/p/02d...
关于我的博客
- 我的个人站点:www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/...
- 简书:http://www.jianshu.com/u/b7b2...
- csdn:http://my.csdn.net/m0_37700275
- 喜马拉雅听书:http://www.ximalaya.com/zhubo...
- 开源中国:https://my.oschina.net/zbj161...
- 泡在网上的日子:http://www.jcodecraeer.com/me...
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xi...
Android 图片相关整理相关推荐
- android 最全 图片相关知识整理
android 最全 图片相关知识整理 图片基础知识梳理 图片基础知识梳理(1) - ImageView 的 ScaleType 属性解析 图片基础知识梳理(2) - Bitmap 占用内存分析 图片 ...
- Android 图片文件操作、屏幕相关、.9图片的理解
一:Android图片操作 1.存储bitmap到本地文件系统 public static void bitmapToFile(Bitmap bitmap, String uri) {if(!ext ...
- 【Android】RecycleView简单仿漫画APP图片相关样式
真的真的想不到起什么标题好了,这次的内容真的是太简单了,没有什么挑战性,一天以内就完成了.最近在学kotlin,也会有一份kotlin的代码,鉴于很多人都是从java开始进行android开发的,ko ...
- android开发相关资料整理【2011-10-29】
外文译本--andbook Android开发基础书籍 Android CheckBox的isChecked属性 方法的反射 Android BluetoothClass.Device Android ...
- Android图片系列-2.Android App图片压缩、裁剪分析整理
移动端常用的图片格式有PNG和JPEG,目前ios手机和大部分安卓手机拍照生成的图片默认格式都是JPEG.我们开发APP的时候通常使用的是PNG,这可能是考虑到图片质量效果.PNG图片是无损压缩格式, ...
- android 常用框架整理
文章目录 UI 框架 WebView 框架 具体内容 UI 卫星菜单 节选器 下拉刷新 模糊效果 HUD与Toast 进度条 UI其他 动画 网络相关 网络连接 网络测试 图像获取 响应式编程 地图 ...
- GitHub 优秀的 Android 开源项目 淘宝技术牛p博客整理开发中最常用的GitHub上 优秀的 Android 开源项目整理(精品)...
原文地址为http://www.trinea.cn/android/android-open-source-projects-view/,作者Trinea 主要介绍那些不错个性化的View,包括Lis ...
- Android 开源项目整理
这是一个基本把github上所有优秀安卓的开源代码整理了,下面是都是转自https://github.com/Trinea/Android-open-project,都是一些牛人,很有开源精神的达人做 ...
- Android技术面试整理
colife Android技术面试整理 前19题为常考题目!! 1.Android的四大组件是哪些,它们的作用? 2.请介绍下Android中常用的五种布局. 3.android中的动画有哪几类, ...
最新文章
- Android-如何开发一个功能强大的图片选择器
- C# 8.0的三个令人兴奋的新特性
- 如何通过SpringMVC框架响应JSON数据
- 输入参数的数目不足_机器学习算法—KMEANS算法原理及阿里云PAI平台算法模块参数说明...
- 天津理工大学c语言上机报告3,天津理工大学-c语言上机报告4.pdf
- 你所不知道的setTimeout
- 2018 区块链技术及应用峰会(BTA)·中国全日程公布!
- 理解crossentropy loss
- php mysql 获取排名,Mysql排序获取排名的实例代码
- python子类调用父类构造函数_Java 子类调用父类的构造函数
- Java、对字符串中的字符排序
- github系列(一) Windows环境下载与安装
- 狗民网:狗与爱的世界
- 将中文字符串转为拼音
- Bootstrap-用ICheck插件给CheckBox换新装
- 如何混淆JavaWeb代码
- 操作系统资源分配管理
- 【Unity小游戏】 横版2D射击小游戏 效果展示+完整项目源码【超级简单,自己也可以做游戏玩了】
- 记录调整CentOS的分区大小
- 甲骨文助ISV 通过SOA与Oracle软件集成
热门文章
- mysql安装、配置、连接
- 通用easyui查询页面组件
- bowtie1和bowtie2的比较
- 《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目1
- 大家一起讨论一下朋友网的人脉关系算法是怎么实现的
- 测试基础-05-bug的定义生命周期
- html toast 插件,基于Bootstrap4的Toast提示插件
- webassembly类型_几张图让你看懂WebAssembly
- mongodb默认的用户名密码_Windows下MongoDB设置用户、密码
- cad插入块_CAD中的quot;块quot;能否修改?能!一个命令可快速解决