Android图片加载与缓存开源框架总结七部曲:Glide Picasso ImageLoader Fresco ASimpleCache等

本文主要是介绍Android图片加载与缓存开源框架总结七部曲:Glide Picasso ImageLoader Fresco ASimpleCache等,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

                                                       Android图片加载与缓存开源框架总结

 

 

1)    Picasso      点击下面红色字体进入详解:
picasso-强大的Android图片下载缓存库
2)    Glide         点击下面红色字体进入详解:
Google推荐的图片加载库Glide介绍
3)    Fresco       点击下面红色字体进入详解:
Fresco使用教程
4)    ImageLoader 点击下面红色字体进入详解:
Android UI-开源框架ImageLoader的完美例子

 

 

 

      ImageLoader可以支持图片下载的过程监听,Picasso和Glide都是非常优秀的,而且使用起来非常容易上手,我们站在用户的需求上考虑,若用户要求更完美的展示图片的细节,那么非Picasso莫属,若更注重于顺滑的图片滑动体验Glide更加适合。

 

                    ImageLoader其实也不难,下面来看看代码:

下载地址:

http://download.csdn.net/detail/wwj_748/5975847

http://download.csdn.net/detail/wwj_748/5975847

要使用ImageLoader就要到这里下载jar包:

 

https://github.com/nostra13/Android-Universal-Image-Loader

 

1.功能概要

 Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。

(1).使用多线程加载图片
(2).灵活配置ImageLoader的基本参数,包括线程数、缓存方式、图片显示选项等;
(3).图片异步加载缓存机制,包括内存缓存及SDCard缓存;
(4).采用监听器监听图片加载过程及相应事件的处理;
(5).配置加载的图片显示选项,比如图片的圆角处理及渐变动画。

2.简单实现

ImageLoader采用单例设计模式,ImageLoader imageLoader = ImageLoader.getInstance();得到该对象,每个ImageLoader采用单例设计模式,ImageLoader必须调用init()方法完成初始化。

  1. //  1.完成ImageLoaderConfiguration的配置  
  2. ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)  
  3.     .memoryCacheExtraOptions(480, 800)          // default = device screen dimensions  
  4.     .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)  
  5.     .taskExecutor(...)  
  6.     .taskExecutorForCachedImages(...)  
  7.     .threadPoolSize(3)                          // default  
  8.     .threadPriority(Thread.NORM_PRIORITY - 1)   // default  
  9.     .tasksProcessingOrder(QueueProcessingType.FIFO) // default  
  10.     .denyCacheImageMultipleSizesInMemory()  
  11.     .memoryCache(new LruMemoryCache(2 * 1024 * 1024))  
  12.     .memoryCacheSize(2 * 1024 * 1024)  
  13.     .memoryCacheSizePercentage(13)              // default  
  14.     .discCache(new UnlimitedDiscCache(cacheDir))// default  
  15.     .discCacheSize(50 * 1024 * 1024)        // 缓冲大小  
  16.     .discCacheFileCount(100)                // 缓冲文件数目  
  17.     .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default  
  18.     .imageDownloader(new BaseImageDownloader(context)) // default  
  19.     .imageDecoder(new BaseImageDecoder()) // default  
  20.     .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default  
  21.     .writeDebugLogs()  
  22.     .build();  
  23.   
  24. //  2.单例ImageLoader类的初始化  
  25. ImageLoader imageLoader = ImageLoader.getInstance();  
  26. imageLoader.init(config);  
  27.   
  28. //  3.DisplayImageOptions实例对象的配置  
  29. //      以下的设置再调用displayImage()有效,使用loadImage()无效  
  30. DisplayImageOptions options = new DisplayImageOptions.Builder()  
  31.     .showStubImage(R.drawable.ic_stub)          // image在加载过程中,显示的图片  
  32.     .showImageForEmptyUri(R.drawable.ic_empty)  // empty URI时显示的图片  
  33.     .showImageOnFail(R.drawable.ic_error)       // 不是图片文件 显示图片  
  34.     .resetViewBeforeLoading(false)  // default  
  35.     .delayBeforeLoading(1000)  
  36.     .cacheInMemory(false)           // default 不缓存至内存  
  37.     .cacheOnDisc(false)             // default 不缓存至手机SDCard  
  38.     .preProcessor(...)  
  39.     .postProcessor(...)  
  40.     .extraForDownloader(...)  
  41.     .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)// default  
  42.     .bitmapConfig(Bitmap.Config.ARGB_8888)              // default  
  43.     .decodingOptions(...)  
  44.     .displayer(new SimpleBitmapDisplayer()) // default 可以设置动画,比如圆角或者渐变  
  45.     .handler(new Handler())                             // default  
  46.     .build();  
  47.       
  48. //  4图片加载  
  49. //  4.1 调用displayImage  
  50. imageLoader.displayImage(  
  51.     uri,        /* 
  52.                     String imageUri = "http://site.com/image.png";      // from Web 
  53.                     String imageUri = "file:///mnt/sdcard/image.png";   // from SD card 
  54.                     String imageUri = "content://media/external/audio/albumart/13"; // from content provider 
  55.                     String imageUri = "assets://image.png";             // from assets 
  56.                     */  
  57.     imageView,      // 对应的imageView控件  
  58.     options);       // 与之对应的image显示方式选项  
  59.   
  60. //  4.2 调用loadImage  
  61. //      对于部分DisplayImageOptions对象的设置不起作用  
  62. imageLoader.loadImage(  
  63.         uri,   
  64.         options,   
  65.         new MyImageListener()); //ImageLoadingListener  
  66. class MyImageListener extends SimpleImageLoadingListener{  
  67.   
  68.     @Override  
  69.     public void onLoadingStarted(String imageUri, View view) {  
  70.         imageView.setImageResource(R.drawable.loading);  
  71.         super.onLoadingStarted(imageUri, view);  
  72.     }  
  73.   
  74.     @Override  
  75.     public void onLoadingFailed(String imageUri, View view,  
  76.             FailReason failReason) {  
  77.         imageView.setImageResource(R.drawable.no_pic);  
  78.         super.onLoadingFailed(imageUri, view, failReason);  
  79.     }  
  80.   
  81.     @Override  
  82.     public void onLoadingComplete(String imageUri, View view,  
  83.             Bitmap loadedImage) {  
  84.         imageView.setImageBitmap(loadedImage);  
  85.         super.onLoadingComplete(imageUri, view, loadedImage);  
  86.     }  
  87.   
  88.     @Override  
  89.     public void onLoadingCancelled(String imageUri, View view) {  
  90.         imageView.setImageResource(R.drawable.cancel);  
  91.         super.onLoadingCancelled(imageUri, view);  
  92.     }  
  93.       
  94. }  

3.支持的Uri

  1. String imageUri = "http://site.com/image.png";      // from Web  
  2. String imageUri = "file:///mnt/sdcard/image.png";   // from SD card  
  3. String imageUri = "content://media/external/audio/albumart/13"; // from content provider  
  4. String imageUri = "assets://image.png";             // from assets  
  5. String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)  

 

加载drawables下图片,可以通过ImageView.setImageResource(...) 而不是通过上面的ImageLoader.

4.缓冲至手机

默认不能保存缓存,必须通过下面的方式指定

  1. DisplayImageOptions options = new DisplayImageOptions.Builder()  
  2.         ...  
  3.         .cacheInMemory(true)  
  4.         .cacheOnDisc(true)  
  5.         ...  
  6.         .build();  
  7. ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())  
  8.         ...  
  9.         .defaultDisplayImageOptions(options)  
  10.         ...  
  11.         .build();  
  12. ImageLoader.getInstance().init(config); // Do it on Application start  
  13.   
  14. ImageLoader.getInstance().displayImage(imageUrl, imageView);    /* 
  15.                                             默认为defaultDisplayImageOptions设定的options对象,此处不用指定options对象 */  

或者通过下面这种方式

  1. DisplayImageOptions options = new DisplayImageOptions.Builder()  
  2.         ...  
  3.         .cacheInMemory(true)  
  4.         .cacheOnDisc(true)  
  5.         ...  
  6.         .build();  
  7. ImageLoader.getInstance().displayImage(imageUrl, imageView, options); //此处指定options对象  

由于缓存需要在外设中写入数据,故需要添加下面的权限

  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

5.OutOfMemoryError

如果OutOfMemoryError错误很常见,可以通过下面的方式设置
(1).减少configuration中线程池的线程数目(.threadPoolSize(...)) 推荐为1 - 5
(2).display options通过.bitmapConfig(Bitmap.Config.RGB_565)设置. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.
(3).使用configuration的memoryCache(new WeakMemoryCache())方法 或者不调用.cacheInMemory()方法
(4).display options通过.imageScaleType(ImageScaleType.IN_SAMPLE_INT) 或者 .imageScaleType(ImageScaleType.EXACTLY)方法
(4).避免使用RoundedBitmapDisplayer,它创建了一个新的ARGB_8888 Bitmap对象

6.内存缓存管理

通过imageLoaderConfiguration.memoryCache([new LruMemoryCache(1)]))对手机内存缓存进行管理

LruMemoryCache

API >= 9默认.it is moved to the head of a queue.

FreqLimitedMemoryCache

当超过缓存大小后,删除最近频繁使用的bitmap

LRULimitedMemoryCache

API < 9 默认.当超过缓存大小后,删除最近使用的bitmap

FIFOLimitedMemoryCache

FIFO rule is used for deletion when cache size limit is exceeded

LargestLimitedMemoryCache

The largest bitmap is deleted when cache size limit is exceeded

WeakMemoryCache

Unlimited cache

7.SDcard缓存管理

通过imageLoaderConfiguration.discCache([new TotalSizeLimitedDiscCache()]))对SD卡缓存进行管理

UnlimitedDiscCache

default The fastest cache, doesn't limit cache size

TotalSizeLimitedDiscCache

Cache limited by total cache size. If cache size exceeds specified limit then file with themost oldest lastusage date will be deleted

FileCountLimitedDiscCache

Cache limited by file count. If file count in cache directory exceeds specified limit then file with the most oldest last usage date will be deleted.

LimitedAgeDiscCache

Size-unlimited cache with limited files' lifetime. If age of cached file exceeds defined limit then it will be deleted from cache.

UnlimitedDiscCache is 30%-faster than other limited disc cache implementations.

 

 

 

?

 

Glide是谷歌推荐使用的加载图片的框架,它相对于其他的框架有更多的有点,说到Glide我们不得不谈谈Picasso,为什么呢?这是因为Picasso的使用与Glide的使用上非常的相似,但是细细看,有明显不同,首先我们看下Picasso与Glide的基本用法?


Picasso:            


   Picasso.with(this)
                 .load(url)//加载图片
                 .placeholder(R.mipmap.ic_launcher)//正在加载时的图片
                 .error(R.mipmap.ic_launcher)//加载错误是的图片
                 .into(glide_image2);
Glide:


  Glide.with(this)
                 .load(url)//加载图片
               .placeholder(R.mipmap.ic_launcher)//正在加载时的图片
                 .error(R.mipmap.ic_launcher)//加载错误是的图片
                 .into(glide_image);
1、看到没有,是不是一样呢,基本上它们的用法一直,但是我们在使用Glide时需要注意,Glide.with(this),我们在传入的时候,我建议传入Actitiy,Fragment对应得context,而不是全局的context,为什么呢,这是因为这样我们可以让Gilde加载图片与我们的Activity,Fragment的生命周期一直,创建时去加载,销毁时停止加载,


2、Glide的加载速度比Picasso的加载速度要快,但是消耗的内存要比Picasso的内存高,为什么呢这是因为Gilde他是根据你传入的尺寸进行缓存,如果俩个地方需要      全尺寸缓存,另一个地方按照比例缓存,那么Glide需要缓存俩次,而Picsso是全尺寸的缓存,每当重新加载时,需要重新绘制


   /**
       * Glide的全尺寸缓存
       */
      public void GlideImage3(String url) {
          Glide.with(this)
                  .load(url)//加载图片
                  .placeholder(R.mipmap.ic_launcher)//正在加载时的图片
                  .error(R.mipmap.ic_launcher)//加载错误是的图片
                  .diskCacheStrategy(DiskCacheStrategy.ALL)
                 .into(glide_image);
     }
 

3,Picasso加载的bitmap格式ARGB_8888而Glide所加载的bitmap格式ARGB_565当然我们可以通过实现GlideMenu来实现

  /**
   * 更改Glide的bitmap的格式为ARGB_8888
   * Created by joe.xiang on 2016/6/9.
   */
 public class GlideConfigration implements GlideModule {
  
  
      @Override
      public void applyOptions(Context context, GlideBuilder builder) {
         builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
     }
 
     @Override
     public void registerComponents(Context context, Glide glide) {
 
     }
 }

 

4、Glide的setTag方法不同之处?


   我们可以通过在我们的values下建立一个ids的xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="image_tag" type="id"/>
</resources>
通过Image.setTag(R.id.image_tag,url)的形式来进行设置

5、Glide如何设置圆形图片


    对于如何制作圆形的方法,有很多可以通过自定义ImageView,当然Glide也给我们提供了很多的方法来时圆角图片。一般有一下方法


    1、自定一个Transform 继承 BitmapTransformation




  /**
   * Created by joe.xiang on 2016/6/9.
   */
  public  class CircleTransform extends BitmapTransformation {
  
      public CircleTransform(Context context) {
         super(context);
      }
 
    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
         return circleCrop(pool, toTransform);
     }
 
     private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
         if (source == null) return null;
         int size = Math.min(source.getWidth(), source.getHeight());
         int x = (source.getWidth() - size) / 2;
         int y = (source.getHeight() - size) / 2;
 
         // TODO this could be acquired from the pool too
         Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
         Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
         if (result == null) {
             result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
         }
         Canvas canvas = new Canvas(result);
         Paint paint = new Paint();
         paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
         paint.setAntiAlias(true);
         float r = size / 2f;
         canvas.drawCircle(r, r, r, paint);
        return result;
     }
 
     @Override public String getId() {
         return getClass().getName();
     }
 }




    /**
       * 通过Glide的TransForMation 自定义圆形图片的bitmap
       */
      public void RoundImage(String url) {
          Glide.with(this)
                  .load(url)
                  .asBitmap()
                  .transform(new CircleTransform(this))
                  .into(glide_image5);
     }


 2、我们可以通过BitmapImageVieTarget,来得到一个带圆角的RoundBitmapDrawable;


   /**
       * 通过RoundBitmapDrawable
       */
      public void RoundImage2(String url) {
          Glide.with(this)
                  .load(url)
                  .asBitmap()
                  .into(new BitmapImageViewTarget(glide_image6) {
                     @Override
                     protected void setResource(Bitmap resource) {
                        RoundedBitmapDrawable RoundedBitmapDrawable = RoundedBitmapDrawableFactory.create(Glide_1.this.getResources(), resource);
                        RoundedBitmapDrawable.setCircular(true);
                         glide_image6.setImageDrawable(RoundedBitmapDrawable);
                    }
               });


3、我们可以通过自定义RoundedCornerLayout 继承RelavityLayout来实现圆角图片效果


  **
   * Created by joe.xiang on 2016/6/9.
   */
  public class RoundedCornerLayout  extends RelativeLayout {
      private Bitmap maskBitmap;
      private Paint paint;
      private float cornerRadius;
  
     public RoundedCornerLayout(Context context) {
         super(context);
         init(context, null, 0);
     }
     public RoundedCornerLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         init(context, attrs, 0);
    }
 
     public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         init(context, attrs, defStyle);
     }
 
    private void init(Context context, AttributeSet attrs, int defStyle) {
         paint = new Paint(Paint.ANTI_ALIAS_FLAG);
         setWillNotDraw(false);
    }


     @Override
     public void draw(Canvas canvas) {
         super.draw(canvas);
 
         if (maskBitmap == null) {
            // This corner radius assumes the image width == height and you want it to be circular
             // Otherwise, customize the radius as needed
             cornerRadius = canvas.getWidth() / 2;
             maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
         }
 
         canvas.drawBitmap(maskBitmap, 0f, 0f, paint);
     }


     private Bitmap createMask(int width, int height) {
        Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(mask);
 
         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
         paint.setColor(Color.WHITE); // TODO set your background color as needed
 
         canvas.drawRect(0, 0, width, height, paint);
 
         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
         canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
         return mask;
     }
 }




    <huanxin.exmaple.com.android_glidedemo.RoundedCornerLayout
                     android:layout_width="200dp"
                     android:layout_height="200dp">
                        <ImageView
                             android:id="@+id/glide_image7"
                             android:layout_width="200dp"
                            android:layout_height="200dp"
                            android:scaleType="centerCrop"
                            />
  </huanxin.exmaple.com.android_glidedemo.RoundedCornerLayout>


使用上跟一般使用没什么区别。。。。。


4 、当然我们亦可以使用开源的圆角图片的自定义控件?




   Glide.with(this).load(url).into(new SimpleTarget<GlideDrawable>() {
              @Override
              public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                  //使用自定义的圆角图片
              }
          });


对于Glide加载图片还有很多可以去研究的地方,它还可以加载gif的动态图,不过这个方法要谨慎使用,因为这个非常耗内存,对于Glide的使用花了一个下午对于他的一些基本使用就总结导致,过段时间深入研究后在总结了、一下附上加载的图片效果图。

 

                                                                                 Android Glide

 

 

Android Glide是一个开源的图片加载和缓存处理的第三方框架。和Android的Picasso库类似,个人感觉比Android Picasso好用。Android Glide使自身内部已经实现了缓存策略,使得开发者摆脱Android图片加载的琐碎事务,专注逻辑业务的代码。Android Glide使用便利,短短几行简单明晰的代码,即可完成大多数图片从网络(或者本地)加载、显示的功能需求。

使用Android Glide,需要先下载Android Glide的库,Android Glide在github上的项目主页:

https://github.com/bumptech/glide 。

实际的项目使用只需要到Glide的releases页面把jar包下载后导入到本地的libs里面即可直接使用。Glide的releases的页面地址:https://github.com/bumptech/glide/releases ,在此页面找到最新的jar包,下载后放到自己项目的libs中,比如glide 3.6.0库的jar包下载地址:https://github.com/bumptech/glide/releases/download/v3.6.0/glide-3.6.0.jar


接下来是在自己的项目中具体使用,现在给出一个具体的使用例子加以简单说明(通过网络加载图片然后在ImageView中显示出来):

MainActivity.java

 下载地址:

http://download.csdn.net/detail/shenggaofei/9613805

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import com.bumptech.glide.Glide;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
     private Activity mActivity;
     // 将从此URL加载网络图片。
     private String img_url = "https://avatar.csdn.net/9/7/A/1_zhangphil.jpg" ;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         mActivity = this ;
         setContentView(R.layout.activity_main);
         ListView lv = (ListView) findViewById(R.id.listView);
         lv.setAdapter( new MyAdapter( this , R.layout.item));
     }
     private class MyAdapter extends ArrayAdapter {
         private int resource;
         public MyAdapter(Context context, int resource) {
             super (context, resource);
             this .resource = resource;
         }
         @Override
         public View getView( int position, View convertView, ViewGroup parent) {
             if (convertView == null ) {
                 convertView = LayoutInflater.from(mActivity).inflate(resource,
                         null );
             }
             ImageView iv = (ImageView) convertView.findViewById(R.id.imageView);
             Glide.with(mActivity).load(img_url).centerCrop()
             /*
              * 缺省的占位图片,一般可以设置成一个加载中的进度GIF图
              */
             .placeholder(R.drawable.loading).crossFade().into(iv);
             return convertView;
         }
         @Override
         public int getCount() {
             // 假设加载的数据量很大
             return 10000 ;
         }
     }
}

 

 

 

MainActivity.java需要的两个布局文件:

activity_main.xml

 

?
1
2
3
4
5
6
<linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "http://schemas.android.com/apk/res/android" >
     <listview android:id= "@+id/listView" android:layout_height= "wrap_content" android:layout_width= "match_parent" >
     </listview>
</linearlayout>

 

 

 

 

item.xml

 

?
1
2
3
4
5
6
<!--?xml version= "1.0" encoding= "utf-8" ?-->
<linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "http://schemas.android.com/apk/res/android" >
     <imageview android:id= "@+id/imageView" android:layout_height= "wrap_content" android:layout_width= "wrap_content" >
</imageview></linearlayout>

                                                                     

 

                                                               

Android Picasso加载网络图片等比例缩放

 

下载地址:

http://download.csdn.net/my

在做Android图片加载的时候,由于手机屏幕受限,很多大图加载过来的时候,我们要求等比例缩放,比如按照固定的宽度,等比例缩放高度,使得图片的尺寸比例得到相应的缩放,但图片没有变形。显然按照android:scaleType不能实现,因为会有很多限制,所以必须要自己写算法。 
之前也写过一篇文章Android根据屏幕宽度缩放图片,但这是缩放的本地图片,网络图片该如何办呢?

通过Picasso来缩放 
其实picasso提供了这样的方法。具体是显示Transformation 的transform方法。 
1、先获取网络或本地图片的宽高 
2、获取需要的目标宽 
3、按比例得到目标的高度 
4、按照目标的宽高创建新图

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span style="font-size:18px;">Transformation transformation = new Transformation() {<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@Override</span>public Bitmap transform(Bitmap <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> targetWidth = mImg.getWidth();LogCat.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"source.getHeight()="</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getHeight()+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",source.getWidth()="</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth()+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",targetWidth="</span>+targetWidth);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth()==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果图片小于设置的宽度,则返回原图</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth()<targetWidth){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果图片大小大于等于设置的宽度,则按照设置的宽度比例来缩放</span>double aspectRatio = (double) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getHeight() / (double) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> targetHeight = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) (targetWidth * aspectRatio);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (targetHeight != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && targetWidth != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {Bitmap result = Bitmap.createScaledBitmap(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>, targetWidth, targetHeight, false);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Same bitmap is returned if sizes are the same</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.recycle();}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>;}}}<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@Override</span>public String key() {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"transformation"</span> + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" desiredWidth"</span>;}};</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">7</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">8</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">9</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">10</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">11</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">12</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">13</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">14</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">15</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">16</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">17</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">18</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">19</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">20</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">21</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">22</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">23</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">24</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">25</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">26</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">27</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">28</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">29</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">30</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">31</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">32</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">33</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">34</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">35</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">36</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">37</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">38</span></li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">7</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">8</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">9</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">10</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">11</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">12</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">13</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">14</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">15</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">16</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">17</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">18</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">19</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">20</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">21</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">22</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">23</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">24</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">25</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">26</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">27</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">28</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">29</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">30</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">31</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">32</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">33</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">34</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">35</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">36</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">37</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">38</span></li></ul>

之后在Picasso设置transform

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span style="font-size:18px;">            Picasso<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.with</span>(mContext)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.load</span>(imageUrl)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.placeholder</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mipmap</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zhanwei</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.error</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mipmap</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zhanwei</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.transform</span>(transformation)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.into</span>(viewHolder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mImageView</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li></ul>

参考文献: 
http://stackoverflow.com/questions/21889735/resize-image-to-full-width-and-variable-height-with-picasso 
http://blog.csdn.net/larryl2003/article/details/6919513

                                  

                                                              

                                          ASimpleCache缓存框架的使用

 简述

简述为ASimpleCache官网( 点击打开链接)对其介绍,ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。

0.1ASimpleCache可以缓存什么

普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据。

0.2ASimpleCache有什么特色

(1)轻:轻到只有一个JAVA文件;
(2)可配置:可以配置缓存路径,缓存大小,缓存数量等;
(3)可以设置缓存超时时间,缓存超时自动失效,并被删除;
(4)支持多进程。

0.3ASimpleCache在Android中的使用场景

(1)替换SharePreference当做配置文件;
(2)可以缓存网络请求数据,可以作为app数据(字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据)的缓存工具;
(3)可以作为预加载数据的缓存库;

1ASimpleCache的使用

ASimpleCache使用起来太简单了,尤其是使用过SharePreference。

1.1缓存字符串

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. //缓存  
  2. private ACache mACache;  
  3.   
  4. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. mACache.put(Constants.KEY_STRING, result);  
还有,获取缓存数据:
[java]  view plain  copy
  1. String result = mACache.getAsString(Constants.KEY_STRING);  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_STRING);  

1.2缓存JsonObject

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. //缓存  
  2. private ACache mACache;  
  3.   
  4. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. mACache.put(Constants.KEY_JSONOBJECT, jsonObject);  
还有,获取缓存数据:
[java]  view plain  copy
  1. JSONObject result = mACache.getAsJSONObject(Constants.KEY_JSONOBJECT);  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_JSONOBJECT);  

1.3缓存JsonArray

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. //缓存  
  2. private ACache mACache;  
  3.   
  4. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. mACache.put(Constants.KEY_JSONARRAY, jsonArray);  
还有,获取缓存数据:
[java]  view plain  copy
  1. JSONArray result = mACache.getAsJSONArray(Constants.KEY_JSONARRAY);  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_JSONARRAY);  

1.4缓存Bitmap

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. //缓存  
  2. private ACache mACache;  
  3.   
  4. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);  
  2.         mACache.put(Constants.KEY_BITMAP, bitmap);  
还有,获取缓存数据:
[java]  view plain  copy
  1. Bitmap bitmap = mACache.getAsBitmap(Constants.KEY_BITMAP);  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_BITMAP);  

1.5缓存Drawable

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. //缓存  
  2. private ACache mACache;  
  3.   
  4. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);  
  2.         mACache.put(Constants.KEY_DRAWABLE, drawable);  
还有,获取缓存数据:
[java]  view plain  copy
  1. Drawable bitmap = mACache.getAsDrawable(Constants.KEY_DRAWABLE);  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_DRAWABLE);  

1.6缓存序列化的java对象

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. //缓存  
  2. private ACache mACache;  
  3.   
  4. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. mACache.put(Constants.KEY_JAVA_BEAN, mWeather);  
还有,获取缓存数据:
[java]  view plain  copy
  1. Weather result = (Weather) mACache.getAsObject(Constants.KEY_JAVA_BEAN);  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_JAVA_BEAN);  

1.7缓存byte数据

首先,创建ASimpleCache对象:
[java]  view plain  copy
  1. private ACache mACache;  
  2.   
  3. mACache = ACache.get(this);  
其次,存储数据:
[java]  view plain  copy
  1. private void saveByte() {  
  2.         OutputStream ostream = null;  
  3.         try {  
  4.             ostream = mACache.put(Constants.KEY_BYTE);  
  5.         } catch (FileNotFoundException e) {  
  6.             e.printStackTrace();  
  7.         }  
  8.         if (ostream == null) {  
  9.             ToastUtil.simpleToast(this"Open stream error!");  
  10.             return;  
  11.         }  
  12.         try {  
  13.             URL u = new URL(Constants.downloadUrl);  
  14.             HttpURLConnection conn = (HttpURLConnection) u.openConnection();  
  15.             conn.connect();  
  16.             InputStream stream = conn.getInputStream();  
  17.             byte[] buff = new byte[1024];  
  18.             int counter;  
  19.             while ((counter = stream.read(buff)) > 0) {  
  20.                 ostream.write(buff, 0, counter);  
  21.             }  
  22.         } catch (IOException e) {  
  23.             e.printStackTrace();  
  24.         } finally {  
  25.             try {  
  26.                 // cache update  
  27.                 ostream.close();  
  28.             } catch (IOException e) {  
  29.                 e.printStackTrace();  
  30.             }  
  31.             runOnUiThread(new Runnable() {  
  32.                 @Override  
  33.                 public void run() {  
  34.                     showTv.setText("done...");  
  35.                 }  
  36.             });  
  37.         }  
  38.     }  
还有,获取缓存数据:
[java]  view plain  copy
  1. private void getsByte() {  
  2.         InputStream stream = null;  
  3.         try {  
  4.             stream = mACache.get(Constants.KEY_BYTE);  
  5.         } catch (FileNotFoundException e) {  
  6.             e.printStackTrace();  
  7.         }  
  8.         if (stream == null) {  
  9.             ToastUtil.simpleToast(this"Bitmap cache is null ...");  
  10.             showTv.setText("file not found");  
  11.             return;  
  12.         }  
  13.         try {  
  14.             showTv.setText("file size: " + stream.available());  
  15.         } catch (IOException e) {  
  16.             showTv.setText("error " + e.getMessage());  
  17.         }  
  18.     }  
最后,清除缓存:
[java]  view plain  copy
  1. mACache.remove(Constants.KEY_BYTE);  

 

觉得不错的话,记得打赏一下:

https://blog.csdn.net/shenggaofei/article/details/105873568

这篇关于Android图片加载与缓存开源框架总结七部曲:Glide Picasso ImageLoader Fresco ASimpleCache等的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/432184

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提