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();
}
}

44 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
  19. This comment has been removed by the author.

    ReplyDelete
  20. Hi! that's very nice work. I need help in showing gif animation in view so that i could set its position in activity and want to add some other items to that activity.

    ReplyDelete
  21. Hey, I want to set Gif Image for particular ListView.
    i want to do that for MediaPlayer, so what i have to do..??

    ReplyDelete
  22. Hey it crash and error message is :

    atal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 7333 (example.showgif)

    ReplyDelete
    Replies
    1. Same issue in here :/
      on Note 3 under Lollipop
      any idea/correction please ?

      Delete
    2. This comment has been removed by the author.

      Delete
    3. I had this error. I fixed it by putting application android:hardwareAccelerated="false" into my manifest to disable hardware acceleration.

      Delete
    4. This android:hardwareAccelerated="false" works like a charm.

      Delete
  23. This comment has been removed by the author.

    ReplyDelete
  24. What about the xml file ??? What should i pun in my xml file?

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

    ReplyDelete
  26. i am getting airthmetic exception - divided by zero at
    this line -

    int relTime = (int) ((now - moviestart) % movie.duration());

    ReplyDelete
  27. and why you change name of your constructor-

    i think constructor name should same as class name...not??
    you defined this :-

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

    // Provide your own gif animation file

    is = context.getResources().openRawResource(R.raw.gif_demo_img);
    movie = Movie.decodeStream(is);

    }

    and this is giving complile time error,
    correct me if i am wrong

    ReplyDelete
  28. finally i change constructor name and replace
    System.out.println()
    with
    Toast popup

    and when i launch, its only showing popup which indicating
    moviestart=4415249
    time=524
    reltime=4480

    but not gif,
    whole activity is blank white

    ReplyDelete
  29. Fetching Problem while changing gif file. I had 2 gif in my draw able folder. But when i try to put it the place u indicates. its showing error.

    ReplyDelete