当前位置:首页 » 文件管理 » 缓存bitmap

缓存bitmap

发布时间: 2023-07-27 12:06:50

❶ 安卓开发Xutils.Bitmap怎么实现的三级缓存

网络缓存
网络拉取图片严格来讲不能称之为缓存,实质上就是下载url对应的图片,我们这里姑且把它看作是缓存的一种。仿照BitmapUtil中的display方法,我自己定制的CustomBitmapUtils也定义这个方法,根据传入的url,将图片设置到ivPic控件上。

[java] view plain
public void display(ImageView ivPic, String url) {

}
定义网络缓存的工具类,在访问网络的时候,我使用了AsyncTask来实现,在AsyncTask的doInBackGround方法里下载图片,然后将 图片设置给ivPic控件,AsyncTask有三个泛型,其中第一个泛型是执行异步任务的时候,通过execute传过来的参数,第二个泛型是更新的进度,第三个泛型是异步任务执行完成之后,返回来的结果,我们这里返回一个Bitmap。具体的下载实现代码如下:

[java] view plain
<pre name="code" class="java">/**
* 网络缓存的工具类
*
* @author ZHY
*
*/
public class NetCacheUtils {

private LocalCacheUtils localCacheUtils;
private MemoryCacheUtils memoryCacheUtils;

public NetCacheUtils() {
localCacheUtils = new LocalCacheUtils();
memoryCacheUtils = new MemoryCacheUtils();
}

/**
* 从网络下载图片
*
* @param ivPic
* @param url
*/
public void getBitmapFromNet(ImageView ivPic, String url) {
// 访问网络的操作一定要在子线程中进行,采用异步任务实现
MyAsyncTask task = new MyAsyncTask();
task.execute(ivPic, url);

}

/**
* 第一个泛型--异步任务执行的时候,通过execute传过来的参数; 第二个泛型--更新进度; 第三个泛型--异步任务执行以后返回的结果
*
* @author ZHY
*
*/
private class MyAsyncTask extends AsyncTask<Object, Void, Bitmap> {

private ImageView ivPic;
private String url;

// 耗时任务执行之前 --主线程
@Override
protected void onPreExecute() {
super.onPreExecute();
}

// 后台执行的任务
@Override
protected Bitmap doInBackground(Object... params) {
// 执行异步任务的时候,将URL传过来
ivPic = (ImageView) params[0];
url = (String) params[1];
Bitmap bitmap = downloadBitmap(url);
// 为了保证ImageView控件和URL一一对应,给ImageView设定一个标记
ivPic.setTag(url);// 关联ivPic和URL

return bitmap;
}

// 更新进度 --主线程
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}

// 耗时任务执行之后--主线程
@Override
protected void onPostExecute(Bitmap result) {
String mCurrentUrl = (String) ivPic.getTag();
if (url.equals(mCurrentUrl)) {
ivPic.setImageBitmap(result);
System.out.println("从网络获取图片");
// 从网络加载完之后,将图片保存到本地SD卡一份,保存到内存中一份
localCacheUtils.setBitmap2Local(url, result);
// 从网络加载完之后,将图片保存到本地SD卡一份,保存到内存中一份
memoryCacheUtils.setBitmap2Memory(url, result);

}
}
}

/**
* 下载网络图片
*
* @param url
* @return
*/
private Bitmap downloadBitmap(String url) {
HttpURLConnection conn = null;
try {
URL mURL = new URL(url);
// 打开HttpURLConnection连接
conn = (HttpURLConnection) mURL.openConnection();
// 设置参数
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
// 开启连接
conn.connect();

// 获得响应码
int code = conn.getResponseCode();
if (code == 200) {
// 相应成功,获得网络返回来的输入流
InputStream is = conn.getInputStream();

// 图片的输入流获取成功之后,设置图片的压缩参数,将图片进行压缩
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;// 将图片的宽高都压缩为原来的一半,在开发中此参数需要根据图片展示的大小来确定,否则可能展示的不正常
options.inPreferredConfig = Bitmap.Config.RGB_565;// 这个压缩的最小

// Bitmap bitmap = BitmapFactory.decodeStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);// 经过压缩的图片

return bitmap;
}

} catch (Exception e) {
e.printStackTrace();
} finally {
// 断开连接
conn.disconnect();
}

return null;
}
}

❷ Bitmap使用详解

用到的图片不仅仅包括.png、.gif、.9.png、.jpg和各种Drawable系对象,还包括位图Bitmap

图片的处理也经常是影响着一个程序的高效性和健壮性。

为什么不直接用Bitmap传输?
位图文件虽好,但是非压缩格式,占用较大存储空间。

Bitmap主要方法有:获取图像宽高、释放,判断是否已释放和是否可修改,压缩、创建制定位图等功能

用于从不同的数据源(如文件、输入流、资源文件、字节数组、文件描述符等)解析、创建Bitmap对象

允许我们定义图片以何种方式如何读到内存。

推荐阅读: Android - Bitmap-内存分析

注意事项:

decodeFileDescriptor比decodeFile高效

查看源码可以知道

替换成

建议采用decodeStream代替decodeResource。

因为BitmapFactory.decodeResource 加载的图片可能会经过缩放,该缩放目前是放在 java 层做的,效率比较低,而且需要消耗 java 层的内存。因此,如果大量使用该接口加载图片,容易导致OOM错误,BitmapFactory.decodeStream 不会对所加载的图片进行缩放,相比之下占用内存少,效率更高。

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

推荐阅读:[ BitmapFactory.decodeResource加载图片缩小的原因及解决方法

canvas和Matrix可对Bitmap进行旋转、放缩、平移、切错等操作

可以用Bitmap.onCreateBitmap、Canvas的clipRect和clipPath等等方式

推荐阅读: android自定义View学习4--图像剪切与变换

对初始化Bitmap对象过程中可能发生的OutOfMemory异常进行了捕获。如果发生了OutOfMemory异常,应用不会崩溃,而是得到了一个默认的Bitmap图。

如果不进行缓存,尽管看到的是同一张图片文件,但是使用BitmapFactory类的方法来实例化出来的Bitmap,是不同的Bitmap对象。缓存可以避免新建多个Bitmap对象,避免内存的浪费。

如果图片像素过大,使用BitmapFactory类的方法实例化Bitmap的过程中,需要大于8M的内存空间,就必定会发生OutOfMemory异常。
可以将图片缩小,以减少载入图片过程中的内存的使用,避免异常发生。

推荐阅读:
Bitmap详解与Bitmap的内存优化

❸ 缓存击穿互斥锁 设置锁的失效时间

  • 设置锁的失效时间是自己设置的,它的过期时间会很短,最长不超过五分钟

  • 缓存穿透是指查询一个一定不存在的数据

  • 由于缓存是不命中时被动写的,

  • 并且出于容错考虑,如果从存储层查不到数据则不写入缓存,

  • 这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

  • 在流量大时,可能DB就挂掉了,

  • 要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

  • 最常见的则是采用布隆过滤器

  • 将所有可能存在的数据哈希到一个足够大的bitmap中,

  • 一个一定不存在的数据会被 这个bitmap拦截掉,

  • 从而避免了对底层存储系统的查询压力。

  • 另外也有一个更为简单粗暴的方法

  • 如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),

  • 我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟

❹ Android-Listview中Bitmap的缓存实现都有哪些方式

1.一般使用2中,一种是 通过 adapter 参数中的List的对应位置线放入一张加载中的图片,然后把adapter 赋值给View以后,开启另外一个线程下载图片,然后刷新adapter 达到效果,
2.自定意个adapter 然后在adapter 中获得获得图片路径有开启一个线程下载,之后在ImageView等VIEW 赋值。

❺ 安卓从手机相册获取照片作为头像缓存地址

* 1、实现原理:用户打开相册或相机选择相片后,相片经过压缩并设置在控件上,图片在本地sd卡存一份(如果有的话,没大桐有则内部存储,所以还
* 需要判断用户是否挂载了sd卡),然后在服务器上存储一份该图片,当下次再次启桐则动应用时,会默认去sd卡加载该图片,如果本地没有,再会去联网请求
* 2、使用了picasso框架以及自定义BitmapUtils工具类
* 3、记得加上相关权局仿棚限
* <uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
* */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ImageView iv;//要设置的头像
private Button btn_photo;//调用相册按钮
private Button btn_camera;//调用相机按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv=(ImageView) findViewById(R.id.iv);
btn_photo = (Button) findViewById(R.id.btn_photo);
btn_camera = (Button) findViewById(R.id.btn_camera);
btn_photo.setOnClickListener(this);
btn_camera.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_photo://打开系统相册
Intent intent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,100);
break;
case R.id.btn_camera://打开系统相机
Intent intent2=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent2,200);
break;
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==100&&resultCode==RESULT_OK&&data!=null){//系统相册
Uri imageData = data.getData();
String path=getPath(imageData);
Bitmap bitmap = BitmapFactory.decodeFile(path);
Bitmap bitmap1 = BitmapUtils.zoom(bitmap, iv.getWidth(), iv.getHeight());
Bitmap bitmap2 = BitmapUtils.circleBitmap(bitmap1);
//加载显示
iv.setImageBitmap(bitmap2);
//bitmap图片上传到服务器......
//bitmap图片保存到本地
saveImage(bitmap2);
}else if(requestCode==200&&resultCode==RESULT_OK&&data!=null){//系统相机
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
BitmapUtils.zoom(bitmap,iv.getWidth(),iv.getHeight());
bitmap=BitmapUtils.circleBitmap(bitmap);
//加载显示
iv.setImageBitmap(bitmap);
//bitmap图片上传到服务器......
//bitmap图片保存到本地
saveImage(bitmap);
}
}
/**
* 数据的存储。(5种)
* Bimap:内存层面的图片对象。
*
* 存储--->内存:
* BitmapFactory.decodeFile(String filePath);
* BitmapFactory.decodeStream(InputStream is);
* 内存--->存储:
* bitmap.compress(Bitmap.CompressFormat.PNG,100,OutputStream os);
*/
private void saveImage(Bitmap bitmap) {
File filesDir;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断sd卡是否挂载
//路径1:storage/sdcard/Android/data/包名/files
filesDir = this.getExternalFilesDir("");
}else{//手机内部存储
//路径:data/data/包名/files
filesDir = this.getFilesDir();
}
FileOutputStream fos = null;
try {
File file = new File(filesDir,"icon.png");
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100,fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//如果本地有,就不需要再去联网去请求
private boolean readImage() {
File filesDir;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断sd卡是否挂载
//路径1:storage/sdcard/Android/data/包名/files
filesDir = getExternalFilesDir("");
}else{//手机内部存储
//路径:data/data/包名/files
filesDir = getFilesDir();
}
File file = new File(filesDir,"icon.png");
if(file.exists()){
//存储--->内存
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
iv.setImageBitmap(bitmap);
return true;
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private String getPath(Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
//高于4.4.2的版本
if (sdkVersion >= 19) {
Log.e("TAG", "uri auth: " + uri.getAuthority());
if (isExternalStorageDocument(uri)) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(this, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(this, contentUri, selection, selectionArgs);
} else if (isMedia(uri)) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor actualimagecursor = this.managedQuery(uri, proj, null, null, null);
int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
actualimagecursor.moveToFirst();
return actualimagecursor.getString(actual_image_column_index);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(this, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* uri路径查询字段
*
* @param context
* @param uri
* @param selection
* @param selectionArgs
* @return
*/
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isMedia(Uri uri) {
return "media".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
/**
* 判断本地是否有该图片,没有则去联网请求
* */
@Override
protected void onResume() {
super.onResume();
if(readImage()){
return;
}
}
}
//BitmapUtils工具类public class BitmapUtils { /**
* 该方法用于将图片进行圆形处理
* */ public static Bitmap circleBitmap(Bitmap source){ //默认只对宽进行处理 int width=source.getWidth(); Bitmap bitmap=Bitmap.createBitmap(width,width,Bitmap.Config.ARGB_8888); Canvas canvas=new Canvas(bitmap); Paint paint=new Paint(); //设置抗锯齿 paint.setAntiAlias(true); canvas.drawCircle(width/2,width/2,width/2,paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(source,0,0,paint); return bitmap; } /** * 该方法用于图片压缩处理,注意width、height参数的类型必须是float * */ public static Bitmap zoom(Bitmap source,float width,float height){ Matrix matrix=new Matrix(); //图片进行压缩处理 matrix.postScale(width/source.getWidth(),height/source.getHeight()); Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, false); return bitmap; }}
以上所述是小编给大家介绍的Android实现调用系统图库与相机设置头像并保存在本地及服务器 ,希望对大家有所帮助

热点内容
滑板鞋脚本视频 发布:2025-02-02 09:48:54 浏览:433
群晖怎么玩安卓模拟器 发布:2025-02-02 09:45:23 浏览:557
三星安卓12彩蛋怎么玩 发布:2025-02-02 09:44:39 浏览:743
电脑显示连接服务器错误 发布:2025-02-02 09:24:10 浏览:537
瑞芯微开发板编译 发布:2025-02-02 09:22:54 浏览:147
linux虚拟机用gcc编译时显示错误 发布:2025-02-02 09:14:01 浏览:240
java驼峰 发布:2025-02-02 09:13:26 浏览:652
魔兽脚本怎么用 发布:2025-02-02 09:10:28 浏览:538
linuxadobe 发布:2025-02-02 09:09:43 浏览:212
sql2000数据库连接 发布:2025-02-02 09:09:43 浏览:726