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之工作原理深入解析(上) ...
随机推荐
- 【三支火把】---CDS5516舵机调试以及自己的感想!
我依然坚持,任何一次自己的心有感触都要及时的记录下来,这样你的努力才是真正的努力. 这两天一直在用STM32调试CDS5516舵机,其实很简单,但是却花了将近两天的时间,过程之曲折我就不说了,先总结一 ...
- 【Java】Socket+多线程实现控制台聊天室
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827212.html 聊天室程序的结构图: 架构解释: Server服务器相当于一个中转站,Client客户端 ...
- 三、FreeMarker 模版开发指南 第三章 模版
章节内容如下: 总体结构 指令 表达式 插值 一.总体结构 实际上你用程序语言编写的程序就是模板,模板也被称为FTL(代表FreeMarker模板语言).这是为编写模板设计的非常简单的编程语言. ...
- php and web service with wsdl
Following are the links: Developing Web Services Using PHP PHP Web Services with WSDL Creating Web S ...
- Windows 窗体的.Net 框架绘图技术
当编写一个典型的Windows 窗体程序时,窗体和控件的绘制.效果等操作是不需要特别加以考虑的.这是为什么呢?因为通过使用 .Net 框架,开发人员可以拖动一系列的控件到窗体上,并书写一些简单的与事件 ...
- decide your linux OS is GUI or not
Try: ps -ef|grep X The ps command will display information about a selection of the active process ...
- Ubuntu下多服务器 Rsync同步镜像服务配置
主服务器:192.168.5.13_ubuntu 从服务器:192.168.5.11_centos ================== 1> 在两台主机上分别安装rsync========== ...
- 不会内存溢出的Android Handler写法
private static class ThisHandler extends Handler { private final WeakReference<MainActivity&g ...
- C#并行编程 (Barrier,CountdownEvent,ManualResetEventSlim,SemaphoreSlim,SpinLock,SpinWait )
背景 有时候必须访问变量.实例.方法.属性或者结构体,而这些并没有准备好用于并发访问,或者有时候需要执行部分代码,而这些代码必须单独运行,这是不得不通过将任务分解的方式让它们独立运行. 当任务和线程要 ...
- QNetworkAccessManager的异步与线程
Qt版本5.1.1 以HTTP操作为例 Qt中的HTTP操作都是异步的. 内部通过线程实现 创建线程的时机在QNetworkReplyHttpImplPrivate::postRequest() vo ...