目录介绍
0.思考问题及解决方案1.加载图片的压缩处理技术2.网络url图片转换Bitmap保存到本地
2.1 直接通过http请求网络图片通过流转化成Bitmap2.2 使用第三方库glide将网络图片转化为Bitmap3.保存bitmap图片到本地文件夹4.实现带有圆角的图片
4.1 使用glide处理图片圆角的逻辑4.2 自定义带有圆角的ImageView5.毫无满仓轮播图背景做高斯模糊
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;
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = calculateInSampleSize(options, newWidth, newHeight);
options.inPreferredConfig = Bitmap.Config.RGB_565;
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) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize =
1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((
float) height / (
float) reqHeight);
final int widthRatio = Math.round((
float) width / (
float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
/**
* 质量压缩
* @param image
* @param maxSize
*/
private static Bitmap
compressImage(Bitmap image,
int maxSize){
ByteArrayOutputStream os =
new ByteArrayOutputStream();
int options =
80;
image.compress(Bitmap.CompressFormat.JPEG, options, os);
while ( os.toByteArray().length /
1024 > maxSize) {
os.reset();
options -=
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;
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
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;
}
12345678910111213141516171819202122232425262728293031323334353637383940414243
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>() {
@Override
public void onResourceReady(Bitmap resource,
GlideAnimation<?
super Bitmap> glideAnimation) {
long l2 = System.currentTimeMillis();
times = (l2-l1) + times;
LogUtils.e(
"毫秒值"+times);
}
});
}
12345678910111213141516171819202122
3.保存bitmap图片到本地文件夹
/**
* 保存图片至自定义路径,刷新相册
*/
public static void saveImageToFile(Context context, Bitmap bmp) {
File appDir =
new File(Environment.getExternalStorageDirectory(),
"yc");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() +
".jpg";
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);
}
12345678910111213141516171819202122232425262728293031323334353637
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) {
@Override
protected void setResource(Bitmap resource) {
super.setResource(resource);
RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory
.create(activity.getResources(), resource);
circularBitmapDrawable.setCornerRadius(round);
target.setImageDrawable(circularBitmapDrawable);
}
});
}
}
12345678910111213141516171819202122232425262728293031
4.2 自定义带有圆角的ImageView
使用BitmapShader实现圆形、圆角图片具体看:https://github.com/yangchong211/YCPaiDian 中的lib\image自定义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) {
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() {
@Override
public void run() {
Bitmap blurBitmap = BlurBitmapUtils.getBlurBitmap(
mIvBlurBackground.getContext(), image,
15);
ViewSwitchUtils.startSwitchBackgroundAnim(mIvBlurBackground, blurBitmap);
}
};
mIvBlurBackground.postDelayed(mBlurRunnable,
100);
}
}
123456789101112131415161718192021222324252627
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 rs = RenderScript.create(context);
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
blurScript.setRadius(radius);
blurScript.setInput(tmpIn);
blurScript.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243
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);
}
}
12345678910111213141516171819202122232425262728293031
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/02da487a2f43
关于我的博客
我的个人站点:www.yczbj.org,www.ycbjie.cngithub:https://github.com/yangchong211知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts简书:http://www.jianshu.com/u/b7b2c6ed9284csdn:http://my.csdn.net/m0_37700275喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/开源中国:https://my.oschina.net/zbj1618/blog泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1邮箱:yangchong211@163.com阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcVsegmentfault头条:https://segmentfault.com/u/xiangjianyu/articles转载于:https://blog.csdn.net/m0_37700275/article/details/80931563