我正在尝试从视频相机获取的JPEG中制作GIF动画。但这个过程非常漫长。我使用了两个不同的库。第一个是使用本地C++代码编写的,第二个是Java的一个。
也许还有其他有用的日志:
我尽可能地压缩帧,但即使如此,仍无法减少生成时间。
本地库处理5秒视频(80帧)需要80-100秒,而Java的库只需要40-60秒(我不知道为什么Java会快两倍,但日志显示了这个结果)。
我根据这个稍微修改了一下C ++算法,因为我遇到了同样的问题(尝试用改变一小段代码和整个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");
}
我很乐意展示与此相关的其他代码。非常感谢任何帮助。
[更新]
检索位图的日志:
D/TimeUtils: Retrieving bitmap executed in 3ms
D/TimeUtils: Retrieving bitmap executed in 3ms
D/TimeUtils: Retrieving bitmap executed in 4ms