android 使用两个surfaceview 在摄像机画面上绘图
使用双surface,将第一个设置为透明背景,在摄像机上绘制图像,纠结搞了一天。
其中参考了http://blog.csdn.net/yanzi1225627/article/details/7934710 的思路和代码,但是,始终会出现 canvas=holder.lockcanvas();返回的canvas为null的情况。加入线程后解决问题。
主Activity:
public class MainActivity extends Activity {
private SVDraw surfaceDraw = null;
private SurfaceView surfaceView = null;
private SurfaceHolder holder1 = null;
private Canvas canvas = null;
private Camera cam = null;
private boolean previewRunning = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绘制surface1
surfaceView = (SurfaceView) findViewById(R.id.surface1);
holder1 = surfaceView.getHolder();
holder1.addCallback(new MySurfaceViewCallback());
holder1.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder1.setFixedSize(500, 350);
holder1.setFormat(PixelFormat.TRANSPARENT);
canvas = holder1.lockCanvas();
if (canvas != null) {
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);
}
// 绘制surface2 其中使用线程
surfaceDraw = (SVDraw) findViewById(R.id.mDraw);
surfaceDraw.setVisibility(View.VISIBLE);
surfaceDraw.drawLine();
}
// =============================create surface 1=================================================
private class MySurfaceViewCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@SuppressWarnings("deprecation")
@Override
public void surfaceCreated(SurfaceHolder holder) {
cam = Camera.open(); // 取得第一个摄像头
Parameters param = cam.getParameters();
// param.setPreviewSize(display.getWidth(), display.getHeight()) ;
param.setPreviewFrameRate(5); // 一秒5帧
param.setPictureFormat(PixelFormat.JPEG); // 图片形式
param.set("jpen-quality", 80);
cam.setParameters(param);
cam.setDisplayOrientation(90); // 纠正摄像头自动旋转,纠正角度,如果引用,则摄像角度偏差90度
try {
cam.setPreviewDisplay(holder);
} catch (IOException e) {
}
cam.startPreview(); // 进行预览
previewRunning = true; // 已经开始预览
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (cam != null) {
if (previewRunning) {
cam.stopPreview(); // 停止预览
previewRunning = false;
}
cam.release();
}
}
}
}
/*只不过一个是继承的view一个是surfaceview,将AttributeSetattrs加上。只要处理好谁是顶层的view谁设成透明,预览视频的surfaceview设成底层,在且要在xml属性文件里设成visible就可以了*/
public class SVDraw extends SurfaceView implements SurfaceHolder.Callback{
protected SurfaceHolder sh;
private int mWidth;
private int mHeight;
private MyThread thread;
public SVDraw(Context context, AttributeSet attrs) {
super(context, attrs);
sh = this.getHolder();
sh.addCallback(this);
sh.setFormat(PixelFormat.TRANSPARENT);
setZOrderOnTop(true);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int w, int h) {
mWidth = w;
mHeight = h;
}
public void surfaceCreated(SurfaceHolder arg0) {
}
public void surfaceDestroyed(SurfaceHolder arg0) {
}
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);*/
thread = new MyThread(sh);
thread.setRun(true);
thread.start();
}
}
// 绘制线程
public class MyThread extends Thread {
private SurfaceHolder holder;
private boolean run;
public MyThread(SurfaceHolder holder) {
this.holder = holder;
run = true;
}
@Override
public void run() {
int counter = 0;
Canvas canvas = null;
while (run) {
// 具体绘制工作
try {
// 获取Canvas对象,并锁定之
canvas = holder.lockCanvas();
// 设定Canvas对象的背景颜色
canvas.drawColor(Color.TRANSPARENT);
// 创建画笔
Paint p = new Paint();
// 设置画笔颜色
p.setColor(Color.RED);
// 设置文字大小
p.setTextSize(30);
// 创建一个Rect对象rect
Rect rect = new Rect(100, 50, 380, 330);
// 在canvas上绘制rect
canvas.drawRect(rect, p);
// 在canvas上显示时间
canvas.drawText("Interval = " + (counter++) + " seconds.", 100, 410, p);
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
// 解除锁定,并提交修改内容
holder.unlockCanvasAndPost(canvas);
}
}
}
}
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test02"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.test02.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!--z>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
android 使用两个surfaceview 在摄像机画面上绘图的更多相关文章
- android 加载自定义图片并在图片上绘图
来源:毕设 关键词:Bitmap Canvas //毕设中需要自定义室内地图,并且在地图上绘制轨迹 //此处是一个测试Demo,实现图片的加载和记录手指在屏幕上的运动轨迹 图片的载入 使用系统提供的内 ...
- Android之View和SurfaceView
Android之View和SurfaceView Android游戏当中主要的除了控制类外就是显示类View.SurfaceView是从View基类中派生出来的显示类.android游戏开发中常用的三 ...
- Android 学习笔记之SurfaceView的使用+如何实现视频播放...
学习内容: 1.掌握Surface的使用... 2.Android中如何实现视频播放... 1.SurfaceView类的使用 在Android中,一般播放音频时我们可以去使用Android提供的 ...
- Unity调用Android的两个方式:其一、调用jar包
unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...
- Android 实现两屏幕互相滑动
Android 实现两屏幕互相滑动 下文来自: http://blog.csdn.net/song_shi_chao/article/details/7081664 ----------------- ...
- 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法
重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...
- unity调用Android的两种方式:其二,调用aar包
上一篇我们讲了unity如何调用jar包 http://www.cnblogs.com/Jason-c/p/6743224.html, 现在我们介绍一下怎么生成aar包和unity怎么调用aar 一. ...
- Unity调用Android的两种方式:其一、调用jar包
unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...
- android多线程-AsyncTask之工作原理深入解析(上)
关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...
随机推荐
- js面形对象(2)
1.原型与in操作符 有两种方式使用in操作符:单独使用和在for-in循环中使用.在单独使用时,in操作符会在通过对象能够访问给定属性时,返回true,无论该属性是存在实例或者是存在于原型 ...
- CodeForces 732D Exams (二分)
题意:某人要考试,有n天考m个科目,然后有m个科目要考试的时间和要复习多少天才能做,问你他最早考完所有科目是什么时间. 析:二分答案,然后在判断时,直接就是倒着判,很明显后出来的优先,也就是一个栈. ...
- Objc基础学习记录1
1.'-'系在实例方法前头 2.'+'类方法class method 相反; 3.void表示没有返回值; 4.&x 和c语言一样,代表的是x的在内存上的地址; 5.*y指向内存存储空间内的数 ...
- 【JDBC】事务的使用
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5868750.html 关于事务的理论知识.ACID特性等等,网上太多了,在此不一一重复.本文主要着重 事务 ...
- iOS 中的UIWindow
使用Xcode新建一个工程后,Xcode会自动新建一些文件,其中有AppDelegate.h,AppDelegate.m,ViewController.h,ViewController.m,Main. ...
- AngularJS~大话开篇
AngularJS是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入.等等. 前端 ...
- js字符串常用判断方法
转自:http://blog.sina.com.cn/s/blog_6819fa800100j5t6.html 一.方法介绍 function obj$(id) ...
- DuiLib(二)——控件创建
上一篇讲了窗口及消息,了解了大体的程序框架.这一篇说的是控件的创建. duilib支持XML配置文件,即根据XML创建窗口及控件,将界面与逻辑分开,便于修改及维护.上一篇的示例中可以看到在消息WM_C ...
- [AngularJS] ngAnimate angular way !!
Idea is set up javascript as an api, then just change html to control the behavor. var app = angula ...
- MySQL_update同一张表
update tb1 inner join(select type, count(*) as cntfrom tb1 group by type)as der using(type)set tb1.c ...