我正在从手机外部存储中的静态图像创建视频。该视频将类似于图像的自动幻灯片放映。我已经为此使用了 JCodec。
下面是我的代码。
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import org.jcodec.common.model.ColorSpace;
import org.jcodec.common.model.Picture;
import java.io.File;
import java.io.IOException;
public class VideoActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
video();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Video Created") //
.setMessage("Hi this video is created") //
.setPositiveButton("Play", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// TODO
Log.d("dee","On Click on the play button");
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/output97.mp4"));
intent.setDataAndType(Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+"/output97.mp4"), "video/mp4");
startActivity(intent);
dialog.dismiss();
}
}) //
.setNegativeButton(("Share"), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
Uri uri = Uri.fromFile(GetSDPathToFile("","output67.mp4"));
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setDataAndType(uri, "video/*");
intent.setType("video/mp4");
startActivity(intent);
dialog.dismiss();
}
});
builder.show();
}
public void video() {
try {
//Harsh bhaiya change the directory name in the GetSdToPath() Function in the belwo 1 lines
File file = this.GetSDPathToFile("", "output97.mp4");
NewSequenceEncoder encoder = new NewSequenceEncoder(file);
File folder = new File(Environment.getExternalStorageDirectory() +"/numeros/fshhaq/") ;
File[] listFile = folder.listFiles();
// only 5 frames in total
String text = "Numero";
for (int i = 1; i <= listFile.length; i++) {
String _path=listFile[i-1].getAbsolutePath();
Log.d("dee","pathhhhhhhhhhhh12"+_path);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
//Log.d("dee","reached here");
Log.d("dee","image " + i);
Typeface tf = Typeface.create("Helvitica", Typeface.NORMAL);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTypeface(tf);
Log.d("dee","reached before the typface");
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(convertToPixels(getApplicationContext(),16));
Rect textRect = new Rect();
Log.d("dee","created the rectange");
paint.getTextBounds(text, 0, text.length(), textRect);
// Log.d("dee","reached here2");
Canvas canvas = new Canvas(mutableBitmap);
Log.d("dee","reached here3");
//If the text is bigger than the canvas , reduce the font size
if (textRect.width() >= (canvas.getWidth() - 4)) //the padding on either sides is considered as 4, so as to appropriately fit in the text
{
Log.d("dee", "Let us know");
paint.setTextSize(convertToPixels(getApplicationContext(), 7)); //Scaling needs to be used for different dpi's
}
//Calculate the positions
int xPos= (canvas.getWidth() -105); //-2 is for regulating the x position offset
Log.d("dee","reached the jesus");
Log.d("dee",canvas.getWidth() + "");
Log.d("dee",canvas.getWidth() + " sbjgbsdj " + canvas.getHeight());
//"- ((paint.descent() + paint.ascent()) / 2)" is the distance from the baseline to the center.
int yPos = (int) ((canvas.getHeight())-50);
canvas.drawText("00O", xPos, yPos, paint);
//int bitmapResId = this.getB.getIdentifier("image" + (i),"drawable", this.getPackageName());
//Log.d("dee", this.getResources().getIdentifier("image" + (i), "drawable", this.getPackageName()) + " " +" is the no");
Log.d("dee","image "+i+"This is the required image number");
//Log.d("dee",this.getBitmapFromResources(getApplicationContext().getResources(),bitmapResId).toString());
// Bitmap bitmap = getBitmapFromResources(this.getResources(), bitmapResId);
//Log.d("dee",R.drawable.class.getResource().l +" fields in drawable");
//BitmapDrawable bitmap1 = this.writeTextOnDrawable(bitmapResId,"NUMERO",getApplicationContext());
Picture pic = this.fromBitmap(mutableBitmap);
//Toast.makeText(getApplicationContext(),"Image +" + i,Toast.LENGTH_SHORT).show();
Log.d("dee",pic.getColor() +" "+pic.createCompatible());
encoder.encodeNativeFrame(pic);
Log.d("dee","reached here4");
}
Log.d("dee","reached here5");
// int bitmapResId = this.getResources().getIdentifier("image6", "drawable", this.getPackageName());
//Log.d("dee",this.getBitmapFromResources(getApplicationContext().getResources(),bitmapResId).toString());
//Bitmap bitmapp = getBitmapFromResources(this.getResources(), bitmapResId);
Log.d("dee","reached here6");
// Picture pic = this.fromBitmap((bitmapp));
//Log.d("dee",pic.getWidth() + " " + pic.getHeight());
Log.d("dee","reached here7");
//encoder.encodeNativeFrame(pic);
Log.d("dee","reached here9");
encoder.finish();
Log.d("dee","reached here8");
} catch (IOException e) {
e.printStackTrace();
}
}
private Bitmap getBitmapFromResources(Resources resources, int bitmapResId) {
return BitmapFactory.decodeResource(resources, bitmapResId);
}
//Change the path in the below function harsh bhaiya
protected File GetSDPathToFile(String filePatho, String fileName) {
File extBaseDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
Log.d("dee", Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).toString());
if (filePatho == null || filePatho.length() == 0 || filePatho.charAt(0) != '/')
filePatho = "/" + filePatho;
createDirIfNotExists(filePatho);
File file = new File(extBaseDir.getAbsoluteFile() + filePatho);
return new File(file.getAbsolutePath() + "/" + fileName);// file;
}
//cahnge in this one too
public static boolean createDirIfNotExists(String path) {
boolean ret = true;
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), path);
if (!file.exists()) {
if (!file.mkdirs()) {
Log.e("TravellerLog :: ", "Problem creating Image folder");
ret = false;
}
}
return ret;
}
public Picture fromBitmap(Bitmap src) {
Picture dst = Picture.create(src.getWidth(), src.getHeight(), ColorSpace.RGB);
fromBitmap(src, dst);
Log.d("dee", dst.getWidth() + "");
return dst;
}
public void fromBitmap(Bitmap src, Picture dst) {
int[] dstData = dst.getPlaneData(0);
int[] packed = new int[src.getWidth() * src.getHeight()*4];
src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight());
for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) {
for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) {
int rgb = packed[srcOff];
dstData[dstOff] = (rgb >> 16) & 0xff;
dstData[dstOff + 1] = (rgb >> 8) & 0xff;
dstData[dstOff + 2] = rgb & 0xff;
}
}
}
public static int convertToPixels(Context context, int nDP)
{
final float conversionScale = context.getResources().getDisplayMetrics().density;
return (int) ((nDP * conversionScale) + 0.5f) ;
}
}
我收到 ArrayIndexOutOfBoundsException 错误。以下是logcat
Process: org.example.android.numero, PID: 8567 java.lang.RuntimeException: Unable to start activity ComponentInfo{org.example.android.numero/org.example.android.numero.VideoActivity}: java.lang.ArrayIndexOutOfBoundsException: length=589824; index=589824
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access$800(ActivityThread.java:147)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5237)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=589824; index=589824
at org.jcodec.scale.RgbToYuv420j.rgb2yuv(RgbToYuv420j.java:72)
at org.jcodec.scale.RgbToYuv420j.transform(RgbToYuv420j.java:38)
at org.example.android.numero.NewSequenceEncoder.encodeNativeFrame(NewSequenceEncoder.java:68)
at org.example.android.numero.VideoActivity.video(VideoActivity.java:124)
at org.example.android.numero.VideoActivity.onCreate(VideoActivity.java:36)
at android.app.Activity.performCreate(Activity.java:5982)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2258)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access$800(ActivityThread.java:147)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5237)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
谁能建议我哪里出错了?感觉图片的分辨率有问题。
编辑:我已将 JCodec ( sequenceEncoder
) 中的一个方法重写为newSequenceEncoder
,以控制视频的每秒帧数。