Qualcomm DragonBoard 下位机
一.背景
这个系列博客,博主详细地描述了一个远程监控系统的下位机系统与上位机控制界面的程序设计。
图1 客户端界面
我们看到基础的视频显示界面与控制界面已经基本呈现,当然,实际应用中我们不会仅仅满足于此。
二.思路
1.客户端缺点:
(1).整体布局过于紧凑,不够美观
(2).视频可视页面太小,无法体现高清摄像头的性能
(3).虚拟按键功能显示不够清晰
2.优化思路:
(1).虚拟按键重新编辑布局与图形效果
(2).整体UI重新布局,将视频页面设为背景,再将功能页面覆盖其上,能形成更形象的可视操作页面。
那么问题来了,在android系统里,视频页面要怎么制作成背景?
三.SurfaceView
学过android应用的童鞋,应该都会知道这个控件----SurfaceView。
1.SurfaceView
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。
surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。
注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。你可以通过SurfaceHolder接口访问这个Surface.用getHolder()方法可以得到这个接口。
surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。
surfaceview的核心在于提供了两个线程:UI线程和渲染线程。
这里应注意:
1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
2> 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效surface
2.SurfaceHolder
显示一个surface的抽象接口,使你可以控制surface的大小和格式, 以及在surface上编辑像素,和监视surace的改变。这个接口通常通过SurfaceView类实现。
3. SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时,它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。
设置Callback的方法是SurfaceHolder.addCallback.
四.核心代码分享:
package com.boss.xiao.Ideas;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView
implements Callback, Runnable
{
private SurfaceHolder sfh;
private Canvas canvas;
URL videoUrl;
private String url;
HttpURLConnection conn;
Bitmap bmp;
private Paint p;
InputStream inputstream=null;
private Bitmap mBitmap;
private static int mScreenWidth;
private static int mScreenHeight;
float myEyesDistance;
int numberOfFaceDetected;
Paint myPaint = new Paint();
public MySurfaceView(Context context, AttributeSet attrs)
{
super(context, attrs);
initialize();
p = new Paint();
p.setAntiAlias(true);
myPaint.setColor(Color.GREEN);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(3);
sfh = this.getHolder();
sfh.addCallback(this);
this.setKeepScreenOn(true);
setFocusable(true);
this.getWidth();
this.getHeight();
}
private void initialize()
{
DisplayMetrics dm = new DisplayMetrics();
dm = getResources().getDisplayMetrics();
mScreenWidth = dm.widthPixels;
mScreenHeight = dm.heightPixels;
}
class DrawVideo extends Thread
{
public DrawVideo() {}
public void run()
{
while (true)
{
try {
videoUrl=new URL(url);
conn = (HttpURLConnection)videoUrl.openConnection();
conn.connect();
inputstream = conn.getInputStream(); //获取流
BitmapFactory.Options BitmapFactoryOption***fo = new BitmapFactory.Options();
BitmapFactoryOption***fo.inPreferredConfig = Bitmap.Config.RGB_565;
bmp = BitmapFactory.decodeStream(inputstream,null,BitmapFactoryOption***fo);//从获取的流中构建出BMP图像
mBitmap = Bitmap.createScaledBitmap(bmp, mScreenWidth, mScreenHeight, true);
canvas = sfh.lockCanvas();
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(mBitmap, 0,0, null);//把BMP图像画在画布上
sfh.unlockCanvasAndPost(canvas);//画完一副图像,解锁画布
} catch (Exception ex) {
ex.printStackTrace();
} finally {}
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height){}
public void surfaceDestroyed(SurfaceHolder holder){}
public void GetCameraIP(String p){url=p; Log.e("GetCameraIP ="+p,"xiao");}
public void run() {
while (true)
{
try {
Log.e("DrawVideo ============","xiao");
videoUrl=new URL(url);
conn = (HttpURLConnection)videoUrl.openConnection();
conn.connect();
inputstream = conn.getInputStream(); //获取流
bmp = BitmapFactory.decodeStream(inputstream);//从获取的流中构建出BMP图像
mBitmap = Bitmap.createScaledBitmap(bmp, mScreenWidth, mScreenHeight, true);
canvas = sfh.lockCanvas();
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(mBitmap, 0,0, null);//把BMP图像画在画布上
sfh.unlockCanvasAndPost(canvas);//画完一副图像,解锁画布
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
}
}
}
public void surfaceCreated(SurfaceHolder holder)
{
new DrawVideo().start();
}
public void drowblack(){}
}
五.实测效果:
图2 新客户端
更多回帖