'Efficiently converting an array of bitmaps to video
Using the Jcodec library, I had success producing and storing a video file on the Android file system from an array of Bitmap objects.
However, the encoding time takes way too long. I thought about scaling down each of the bitmaps to speed this up but this did not seem to work. Despite researching extensively, I struggled to find a helpful answer.
The below code is currently how I'm creating a bitmap, Where canvasView.getWidth() and canvasView.getHeight() correspond to 1920 x 1280 respectively.
public Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(canvasView.getWidth(), canvasView.getHeight(), Bitmap.Config.RGB_565);
Log.i("Downloading", "OWidth: " + b.getWidth() + " --- " + "OHeight: " + b.getHeight());
Canvas c = new Canvas(b);
c.drawColor(Color.WHITE); // Essential
v.draw(c);
v.invalidate();
v.requestLayout();
return b;
}
I noticed when you change these two parameters to something smaller, IE:
Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
The encoding speeds up dramatically.
The size of the entire view is 1920 x 1280, so the createBitmap method shown above would only capture a small portion of the window (256 x 256), which is not what I require.
I need help finding a way to more efficiently encode an array of bitmaps to video or use the same method I am using but scaling down each bitmap while maintaining the entire image's visibility and speeding up the encoding process.
Solution 1:[1]
I just put up this project that does this without external libs.
Solution 2:[2]
for implementation use these
implementation 'org.jcodec:jcodec:0.2.5'
implementation 'org.jcodec:jcodec-android:0.2.5'
implementation 'org.jcodec:jcodec-javase:0.2.5'
implementation 'com.writingminds:FFmpegAndroid:0.3.2'
fun creteRootPath(): File? {
var file: File? = null
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
file = File(getApplicationContext()
.getExternalFilesDir("")
.toString() + File.separator + "UsamaSd.mp4")
} else {
file = File(Environment
.getExternalStorageDirectory()
.absolutePath.toString()
+ File.separator + "UsamaSd.mp4")
}
if (file?.exists() == true) {
file?.mkdirs()
}
} catch (e: Exception) {
e.printStackTrace()
file // it will return null
}
return file
}
fun convertImagesToVideo() {
try {//Rational(1, 1). SequenceEncoder
val output = creteRootPath()
val enc =
AWTSequenceEncoder.createWithFps(NIOUtils.writableChannel(output),
Rational.R(2, 1))
for (bitmap in arrayOfImagesFinalImages) {
enc.encodeNativeFrame(fromBitmaps(bitmap))
}
enc.finish()
} finally {
NIOUtils.closeQuietly(out);
}
}
fun fromBitmaps(src: Bitmap): Picture {
val dst: Picture = Picture.create(src.width, src.height, RGB)
AndroidUtil.fromBitmap(src, dst)
return dst
}
for AndroidUtil class https://github.com/jcodec/jcodec/blob/master/android/src/main/org/jcodec/common/AndroidUtil.java
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dustin |
| Solution 2 |
