- Linux 下使用 QT 调用 opencv 读取摄像头视频 调试心得
- Android 开发 摄像头 SurfaceView 预览 背景带矩形框 实现
- Android 开发:安装 NDK,移植 OpenCV2.3.1,JNI 调用 OpenCV 全过程
- try to load OpenCV.mk from default install location
- Android 摄像头开发完美 demo
- 如何设置 ImageButton 按键按下去后的 特效
- Android 摄像头:只拍摄 SurfaceView 预览界面特定区域内容(矩形框)
- Android 开发:SurfaceView 上新建线程绘制旋转图片 及 刷新特定区域(脏矩形)
- Android 开发:ImageView 上绘制旋转圆环(透明度不同的旋转圆环,利用 canvas.drawArc 实现)
- Android 上掌纹识别第一步:基于 OpenCV 的 6 种肤色分割 源码和效果图
- Android 开发:实时处理摄像头预览帧视频 - 浅析
- Android 摄像头开发:拍照后添加相框,融合相框和图片为一副 图片
- Android(OpenCV) NDK 开发: 0xdeadbaad(code=1) 错误 及 关闭 armeabi 和 libnative_camera_r2.2.2.so 的生成
- Android 摄像头开发:实时摄像头视频预览帧的编码问题(二)
- setContentView 切换页面(无需每次都 findViewById) - 二
- Android 开发:setContentView 切换界面,自定义带 CheckBox 的 ListView 显示 SQlite 条目 - 实现
Android 开发 摄像头 SurfaceView 预览 背景带矩形框 实现
原理:双 surfaceview,顶层画矩形框,底层预览视频
为了能在摄像头预览的时候,背景有个矩形框、或一些坐标、横线来标示关键位置,真让杂家费劲心思了。苦苦研究了两天,毫无进展。baidu 了若干资料,大都是提出这个问题,但怎么解决的没有说,都不了了之。后来转而 google,又研究了两天,终于完美解决啦!
1,网上介绍的摄像头预览,一般是用一个 surfaceview,为了能让其正常预览视频,设置属性
mySurfaceView.setZOrderOnTop(true);
mySurfaceHolder = mySurfaceView.getHolder();
mySurfaceHolder.setFormat(PixelFormat.TRANSPARENT)
我先前也是在这种思路下,看能否加画个矩形框。这篇 http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html 文章提到一种方法,是用一个 surfaceview,然后自己定义一个继承 View 的画矩形框的类 DrawCaptureRect,经我实践,发现还是不中。用这种思路,在摄像头未预览的时候可以看到红色矩形框,但一点击预览,矩形框就被覆盖了。
2,还有一种思路是,在预览 surfaceview 的 callback 里面,取到 canvas 画布,然后画。这种思路也行不通,程序直接挂掉!
3,后来我想到了 framelayout,用帧布局,融合第一种方法的思路,结果还是未能解决预览的时候,视频遮挡矩形框的问题。
4,还有人提出,给 surfaceview 或其所在的布局文件里加一个带矩形框的图片的方法,更是行不通!说这话的人真是站着不腰疼,别说背景设成带图片的矩形框,就是背景设成有颜色的,预览的 surfaceview 就不显示了,被遮挡了。
原来,当 SurfaceHolder 对象的类型设置为 SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS 时就只能拍照不能绘制了 ,这就是为什么第二种思路程序会直接挂掉的原因。为了能够预览视频的同时绘制矩形框等信息,需要用两个同样大小的 SurfaceView 放在一个 FrameLayout 里,顶层的 SurfaceView 设成 setZOrderOnTop(true); setFormat(PixelFormat.TRANSPARENT);预览的 Surfaceview 这两个属性就不用设置了。
首先在包 yan.guoqi.testphoto 下新建一个类 SVDraw,如图:
源码如下:
package yan.guoqi.testphoto;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
/*定义一个画矩形框的类*/
public class SVDraw extends SurfaceView implements SurfaceHolder.Callback{
protected SurfaceHolder sh;
private int mWidth;
private int mHeight;
public SVDraw(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
sh = getHolder();
sh.addCallback(this);
sh.setFormat(PixelFormat.TRANSPARENT);
setZOrderOnTop(true);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int w, int h) {
// TODO Auto-generated method stub
mWidth = w;
mHeight = h;
}
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
void clearDraw()
{
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.BLUE);
sh.unlockCanvasAndPost(canvas);
}
public void drawLine()
{
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.TRANSPARENT);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.RED);
p.setStyle(Style.STROKE);
//canvas.drawPoint(100.0f, 100.0f, p);
canvas.drawLine(0,110, 500, 110, p);
canvas.drawCircle(110, 110, 10.0f, p);
sh.unlockCanvasAndPost(canvas);
}
}
类里面的方法 drawLine()
就是画预览视频时背景矩形的,由于我需画一条线,上面程序就是画一条线和一个圆的。需要画什么图形,就在这里改!
注意在建这个类时构造函数里一定要有
public SVDraw(Context context, AttributeSet attrs) {
super(context, attrs);
AttributeSet attrs 这个参数,否则是不能在 xml 文件里正常解析的。先前提到的 http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html 这位就没有引用这个参数,所以后来用了
addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT))
将这个对象加到布局中去!
上面的类建好之后,在布局文件里引用他,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/myFramelayout"
android:layout_width="fill_parent"
android:layout_height="800px"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/mySurfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:visibility="visible" />
<yan.guoqi.testphoto.SVDraw
android:id="@+id/mDraw"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
android:paddingTop="10dip" >
<Button
android:id="@+id/btnPreview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="预览"
android:textSize="28sp" />
<Button
android:id="@+id/btnPhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拍照"
android:textSize="28sp" />
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:textSize="28sp" />
</LinearLayout>
</LinearLayout>
注意上面两个 surfaceview 是同样大小的,mySurfaceView 是预览视频的,mDraw 是用来画矩形的。
接下来就是在主 Activity 里引用这个 mDraw。首先定义变量 private SVDraw mSVDraw = null; 然后 mSVDraw = (yan.guoqi.testphoto.SVDraw)findViewByIf(R.id.mDraw)。之后 mSVDraw 就可以用了,至于什么时候来画这个矩形,有人是在按下拍照按钮后,我选择的是在按下预览按钮后,
case R.id.btnPreview:
Toast.makeText(TestPhotoActivity.this,
"您按了预览按钮",
Toast.LENGTH_SHORT).show();
initCamera();
mDraw.setVisibility(View.VISIBLE);
mDraw.drawLine();
break;
让其可见,然后调用 drawLine()方法就可以了!你可以随时控制让其可见或者隐藏!
将上面这些代码融合我 http://blog.csdn.net/yanzi1225627/article/details/7926994 文章里 http://download.csdn.net/detail/yanzi1225627/4538626 这里的源码就可以了!即可以预览,自动聚焦,缩放标准大小,背景有矩形框!
来张图,有图有真相
反思:其实用第一种 http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html 这里的思路和本篇的思路合并起来,应该也是可行的,只不过一个是继承的 view 一个是 surfaceview,将 AttributeSet attrs 加上。只要处理好谁是顶层的 view 谁设成透明,预览视频的 surfaceview 设成底层,在且要在 xml 属性文件里设成 visible 就可以了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论