如何在 Android 上的 Camera 使用的 SurfaceView 上绘制叠加层?
我有一个简单的程序,可以将Camera
的预览绘制到SurfaceView
中。我想做的是使用 onPreviewFrame
方法,每次将新帧绘制到 SurfaceView
中时都会调用该方法,以便执行 invalidate
方法应该调用 onDraw
方法。事实上,onDraw
方法正在被调用,但没有打印任何内容(我猜相机预览正在覆盖我试图绘制的文本)。
这是我拥有的 SurfaceView 子类的简化版本:
public class Superficie extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Superficie(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(final SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
invalidar();
}
});
} catch (IOException e) {}
}
public void invalidar(){
invalidate();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// nothing gets drawn :(
Paint p = new Paint(Color.RED);
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}
I have a simple program that draws the preview of the Camera
into a SurfaceView
. What I'm trying to do is using the onPreviewFrame
method, which is invoked each time a new frame is drawn into the SurfaceView
, in order to execute the invalidate
method which is supposed to invoke the onDraw
method. In fact, the onDraw
method is being invoked, but nothing there is being printed (I guess the camera preview is overwriting the text I'm trying to draw).
This is a simplify version of the SurfaceView
subclass I have:
public class Superficie extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Superficie(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(final SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
invalidar();
}
});
} catch (IOException e) {}
}
public void invalidar(){
invalidate();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// nothing gets drawn :(
Paint p = new Paint(Color.RED);
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这方面,
SurfaceView
可能不像常规View
那样工作。相反,请执行以下操作:
SurfaceView
放入FrameLayout
或RelativeLayout
中你的布局 XML 文件,因为
那些允许堆叠小部件
Z轴
到一个单独的自定义
View
类中类作为布局 XML 文件
FrameLayout
的子级或RelativeLayout
,但让它出现在
SurfaceView
之后这将导致您的自定义
View
类看起来浮动在SurfaceView
之上。SurfaceView
probably does not work like a regularView
in this regard.Instead, do the following:
SurfaceView
inside of aFrameLayout
orRelativeLayout
inyour layout XML file, since both of
those allow stacking of widgets on
the Z-axis
into a separate custom
View
classclass to the layout XML file as a
child of the
FrameLayout
orRelativeLayout
, but have it appearafter the
SurfaceView
This will cause your custom
View
class to appear to float above theSurfaceView
.尝试从
surfaceCreated
调用setWillNotDraw(false)
:并从
onTouchEvent
调用invalidate
:Try calling
setWillNotDraw(false)
fromsurfaceCreated
:and calling
invalidate
fromonTouchEvent
:我认为在 SurfaceView 的绘制方法中执行任何操作之前,您应该先调用 super.draw() 方法。
I think you should call the
super.draw()
method first before you do anything in surfaceView's draw method.