Sunday, December 30, 2018

Apply PostProcess for ImageDecoder

Last post show a simple example to "Display animated GIF using ImageDecoder". This example show how to implement our own PostProcess, to apply effect on the decoded images.


Modify layout, to have two ImageView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/background_dark"
    tools:context=".MainActivity">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="1dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5"/>

    <ImageView
        android:id="@+id/gifimage1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <ImageView
        android:id="@+id/gifimage2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/guideline"/>

</android.support.constraint.ConstraintLayout>


Java code:
package com.blogspot.android_er.androidimagedecoder;

import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageDecoder;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.PostProcessor;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.IOException;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView imageView1 = findViewById(R.id.gifimage1);
        ImageView imageView2 = findViewById(R.id.gifimage2);

        loadGif(imageView1);
        loadRoundGif(imageView2);
    }

    PostProcessor myPostProcessor =
            new PostProcessor(){
                @Override
                public int onPostProcess(
                        Canvas canvas) {
                    // This will create rounded corners.
                    Path path = new Path();
                    path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
                    int width = canvas.getWidth();
                    int height = canvas.getHeight();
                    path.addRoundRect(0, 0,
                            width, height, 150, 150,
                            Path.Direction.CW);
                    Paint paint = new Paint();
                    paint.setAntiAlias(true);
                    paint.setColor(Color.TRANSPARENT);
                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
                    canvas.drawPath(path, paint);
                    return PixelFormat.TRANSLUCENT;
                }
            };


    ImageDecoder.OnHeaderDecodedListener myOnHeaderDecodedListener =
            new ImageDecoder.OnHeaderDecodedListener(){
                @Override
                public void onHeaderDecoded
                        (ImageDecoder decoder,
                         ImageDecoder.ImageInfo info,
                         ImageDecoder.Source source) {
                    decoder.setPostProcessor(myPostProcessor);
                }
            };

    private void loadGif(ImageView iv){

        try {
            ImageDecoder.Source source =
                    ImageDecoder.createSource(getResources(), R.drawable.android_er);

            Drawable drawable = ImageDecoder.decodeDrawable(source);

            iv.setImageDrawable(drawable);

            if (drawable instanceof AnimatedImageDrawable) {
                ((AnimatedImageDrawable) drawable).start();
                Toast.makeText(getApplicationContext(),
                        "loadGif: Animation started",
                        Toast.LENGTH_LONG).show();
            }

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),
                    "loadGif: IOException: \n" + e.getMessage(),
                    Toast.LENGTH_LONG).show();
        }

    }

    private void loadRoundGif(ImageView iv){

        try {
            ImageDecoder.Source source =
                    ImageDecoder.createSource(getResources(), R.drawable.android_er);

            //Drawable drawable = ImageDecoder.decodeDrawable(source);
            Drawable drawable = ImageDecoder.decodeDrawable(source,
                    myOnHeaderDecodedListener);

            iv.setImageDrawable(drawable);

            if (drawable instanceof AnimatedImageDrawable) {
                ((AnimatedImageDrawable) drawable).start();
                Toast.makeText(getApplicationContext(),
                        "loadRoundGif: Animation started",
                        Toast.LENGTH_LONG).show();
            }

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),
                    "loadRoundGif: IOException: \n" + e.getMessage(),
                    Toast.LENGTH_LONG).show();
        }

    }
}



If you target to animated GIF and it cannot shown, try to disable hardwareAccelerated, refer to "Display animated GIF using ImageDecoder".

Next:
Mix using of ImageDecoder and ObjectAnimator


No comments: