1. 程式人生 > >Picasso入門教程(十)圖片旋轉和變換

Picasso入門教程(十)圖片旋轉和變換

如果你閱讀了之前的部落格,你就會知道如何使用Picasso載入圖片和處理圖片。到目前為止,我們的圖片還是untouched狀態(我們希望resize 和 scale圖片,這樣可以讓圖片更合適一些)這篇部落格會講圖片的操作。

圖片旋轉

在我們學習高階圖片變化之前,你需要先學習一些圖片旋轉。Picasso支援圖片旋轉。有兩種圖片旋轉:簡單的旋轉和複雜的旋轉

簡單旋轉

簡單旋轉需要這樣呼叫一個方法:rotate(float degrees) 。 這個方法通過使用者傳入的角度進行圖片旋轉。這個角度是大於0小於360度。(0度和360度對於圖片來說是不動的)來看一下例子:

Picasso
    .with
(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .rotate(90f) .into(imageViewSimpleRotate);

這會將圖片旋轉90度。

複雜旋轉

預設情況下,旋轉中心(pivot point)是(0,0)的位置。有時候你可能需要在一個特定的旋轉中心旋轉圖片,而不是在(0,0)處。你可以呼叫下面那個方法來實現:

rotate(float degrees, float pivotX, float pivotY)

現在載入圖片的程式碼變成了下面那個:

Picasso
    .with
(context) .load(R.drawable.floorplan) .rotate(45f, 200f, 100f) .into(imageViewComplexRotate);

變換(Transformation)

旋轉只是圖片操作方法中的一小部分。Picasso可以通過呼叫Transformation 介面允許操作圖片做很多操作。你可以實現Transformation 介面中的transform(android.graphics.Bitmap source) 方法。這個方法傳入一個Bitmap,返回一個變換過的圖片。
在你實現你自定義的轉換之後,你可以簡單的使用transform(Transformation transformation)

來設定Picasso請求 。這可以在圖片顯示之前就變換圖片。

例子1:Blurring an Image

我們的方法將會實現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(10);

        // 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 加到Picasso的請求中:

Picasso
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .transform(new BlurTransformation(context))
    .into(imageViewTransformationBlur);

執行這段程式碼之後,圖片將會被模糊化呈現在ImageView中。

例子2:Blurring and Gray-Scaling an Image

Picasso也允許transform 的引數是列表:transform(List<? extends Transformation> transformations) 這意味著你可以對image做一系列的變化。
這個例子我們對圖片新增一個gray-scaling的變換。程式碼實現如下:

public class GrayscaleTransformation implements Transformation {

    private final Picasso picasso;

    public GrayscaleTransformation(Picasso picasso) {
        this.picasso = picasso;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        Bitmap result = createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
        Bitmap noise;
        try {
            noise = picasso.load(R.drawable.noise).get();
        } catch (IOException e) {
            throw new RuntimeException("Failed to apply transformation! Missing resource.");
        }

        BitmapShader shader = new BitmapShader(noise, REPEAT, REPEAT);

        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.setSaturation(0);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);

        Paint paint = new Paint(ANTI_ALIAS_FLAG);
        paint.setColorFilter(filter);

        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(source, 0, 0, paint);

        paint.setColorFilter(null);
        paint.setShader(shader);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));

        canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);

        source.recycle();
        noise.recycle();

        return result;
    }

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

如果你想對圖片新增多個變換,你可以放到一個list中,然後將list傳給Picasso。程式碼如下:

List<Transformation> transformations = new ArrayList<>();

transformations.add(new GrayscaleTransformation(Picasso.with(context)));
transformations.add(new BlurTransformation(context));

Picasso
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .transform(transformations)
    .into(imageViewTransformationsMultiple);

Transformation應該會給你提供足夠的方法進行圖片變換。在實現Transformation你需要注意兩點:

  • 如果不需要變換的話,那就返回原始的圖片
  • 當建立一個新的Bitmap的時候,舊的Bitmap要呼叫.recycle() 方法。

總結

Transformation 非常有用。你可以使用它對圖片做各種變換。這是Picasso功能的巔峰。
下一篇部落格,我們將會將一些關於記憶體有關的。