我需要帮助处理我正在处理的应用程序。应用程序必须有一个自定义Camera接口来录制带有音频的视频,并且必须在TextureView画布上实时添加一些对象。不推荐使用Old Camera API,因此我必须使用Camera2 API在TextureView上呈现实时预览。我的目标是在TextureView Canvas之上绘制一些对象,可以是一些text / jpg / gif,而相机流在后台呈现,并且能够使用我的覆盖画布内容和相机提要录制视频。
问题是我可以在透明叠加视图中绘制自定义内容,但这仅供用户查看之用。我已经尝试过研究这几天,但我无法找到正确的方法来解决我的目的。
我在调用openCamera()方法之后尝试了以下代码,但之后我只看到一个绘制的矩形而不是相机预览:
Canvas canvas = mTextureView.lockCanvas();
Paint myPaint = new Paint();
myPaint.setColor(Color.WHITE);
myPaint.setStrokeWidth(10);
canvas.drawRect(100, 100, 300, 300, myPaint);
mTextureView.unlockCanvasAndPost(canvas);
我还尝试了一个自定义的TextureView类并覆盖了vonDrawForeground(Canvas canvas)方法,但它没有用。
TextureView类中的onDraw()方法是最终的,因此,除了流式传输相机源外,此时我无法执行任何操作。
/**
* Subclasses of TextureView cannot do their own rendering
* with the {@link Canvas} object.
*
* @param canvas The Canvas to which the View is rendered.
*/
@Override
protected final void onDraw(Canvas canvas) {
}
简而言之,我希望用户能够通过我的相机应用程序录制视频,并带有一些道具。
答案 0 :(得分:0)
实时修改视频是一个高处理器,因此,高电池开销操作 - 我相信你知道这一点但它的价值说,如果你可以在服务器端添加你的修改,可能通过发送流与一组带时间戳的文本覆盖到服务器,你应该有更多的马力服务器端。
以下代码会将文本和图像添加到Android上Camera2捕获的静态图片或帧中。我没有将它用于视频,因此无法评论速度以及使用实时视频流进行此操作是否切实可行 - 它没有针对此进行优化,但它应该是您的起点:
//Copy the image to a BitBuffer
ByteBuffer buffer = mCameraImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
Log.d(TAG,"ImageSaver bytes.length: " + bytes.length);
buffer.get(bytes);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inMutable = true;
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length, opt);
if (cameraBitmap == null) {
Log.d(TAG,"ImageSaver cameraBitmap is null");
return;
} else {
camImgBitmap = cameraBitmap;
}
//Modify captured picture by drawing on canvas
Canvas camImgCanvas = new Canvas(camImgBitmap);
//Draw an image in the middle
Drawable d = ContextCompat.getDrawable(this, R.drawable.image_to_add);
int bitMapWidthCenter = camImgBitmap.getWidth()/2;
int bitMapheightCenter = camImgBitmap.getHeight()/2;
int imageToDrawSize = camImgBitmap.getWidth()/10;
int rTop = bitMapheightCenter - sightsSize;
int rLeft = bitMapWidthCenter - sightsSize;
int rRight = bitMapWidthCenter + sightsSize;
int rBot = bitMapheightCenter + sightsSize;
d.setBounds(rLeft, rTop, rRight, rBot);
d.draw(camImgCanvas);
//Now Draw in some text
Paint paint = new Paint();
paint.setColor(Color.GREEN);
int textSize = camImgBitmap.getHeight()/20;
int textPadding = 40;
paint.setTextSize(textSize);
camImgCanvas.drawText("Name: " + text1, textPadding, (camImgBitmap.getHeight() - (textSize * 2) ) - textPadding, paint);
camImgCanvas.drawText("Time: " + text2 + " degrees", textPadding, (camImgBitmap.getHeight() - textSize) - textPadding, paint);
答案 1 :(得分:0)
可能性能最佳的选择是将摄像头直接送入GPU,在其上方绘制,然后直接渲染到显示器和视频编码器。
这是许多视频聊天应用程序所做的事情,例如,任何效果。
您可以使用SurfaceTexture将camera2连接到EGL,然后您可以将预览渲染到四边形,然后添加到顶部。
然后,您可以渲染到屏幕缓冲区(例如GLSurfaceView),并从MediaRecorder / MediaCodec Surface渲染到单独的EGLImage。
那里有很多代码,还有很多用于EGL设置的脚手架,因此很难指出任何简单的例子。