Search code examples
androidsharinganimated-gifandroid-glideandroid-sharing

Glide sharing transformed GIF


I'd like to share GIFs I loaded with Glide but i can't find a way to do it.

I tried to share the GifDrawable data as an array of byte but when i try to share, the GIF doesn't appear.

Here's the code I wrote :

Glide.with(getActivity())
        .load(to_add.mMeme.getmUrl())
        .asGif()
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .transformFrame(new TextTransformation(getContext(), to_add.mMeme.getmText()))
        .listener(new RequestListener<String, GifDrawable>() {
            @Override
            public boolean onException(Exception e, String s, Target<GifDrawable> target, boolean b) {
                return false;
            }

            @Override
            public boolean onResourceReady(GifDrawable gifDrawable, String s, Target<GifDrawable> target, boolean b, boolean b1) {
                to_add.mDrawable = gifDrawable;
                to_add.mView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Meme to_share = null;
                        for (Meme meme : mViewList) {
                            if (meme.mView.equals(v)) {
                                to_share = meme;
                                break;
                            }
                        }
                        if (to_share != null) {
                            Intent shareIntent = new Intent();
                            shareIntent.setAction(Intent.ACTION_SEND);
                            shareIntent.setType("image/*");
                            shareIntent.putExtra(Intent.EXTRA_STREAM, to_share.mDrawable.toString());
                            startActivity(Intent.createChooser(shareIntent, "Share"));
                        }
                    }
                });
                return false;
            }
        })
        .into((ImageView) to_add.mView.findViewById(R.id.memeImageView));

Here is my Meme class used in the previous code :

public static class Meme {
    public Meme(StorageManager.Meme meme, View view) {
        mMeme = meme;
        mView = view;
    }

    StorageManager.Meme mMeme;
    View mView;
    GifDrawable mDrawable;
}

mViewList is a List of Meme:

List<Meme> mViewList;

And to_add variable is the Meme containing the GIF i'm trying to share :

final Meme to_add = new Meme(data, getActivity().getLayoutInflater().inflate(R.layout.meme_layout, null));

Solution

  • I miss understood how to use share intents.

    Sharing with intents

    To answer my question, sharing a file with a Share intent require the file to be accessible on drive. That's why I had to write it in the cache memory using :

    File file = new File(mContext.getExternalCacheDir(), myMeme.getmFileName());
    file.setReadable(true);
    

    Don't write your file in your App cache dir, otherwise file will not be accessible by other applications

    mContext.getCacheDir()
    

    Then I could easily share my File using Uris :

    Uri uri = Uri.fromFile(file);
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.setType("image/gif");
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    startActivity(Intent.createChooser(shareIntent, "Share with"));
    

    Sharing works perfectly now.

    Concerning Glide GIF

    I wasn't able to get Glide transformed GIF. To add my text to the GIF, i splitted all frames composing the GIF and writted down the text.

    Split GIF into frames using Glide

    GifDecoder decoder = mGif.getmDrawable().getDecoder();
    Bitmap frame;
    
    Log.d("GIF GENERATION", "STARTED FRAME SPLIT");
    int max = mGif.getmDrawable().getFrameCount();
    int current = 0;
    decoder.advance();
    while (current < max && (frame = decoder.getNextFrame()) != null) {
        Log.d("GIF GENERATION", "ADDED FRAME");
        // Here you get your GIF frame per frame
        decoder.advance();
        current++;
    }
    Log.d("GIF GENERATION", "ENDED FRAME SPLIT");
    

    Adding text to every frame

    To write down my text on every frame, I used this class that works perfectly for single line text : http://www.skoumal.net/en/android-how-draw-text-bitmap/

    Creating new GIF with frames

    To do that, I used another class called GifCreator. It can be found here : https://github.com/nbadal/android-gif-encoder

    Final Result

    Here's how the actual code is :

    GifDecoder decoder = mGif.getmDrawable().getDecoder();
    GifCreator creator = new GifCreator();
    Bitmap frame;
    
    creator.start(mOs);
    creator.setSize(mGif.getmDrawable().getDecoder().getWidth(), mGif.getmDrawable().getDecoder().getHeight());
    creator.setRepeat(0);
    creator.setQuality(15);
    
    Log.d("GIF GENERATION", "STARTED FRAME SPLIT");
    int max = mGif.getmDrawable().getFrameCount();
    int current = 0;
    decoder.advance();
    
    while (current < max && (frame = decoder.getNextFrame()) != null) {
        Log.d("GIF GENERATION", "ADDED FRAME");
        creator.addFrame(TextTransformation.drawTextToBitmap(mContext, temp, mText));
        creator.setDelay(decoder.getNextDelay());
        decoder.advance();
        current++;
    }
    Log.d("GIF GENERATION", "ENDED FRAME SPLIT");
    
    creator.finish();