我正在尝试从摄像机获得的 jpeg 制作 gif 动画。但这个过程却异常漫长。我使用了两个不同的库。First http://jiggawatt.org/badc0de/android/#gifflen是用本机 C++ 代码编写的,其次是 Java 的one https://github.com/nbadal/android-gif-encoder.
我尽可能压缩帧,但即使这样也不能减少生成时间。
对于 16 fps 的 5 秒视频(每个 gif 80 帧),本机库大约需要 80-100 秒,Java 大约需要 40-60 秒(我不知道 java 是如何快 2 倍的,但日志向我显示了这个结果)。
我根据以下内容改变了一点C++算法this https://stackoverflow.com/questions/18075421/gifflen-fatal-signal-11,因为我遇到了同样的问题(尝试了两个版本,更改一段代码并更改整个learn()
功能)。
在这里你可以看到一段日志:
这是本机实现中的最后三帧:
D/TimeUtils: Adding frame executed in 949ms
D/TimeUtils: Adding frame executed in 976ms
D/TimeUtils: Adding frame executed in 1028ms
D/TimeUtils: Creating gif with native library executed in 82553ms
这是 Java 版本的最后三帧:
D/TimeUtils: Adding frame executed in 541ms
D/TimeUtils: Adding frame executed in 513ms
D/TimeUtils: Adding frame executed in 521ms
D/TimeUtils: Creating gif with nbadal's library executed in 44811ms
也许还有一些其他有用的日志:
D/CameraActivity: Duration of the captured video is 5000ms
V/CameraActivity: Dimensions are 288w x 288h
D/CameraActivity: Final bitmaps count: 80
TimeUtils.java 包含静态方法来检查方法执行的时间。
NativeGifConverter.java(仅转换功能):
@Override public void createGifFile(String path, List<String> bitmapPaths) {
Bitmap bitmap = BitmapUtils.retrieve(bitmapPaths.get(0));
if (init(path, bitmap.getWidth(), bitmap.getHeight(), mNumColors, mQuality, mFrameDelay) != 0) {
Timber.e("Gifflen init failed");
return;
}
bitmap.recycle();
for (String bitmapPath : bitmapPaths) {
bitmap = howLong("Retrieving bitmap", () -> BitmapUtils.retrieve(bitmapPath));
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
final int[] pixels = new int[width * height];
final Bitmap finalBitmap = bitmap; // for counting time
howLongVoid("Retrieving pixels", () -> finalBitmap.getPixels(pixels, 0, width, 0, 0, width, height));
howLongVoid("Adding frame", () -> addFrame(pixels));
bitmap.recycle();
}
bitmap = null;
close();
}
NbadalGifConverter.java(仅转换功能):
@Override public void createGifFile(String path, List<String> bitmapsNames) {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.setDelay(mDelay);
encoder.setQuality(mQuality);
encoder.start(bos);
for (String bitmapName : bitmapsNames) {
final Bitmap bitmap = howLong("Retrieving bitmap", () -> BitmapUtils.retrieve(bitmapName));
howLongVoid("Adding frame", () -> encoder.addFrame(bitmap));
}
encoder.finish();
FileUtils.store(bos.toByteArray(), path.substring(0, path.lastIndexOf('.')) + ".gif");
}
我愿意向您展示另一段相关的代码。我将非常感谢任何帮助。
[UPDATE]
检索位图的日志:
D/TimeUtils: Retrieving bitmap executed in 3ms
D/TimeUtils: Retrieving bitmap executed in 3ms
D/TimeUtils: Retrieving bitmap executed in 4ms