从 gif / 视频保存位图

Save bitmaps from gif / video

我想保存 GIF 文件和视频文件的单个图像(位图)。我想要每个文件的 5 张图片。根据文件的长度(秒),图片要每隔一定时间拍照,这样就有5张了。希望有人能帮帮我,谢谢!

您可以使用 Android-Ndk-Gif 库来处理您的需求,这里有一个完整的示例,说明如何从 GIF 中获取每个位图,您可以将 gifDecoder.frameNum() 更改为 4,以便获取前 5 个来自您的 GIF 的帧

 GifDecoder gifDecoder = new GifDecoder();
 boolean isSucceeded = gifDecoder.load(Path); // PATH OF YOUR IMAGE
 ArrayList<BitmapGIFUtil> arrayListBitmaps = new ArrayList<>();

 for (int i = 0; i < gifDecoder.frameNum(); ++i) {
                Bitmap bitmap = gifDecoder.frame(i);
                int GIFDelay = gifDecoder.delay(i);
                arrayListBitmaps.add(new BitmapGIFUtil(bitmap, GIFDelay));
     }

BitmapGIFUtil.java

public class BitmapGIFUtil {
    private Bitmap bitmap;
    private int Delay;

    public BitmapGIFUtil() {
    }

    public BitmapGIFUtil(Bitmap bitmap, int delay) {

        this.bitmap = bitmap;
        Delay = delay;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

    public int getDelay() {
        return Delay;
    }

    public void setDelay(int delay) {
        Delay = delay;
    }
}

填写完 arrayListBitmaps 后,您可以将每个 bitmap 保存到您的图库中

我用 Glide 找到了一个很好的解决方案(对于 gif):

 Glide.with(Activity.this)
                                .asGif()
                                .load(picturePath)
                                .into(new SimpleTarget<GifDrawable>() {
                                    @Override
                                    public void onResourceReady(@NonNull GifDrawable resource, @Nullable Transition<? super GifDrawable> transition) {
                                        try {
                                            Object GifState = resource.getConstantState();
                                            Field frameLoader = GifState.getClass().getDeclaredField("frameLoader");
                                            frameLoader.setAccessible(true);
                                            Object gifFrameLoader = frameLoader.get(GifState);

                                            Field gifDecoder = gifFrameLoader.getClass().getDeclaredField("gifDecoder");
                                            gifDecoder.setAccessible(true);
                                            StandardGifDecoder standardGifDecoder = (StandardGifDecoder) gifDecoder.get(gifFrameLoader);
                                            for (int i = 0; i < standardGifDecoder.getFrameCount(); i++) {

                                                standardGifDecoder.advance();

                                                if (i == 4) {
                                                    bitmap1 = standardGifDecoder.getNextFrame();
                                                } else if (i == standardGifDecoder.getFrameCount() / 3) {
                                                    bitmap2 = standardGifDecoder.getNextFrame();
                                                } else if (i == standardGifDecoder.getFrameCount() / 2) {
                                                    bitmap3 = standardGifDecoder.getNextFrame();
                                                } else if (i == standardGifDecoder.getFrameCount() - 4) {
                                                    bitmap4 = standardGifDecoder.getNextFrame();
                                                }

                                            }

                                        } catch (Exception ex) {
                                            ex.printStackTrace();
                                        }

                                    }
                                });

这是一个使用 MediaMetadataRetriever 的解决方案(针对视频):

            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(videoFile.getAbsolutePath());
            MediaPlayer mp = MediaPlayer.create(getBaseContext(), vidUri);
            mp.release();
            String strLength = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            long time=Long.valueOf(strLength)*1000;

                bitmap1 = retriever.getFrameAtTime(time/10*2,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                bitmap2 = retriever.getFrameAtTime(time/10*4,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                bitmap3 = retriever.getFrameAtTime(time/10*6,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                bitmap4 = retriever.getFrameAtTime(time/10*8,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);