I'm trying to make gif animation from jpegs I get from video camera. But this process is unreal long. I used two different libraries. First is written with native C++ code and second is Java's one.
I compress frames as I can, but even this cannot reduce generating time.
Native library takes about 80-100 seconds and Java's takes about 40-60 seconds (I don't know how java is 2 times faster, but logs show me this result) for 5 seconds video with 16 fps (80 frames per gif).
I changed a bit C++ algorithm according to this, because I got same problem (tried both versions with changing a piece of code and changing whole learn()
function).
Here you can see piece of logs:
It's last three frames in native implementation:
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
It's last three frames in Java's version:
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
Maybe some other useful logs:
D/CameraActivity: Duration of the captured video is 5000ms
V/CameraActivity: Dimensions are 288w x 288h
D/CameraActivity: Final bitmaps count: 80
TimeUtils.java contains static methods to check how long method executes.
NativeGifConverter.java (only converting function):
@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 (only converting function):
@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");
}
I'm open to show you another related pieces of code. I would greatly appreciate any help.
[UPDATE]
Logs of the retrieving bitmaps:
D/TimeUtils: Retrieving bitmap executed in 3ms
D/TimeUtils: Retrieving bitmap executed in 3ms
D/TimeUtils: Retrieving bitmap executed in 4ms