转载自http://blog.csdn.net/jesse__zhong/article/details/24934083

使用双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>
&nbsp;<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 在摄像机画面上绘图的更多相关文章

  1. android 加载自定义图片并在图片上绘图

    来源:毕设 关键词:Bitmap Canvas //毕设中需要自定义室内地图,并且在地图上绘制轨迹 //此处是一个测试Demo,实现图片的加载和记录手指在屏幕上的运动轨迹 图片的载入 使用系统提供的内 ...

  2. Android之View和SurfaceView

    Android之View和SurfaceView Android游戏当中主要的除了控制类外就是显示类View.SurfaceView是从View基类中派生出来的显示类.android游戏开发中常用的三 ...

  3. Android 学习笔记之SurfaceView的使用+如何实现视频播放...

    学习内容: 1.掌握Surface的使用... 2.Android中如何实现视频播放... 1.SurfaceView类的使用   在Android中,一般播放音频时我们可以去使用Android提供的 ...

  4. Unity调用Android的两个方式:其一、调用jar包

    unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...

  5. Android 实现两屏幕互相滑动

    Android 实现两屏幕互相滑动 下文来自: http://blog.csdn.net/song_shi_chao/article/details/7081664 ----------------- ...

  6. 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法

    重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...

  7. unity调用Android的两种方式:其二,调用aar包

    上一篇我们讲了unity如何调用jar包 http://www.cnblogs.com/Jason-c/p/6743224.html, 现在我们介绍一下怎么生成aar包和unity怎么调用aar 一. ...

  8. Unity调用Android的两种方式:其一、调用jar包

    unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...

  9. android多线程-AsyncTask之工作原理深入解析(上)

    关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...

随机推荐

  1. spring对数据库特殊字段的支持

    1.CLOB <property name="tomdTemplateContent" type="org.springframework.orm.hibernat ...

  2. 关于ssh和ajax小小总结

    我是相当的不专业,写给自己看.有什么错误的话,说出来将感激不尽. 有两种方法异步传输 1.通过json字符串:  jsp中这么写: $.getJSON( "details_ajaxActio ...

  3. SQL Server中如何获取当前年,月,日,时,分,秒

    分类: SQL Server  select GETDATE() as '当前日期',DateName(year,GetDate()) as '年',DateName(month,GetDate()) ...

  4. ubuntu为IDE(Eclipse WebStorm)添加桌面快捷方式

    在ubuntu15.10环境配置webstorm和eclipse的时候会下载官网上编译好的包, bin目录下面会有一个.sh文件(linux版本), 那么一般情况下,执行 ./sh就会启动IDE, 但 ...

  5. NFA与DFA

    正则表达式匹配,包含两个东西,一个是表达式,一个文本. NFA(Nondeterministic Finite Automaton),不确定有穷自动机,表达式主导,NFA去吃文本,贪婪算法吃下去,如果 ...

  6. 从零开始学android开发-布局中 layout_gravity、gravity、orientation、layout_weight

    线性布局中,有 4 个及其重要的参数,直接决定元素的布局和位置,这四个参数是 android:layout_gravity ( 是本元素相对于父元素的重力方向 ) android:gravity (是 ...

  7. BW知识点总结及面试要点

    1.       如何理解数据仓库? 数据仓库 是 一个面向主题的,集成的,相对稳定的,反应历史变化的数据集合,用于支持管理决策. 2.       OLAP 和 OLTP的基本概念 和 区别? Ol ...

  8. Android开发学习之 定制界面风格

    统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...

  9. iOS开发——UI篇&九宫格算法

    九宫格算法 关于iOS开发中九宫格的实现虽然使用不多,而且后面会有更好的方实现,但是作为一个程序员必需要知道的就是九宫格算法的实现. 一:实现思路: (1)明确每一块用得是什么view (2)明确每个 ...

  10. perl详解

    http://www.blogjava.net/qileilove/archive/2013/09/04/403646.html