1. 程式人生 > >Android中圖片載入框架Picasso的使用

Android中圖片載入框架Picasso的使用

技術要點

  • 基本顯示(非同步載入,圖片壓縮,圖片快取)
  • 載入中和載入錯誤的圖片顯示
  • 設定圖片尺寸(Resize)、縮放(Scale)和裁剪(Crop)
  • 圖片旋轉
  • 設定轉換器
  • 取消預設的記憶體快取
  • 設定快取指示器
  • 請求優先順序設定
  • 圖片還未加載出來時取消Picasso的請求
  • 其它擴充套件功能

Demo展示圖片

這裡寫圖片描述

佈局程式碼

//(layout)activity_main.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.test.picassodemo.activity.MainActivity">
<ImageView android:id="@+id/imageView1" android:layout_weight
="1" android:layout_margin="10dp" android:layout_width="match_parent" android:layout_height="0dp"/>
<ImageView android:id="@+id/imageView2" android:layout_weight="1" android:layout_margin="10dp" android:layout_width="match_parent" android:layout_height
="0dp"/>
</LinearLayout> ---------------------------------------------------------------------------------------- //(menu)main.xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/fromInternet" android:showAsAction="never" android:title="fromInternet"/> <item android:id="@+id/fromUri" android:showAsAction="never" android:title="fromUri"/> <item android:id="@+id/fromFile" android:showAsAction="never" android:title="fromFile"/> <item android:id="@+id/fromResourse" android:showAsAction="never" android:title="fromResourse"/> <item android:id="@+id/noFade" android:showAsAction="never" android:title="noFade"/> <item android:id="@+id/reSize" android:showAsAction="never" android:title="reSize"/> <item android:id="@+id/transformation1" android:showAsAction="never" android:title="transformation1"/> <item android:id="@+id/transformation2" android:showAsAction="never" android:title="transformation2"/> <item android:id="@+id/transformation3" android:showAsAction="never" android:title="transformation3"/> <item android:id="@+id/transformation4" android:showAsAction="never" android:title="transformation4"/> <item android:id="@+id/cache" android:showAsAction="never" android:title="cache"/> <item android:id="@+id/indicator" android:showAsAction="never" android:title="indicator"/> </menu> ---------------------------------------------------------------------------------------- //(values)dimens <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="image_width">200dp</dimen> <dimen name="image_height">200dp</dimen> ----------------------------------------------------------------------------------------

activity程式碼

  注:不要忘了設定網路許可權

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

  新增Gradle依賴

    compile 'com.squareup.picasso:picasso:2.5.2'
//(activity)MainActivity
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import com.squareup.picasso.MemoryPolicy;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import com.test.picassodemo.R;
import com.test.picassodemo.transformation.BlurTransformation;
import com.test.picassodemo.transformation.CircleImageTransformation;
import com.test.picassodemo.transformation.CropSquareTransformation;
import com.test.picassodemo.transformation.GrayTransformation;
import com.test.picassodemo.transformation.RoundTransformation;

public class MainActivity extends AppCompatActivity {
    private Context mContext = MainActivity.this;
    private ImageView mImageView1;
    private ImageView mImageView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView(){
        mImageView1 = (ImageView) findViewById(R.id.imageView1);
        mImageView2 = (ImageView) findViewById(R.id.imageView2);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.fromInternet:
                // fromInterNet  預設是非同步載入
                // placeholder和error通常在網路載入中使用
                // placeholder提供一張在網路請求還沒有完成時顯示的圖片,它必須是本地圖片
                // error提供一張在載入圖片出錯的情況下顯示的預設圖片,它必須是本地圖片
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/w2/52/d/102.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        // 設定請求的優先順序 高,預設是正常
                        .priority(Picasso.Priority.HIGH)
                        // 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
                        .tag("photoTag")
                        .into(mImageView1);

                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/w2/52/d/105.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        // 設定請求的優先順序 低,預設是正常
                        .priority(Picasso.Priority.LOW)
                        // 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.noFade:
                // fromInterNet  預設是非同步載入
                // noFade 取消漸入過度效果
                Picasso.with(mContext)
                        .load("http://img2.3lian.com/2014/c7/12/d/77.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .noFade()
                        .tag("photoTag")
                        .into(mImageView1);

                Picasso.with(mContext)
                        .load("http://img2.3lian.com/2014/c7/12/d/82.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .noFade()
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.reSize:
                // fromInterNet  預設是非同步載入
                // reSize 設定圖片尺寸
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a1/110/d/13.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        // 使用dp設定圖片寬高
                        .resizeDimen(R.dimen.image_width,R.dimen.image_height)
                        // 使用px設定圖片寬高
//                        .resizeDimen(400,200)
                        // 只有當原始圖片的尺寸大於我們指定的尺寸時,resize才起作用
                        .onlyScaleDown()
                        // 以(pivotX, pivotY)為原點旋轉
                        .rotate(180,200,100)
                        .tag("photoTag")
                        .into(mImageView1);

                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a1/110/d/11.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        // 使用dp設定圖片寬高
                        .resizeDimen(R.dimen.image_width,R.dimen.image_height)
                        // 使用px設定圖片寬高
//                        .resizeDimen(400,200)
                        // 只有當原始圖片的尺寸大於我們指定的尺寸時,resize才起作用
                        .onlyScaleDown()
                        // 以(pivotX, pivotY)為原點旋轉
                        .rotate(180,200,100)
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.fromUri:
                // fromUri
                break;

            case R.id.fromFile:
                // fromFile
                break;

            case R.id.fromResourse:
                // fromResourse
                Picasso.with(mContext).load(R.mipmap.pic1).into(mImageView1);
                Picasso.with(mContext).load(R.mipmap.pic2).into(mImageView2);
                break;

            case R.id.transformation1:
                // 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
                // 高斯模糊
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a1/110/d/12.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .transform(new BlurTransformation(mContext))
                        .tag("photoTag")
                        .into(mImageView1);

                // 度灰處理
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a1/110/d/15.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .transform(new GrayTransformation())
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.transformation2:
                // 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
                // 圓角處理
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a1/120/d/120.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .transform(new RoundTransformation(30))
                        .tag("photoTag")
                        .into(mImageView1);

                // 圓形遮罩處理
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a1/120/d/122.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .transform(new CircleImageTransformation())
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.transformation3:
                // 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
                // 方形圖片
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a2/58/d/146.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .transform(new CropSquareTransformation())
                        .tag("photoTag")
                        .into(mImageView1);
                break;

            case R.id.transformation4:
                // 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
                // 混合處理(新增圓角、度灰處理)
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a2/58/d/146.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        // 有些還是不能一起使用  比如圓角和灰度一起使用沒效果
                        // 灰度和圓形遮罩一起使用 顯示外圍邊框線
//                        .transform(new GrayTransformation())
                        .transform(new RoundTransformation(100))
                        .transform(new BlurTransformation(mContext))
                        .tag("photoTag")
                        .into(mImageView1);

                // 混合處理(新增高斯模糊、圓形遮罩處理)
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/a2/58/d/151.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .transform(new BlurTransformation(mContext))
                        .transform(new CircleImageTransformation())
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.cache:
                // 預設記憶體快取和磁碟快取都開啟,圖片保存於記憶體中容易OOM,取消記憶體快取
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/w2/53/d/8.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        // 設定請求的優先順序 高,預設是正常
                        .priority(Picasso.Priority.HIGH)
                        // 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
                        //跳過記憶體快取
                        .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)
                        //跳過磁碟快取
                        .networkPolicy(NetworkPolicy.NO_CACHE)
                        .tag("photoTag")
                        .into(mImageView1);

                // 預設記憶體快取和磁碟快取都開啟,圖片保存於記憶體中容易OOM,取消記憶體快取
                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/w2/53/d/5.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        // 設定請求的優先順序 高,預設是正常
                        .priority(Picasso.Priority.HIGH)
                        // 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
                        //強制從快取獲取結果
                        .networkPolicy(NetworkPolicy.OFFLINE)
                        .tag("photoTag")
                        .into(mImageView2);
                break;

            case R.id.indicator:
                // 開啟快取指示器 true為開啟
                // 紅色表示網路載入  藍色表示磁碟載入  綠色表示快取載入
                Picasso.with(mContext).setIndicatorsEnabled(true);

                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/w2/53/d/2.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .tag("photoTag")
                        .into(mImageView1);

                Picasso.with(mContext)
                        .load("http://img1.3lian.com/2015/w2/53/d/6.jpg")
                        .placeholder(R.mipmap.loading)
                        .error(R.mipmap.error)
                        .centerCrop()
                        .fit()
                        .tag("photoTag")
                        .into(mImageView2);

                break;

            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onDestroy() {
        // 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
        Picasso.with(mContext).cancelTag("PhotoTag");
        super.onDestroy();
    }
}

transformation程式碼

//(transformation)BlurTransformation
import android.content.Context;
import android.graphics.Bitmap;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import com.squareup.picasso.Transformation;

/**
 * 高斯模糊處理
 */
public class BlurTransformation implements Transformation{
    RenderScript rs;
    public BlurTransformation(Context context) {
        super();
        rs = RenderScript.create(context);
    }

    @Override
    public Bitmap transform(Bitmap bitmap) {
        // Create another bitmap that will hold the results of the filter.
        Bitmap blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

        // Allocate memory for Renderscript to work with
        Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED);
        Allocation output = Allocation.createTyped(rs, input.getType());

        // Load up an instance of the specific script that we want to use.
        ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        script.setInput(input);

        // Set the blur radius
        script.setRadius(25);

        // Start the ScriptIntrinisicBlur
        script.forEach(output);

        // Copy the output to the blurred bitmap
        output.copyTo(blurredBitmap);

        bitmap.recycle();

        return blurredBitmap;
    }

    @Override
    public String key() {
        return "blur";
    }
}
----------------------------------------------------------------------------------------
//(transformation)CircleImageTransformation
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import com.squareup.picasso.Transformation;

/**
 * 圓形遮罩處理
 */
public class CircleImageTransformation implements Transformation{

    @Override
    public Bitmap transform(Bitmap source) {
        int minEdge = Math.min(source.getWidth(), source.getHeight());
        int dx = (source.getWidth() - minEdge) / 2;
        int dy = (source.getHeight() - minEdge) / 2;

        // Init shader
        Shader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        Matrix matrix = new Matrix();
        matrix.setTranslate(-dx, -dy);   // Move the target area to center of the source bitmap
        shader.setLocalMatrix(matrix);

        // Init paint
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setShader(shader);

        // Create and draw circle bitmap
        Bitmap output = Bitmap.createBitmap(minEdge, minEdge, source.getConfig());
        Canvas canvas = new Canvas(output);
        canvas.drawOval(new RectF(0, 0, minEdge, minEdge), paint);

        // Recycle the source bitmap, because we already generate a new one
        source.recycle();

        return output;
    }

    @Override
    public String key() {
        return "circleImage";
    }
}
----------------------------------------------------------------------------------------
//(transformation)CropSquareTransformation
import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;

/**
 * 正方形切割
 */
public class CropSquareTransformation implements Transformation {
    @Override
    public Bitmap transform(Bitmap source) {
        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;
        Bitmap result = Bitmap.createBitmap(source, x, y, size, size);
        if (result != source) {
            source.recycle();
        }
        return result;
    }
    @Override
    public String key() {
        return "square";
    }
}
----------------------------------------------------------------------------------------
//(transformation)GrayTransformation
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;

/**
 * 灰度處理
 */
public class GrayTransformation implements Transformation{

    @Override
    public Bitmap transform(Bitmap source) {
        int width, height;
        height = source.getHeight();
        width = source.getWidth();

        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(source, 0, 0, paint);

        if(source!=null && source!=bmpGrayscale){
            source.recycle();
        }
        return bmpGrayscale;
    }

    @Override
    public String key() {
        return "gray";
    }
}
----------------------------------------------------------------------------------------
//(transformation)RoundTransformation
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import com.squareup.picasso.Transformation;

/**
 * 圓角處理
 */
public class RoundTransformation implements Transformation {
    private int radius;//圓角值

    public RoundTransformation(int radius) {
        this.radius = radius;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        int width = source.getWidth();
        int height = source.getHeight();
        //畫板
        Bitmap bitmap = Bitmap.createBitmap(width, height, source.getConfig());
        Paint paint = new Paint();
        Canvas canvas = new Canvas(bitmap);//建立同尺寸的畫布
        paint.setAntiAlias(true);//畫筆抗鋸齒
        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
        //畫圓角背景
        RectF rectF = new RectF(new Rect(0, 0, width, height));//賦值
        canvas.drawRoundRect(rectF, radius, radius, paint);//畫圓角矩形
        //
        paint.setFilterBitmap(true);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(source, 0, 0, paint);
        source.recycle();//釋放

        return bitmap;
    }

    @Override
    public String key() {
        return "round";
    }
}

參考資料