Sunday, September 19, 2010

GIF Animation In Android

The gif animation is supported in Android when GIF animation is played as Movie. Movie is a class provided to you by Android SDK.

In your main or any Activity File

public class AA extends Activity {

@Override
public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceStated);


setContentView(new MYGIFView());
}

}


Here's the class


private class MYGIFView extends View{

Movie movie,movie1;
InputStream is=null,is1=null;
long moviestart;
public GIFView(Context context) {
super(context);


Provide your own gif animation file

is=context.getResources().openRawResource(R.drawable.earth);
movie=Movie.decodeStream(is);

}

@Override
protected void onDraw(Canvas canvas) {

canvas.drawColor(Color.WHITE);
super.onDraw(canvas);
long now=android.os.SystemClock.uptimeMillis();
System.out.println("now="+now);
if (moviestart == 0) { // first time
moviestart = now;

}
System.out.println("\tmoviestart="+moviestart);
int relTime = (int)((now - moviestart) % movie.duration()) ;
System.out.println("time="+relTime+"\treltime="+movie.duration());
movie.setTime(relTime);
movie.draw(canvas,this.getWidth()/2-20,this.getHeight()/2-40);
this.invalidate();
}
}

24 comments:

  1. Get this man a beer! I have been looking for a way to draw an animated gif on a canvas for days...

    ReplyDelete
  2. Hey!
    I'm using this method to show a .gif animation. I get a problem though. The gif displayed is larger than the resolution, which results in a clipped picture. I've also tried the following:

    C = new GIFView(Image.this);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(200,200); C.setLayoutParams(params);
    parent.addView(C, index);

    Which shows a 200x200 view, but the movie is still clipped within those 200x200.

    How would I go about to resize the movie?

    Thanks!

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. this is absolutly the esaiest way to do the job..

    nevertheless there are 2 changes to do in the code to get it working...

    IN THE FOLLOWING

    @Override
    public void onCreate(Bundle savedInstanceState){

    super.onCreate(savedInstanceStated);
    setContentView(new MYGIFView());

    }

    }
    just replace

    setContentView(new MYGIFView());

    in

    setContentView(new MYGIFView(this));

    AND IN

    public GIFView(Context context) {
    super(context);


    Provide your own gif animation file

    is=context.getResources().openRawResource(R.drawable.earth);
    movie=Movie.decodeStream(is);

    }

    REPLACE THE FIRST LINE IN

    public MYGIFView(Context context)


    according to the name of the class...

    after done this little changes it should work as for me... thank you man

    ReplyDelete
  5. Hi Erik,

    Did you figure out how to resize the movie?

    Thanks,
    Utpal

    ReplyDelete
  6. I did!

    Within the MYGIFView class, you have onDraw(Canvas canvas)

    Simply, within onDraw, before movie.draw, pass canvas.scale(scalefactorx,scalefactory);

    I calculated the scale factors as the ratio between the view size and the movie size, using:
    (double)this.getWidth() / (double)movie.width()
    and the same for height.

    ReplyDelete
  7. Thanks a lot Erik. I will try out..

    ReplyDelete
  8. Replies
    1. Hi Erik, i implemented what you advised Utpal above but it didn't work my mine. It just displayed a blank canvas with nothing drawn on it.

      Delete
  9. it displays the gif but does not play it properly.. its totally distorted..

    ReplyDelete
    Replies
    1. I am getting same results for few gifs. Did you find answer to this?

      Delete
    2. I've had this problem only on specific devices (Namely HTC Desire GSM). However, this only happened on stock roms, not on custom MIUI or Cyanogenmod roms. Also, it happens in the emulator.

      I suspect this is something in the implementation of Movie and thus not something that can be rectified without modifying Movie. While my Android knowledge is very small, I think this means that on devices where the problem occurs, a custom ROM is required. Perhaps it is possible to use a custom implementation of Movie, but if so, I think that it is A LOT simpler to simply use some existing Java library to split any gif file into individual bitmaps, and display them as an animation.

      However I have shelved the project where I used GIF so I won't be looking into it anytime soon.

      At any rate, I used a Java library for GIF encoding. The only specifically Android lib I could find at the time was a Native lib but I wanted to maintain cross-platform compatibility so I discarded that and used and adapted a Java lib instead. The only problem I had with that was that it assumed RBG instead of RGB. Perhaps this is native to gif or specific to that lib. At any rate, I solved this by doing a pixel-by-pixel conversion to RGB.

      Let me know if you try anything!

      Delete
  10. I am using the above code but my animation is distorted. I have tried different gif images but same result. Do you know why animation is distorting...???

    ReplyDelete
    Replies
    1. This seems to be an Android problem. Some ROMs exhibit the problem, other not.
      I believe the only solution is to not use this method at all, and simply extract each frame and display separately.

      Gif is, unfortunately, poorly supported by Android.

      Delete
  11. How can we use onClick() method on this gif image?

    ReplyDelete
  12. Its working only on API level 3.. This is not working on later versions of SDK.. Anyone faced the same issue??

    ReplyDelete
  13. This comment has been removed by the author.

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. How can I add this to a fragment layout I already have and have it in a specific spot?

    ReplyDelete
  16. hi...sir..first of all thank u so much for this method...bt i need lil help in displaying the .gif image at a specific location.How cn i do that..???

    ReplyDelete
  17. Use
    movie.draw(canvas, ((float) this.getWidth() / (float) movie.width()),
    (float) this.getHeight() / (float) movie.height());

    instead of
    movie.draw(canvas,this.getWidth()/2-20,this.getHeight()/2-40);

    Just you cant set scaletype to fitxy for gif..

    ReplyDelete
  18. if you get blank screen, try this:
    Paint p = new Paint();
    p.setAntiAlias(true);
    setLayerType(LAYER_TYPE_SOFTWARE, p);

    ReplyDelete