Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add subsampling option #239

Closed
huyduongtu opened this issue Jan 5, 2016 · 21 comments
Closed

Add subsampling option #239

huyduongtu opened this issue Jan 5, 2016 · 21 comments

Comments

@huyduongtu
Copy link

Firstly, thanks for your library. It works well and save my life a lot
In your lib, you create a Bitmap in java heap with size based on the width and height of each frame. Foe each frame, you set the corresponding color pixel of the bitmap in native.
But If the gif size is so big (width and height of each frame are big also) and the imageview is small. I'm afraid of creating the bitmap can causes OutOfMemoryError in low-end devices.
How can I scale down the bitmap size?
I mean, I can pass the actual width, height of the ImageView, then the library can scale down the frame size base on those argument. This is similar to BitmapFactory.Options.inSampleSize.
Thanks in advance.

@koral--
Copy link
Owner

koral-- commented Jan 5, 2016

Currently there is no way reduce size of bitmaps used as frame buffers in GifDrawable from code. There are only indirect ways to reduce overall memory usage in given moment of time eg. by reusing existing GifDrawable instances instead of creating them from scratch.
However I'll add resampling option ASAP.

@koral-- koral-- changed the title Scale down Bitmap Add subsampling option Jan 5, 2016
@huyduongtu
Copy link
Author

Thanks for your quick response. Could you tell the way to reuse existing GifDrawable?
And when subsampling option is available?
Edit:
I'm playing Gif in ListView(maybe once at a time or many which depends on performance). I just wanna use GifDrawable, not GifTextureView, because my view is custom view. What should I do?
I see GifDrawableBuilder in your lib, but don't know how to use it. Please provide documentation of it to reuse GifDrawable to reduce memory usage.

@koral--
Copy link
Owner

koral-- commented Jan 7, 2016

Reusing existing GifDrawable is similar to BitmapFactory.Options.inBitmap. You have to pass existing drawable to GifDrawableBuilder. I've added that to sample project.
Another workaround is to use GifTextureView, in such case no Bitmaps are needed.
I can't promise exact time when subsampling will be added.

@huyduongtu
Copy link
Author

You said "Sets drawable to be reused when creating new one. Currently it works only on KITKAT and newer, on older API levels call has no effect.". Older version can not use this way.
About GifTextureView, I don't understand how it works. Can you clarify it for me?
The secret is

 final Surface surface = new Surface(surfaceTexture);
 try {
      mGifInfoHandle.bindSurface(surface, mSavedState, gifTextureView.isOpaque());
 } finally {
      surface.release();
 }

Is it right?

@koral--
Copy link
Owner

koral-- commented Jan 7, 2016

Note about Kitkat in javadoc is outdated, this issue reminded me to remove it and it is not present in the latest snapshot. Drawable reusing is working in all API levels.

For GifTextureView you have to use #setInputSource. Keep in mind that TextureView is available since API level 14 and requires hardware accelerated window.

@huyduongtu
Copy link
Author

Thanks. Hope to see the next subsampling feature soon.

@huyduongtu
Copy link
Author

One more question. I'm implementing a cache that keeps GifDrawable in memory. I wonder how much space does GifDrawable take in memory? It is much? Because I've had some other ones already.
In my opinion, GifDrawable just has only one bitmap for the current frame, the rest is in native memory. So it is ok to keep them in memory? Right?

@koral--
Copy link
Owner

koral-- commented Jan 7, 2016

There is always one Bitmap in terms of android.graphics.Bitmap. If GIF uses "Restore to previous" disposal method then additionally memory of size equal to bitmap (4 bytes per pixel) is allocated in native code.
I would say that the same rules as used with Bitmaps applies, so when number of used objects is high enough (depends on targeted devices and expected bitmap sizes) then instead of keeping all of them, some cache should be used. Like LRUCache: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

@huyduongtu
Copy link
Author

So Does your lib use "Restore to previous" disposal method? Because native memory is stilled counted in limited memory used for an Android application. I need to know to consider how much space for the GifDrawable cache.

@koral--
Copy link
Owner

koral-- commented Jan 11, 2016

Not sure if I understand correctly, but try to answer.
Library does not "use" "Restore to previous". Only creator of a GIF file can use it. If GIF is animated then each frame descriptor contains information how it should be disposed. There are 3 methods available: http://www.imagemagick.org/Usage/anim_basics/#dispose
Library supports all of them appropriately.

@huyduongtu
Copy link
Author

So the most memory space taken by an instance GifDrawable is a Bitmap (in heap memory)?The rest is the information of the Gif file?

@koral--
Copy link
Owner

koral-- commented Jan 11, 2016

It is true that that most of the memory is consumed by Bitmap in GifDrawable (width * height * 4 bytes + overhead of Bitmap internal data) but in the rest apart from information about GIF file there are 2 things:

@huyduongtu
Copy link
Author

Got it. Thanks.

@ghost
Copy link

ghost commented Jan 19, 2016

your library is very helpful it is load GIF with low efficiency.is there any method does your libaray can build gif from combine bitmap?

@koral--
Copy link
Owner

koral-- commented Jan 20, 2016

@manoj99 unfortunately not yet, but such option may be added in the future.

@koral--
Copy link
Owner

koral-- commented Jan 25, 2016

Subsampling draft:

  • size of the canvas, frame and offsets should be seen scaled everywhere except DDGifSlurp, so drawing logic should work OOTB
  • dimensions scaling will occur in DDGifSlurp just after calling DGifGetImageDesc
  • raster size will be unchanged but after calling DGifGetLine it will be subsampled (using the same memory block)
  • it must be guaranteed that canvas size will not be smaller than 1x1 px

@koral--
Copy link
Owner

koral-- commented Feb 15, 2016

Subsampling option is now available on dev branch and on maven snapshot repository. It can be enabled using GifDrawableBuilder#sampleSize().

@huyduongtu
Copy link
Author

Thanks. Is it stable?

@koral--
Copy link
Owner

koral-- commented Feb 17, 2016

Yeah, it should be.

@koral--
Copy link
Owner

koral-- commented Feb 22, 2016

It look like everything is ready, including javadocs and subsampling is going to be included in v 1.1.14.

@huyduongtu
Copy link
Author

Thanks. Wait for it is available on the master branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants