借助JavaCV实现android手机查看PC摄像头实时视频

来源:互联网 发布:sql数据库获取当前时间 编辑:程序博客网 时间:2024/05/16 05:27

查看PC实时摄像头视频,其实就是以大于24次/秒的速度,控制PC摄像头进行拍照,并把每一张拍得的图片发送到android手机端,在手机上展示这些图片,得到实时的视频。

主要解决两个问题一时调用PC摄像头拍摄图片,二是在PC和android之间传输图片。

利用JavaCV(简介见本文末尾)调用PC摄像头很简单

OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);grabber.start();//调用grab()方法就能得到IplImage类的一个对象,进行进一步处理就能得到图片

传输图片涉及图片数据和字节流之间的转化

PC端将图片转化为字节流

while ((image = grabber.grab()) != null && writeImageSocket.isConnected()) {ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(image.getBufferedImage(), "jpg", baos );baos.flush();byte[] imageInByte = baos.toByteArray(); baos.close();dos.writeInt(imageInByte.length);dos.write(imageInByte,0,imageInByte.length);dos.flush();}
Android读取字节流转化为图片
while (true) {int size = dataInput.readInt();Log.e("size in client", Integer.toString(size));byte[] data = new byte[size];int len = 0;while (len < size) {len += dataInput.read(data, len, size - len);}ByteArrayOutputStream outPut = new ByteArrayOutputStream();bitmap = BitmapFactory.decodeByteArray(data, 0,data.length);bitmap.compress(CompressFormat.PNG, 100, outPut);Message message = new Message();message.what = 1;mHandler.sendMessage(message);}
具体代码

PC端服务程序的实现CameraSever.java

package com.giantpoplar.cameraserver;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.Executor;import java.util.concurrent.Executors;import javax.imageio.ImageIO;import com.googlecode.javacv.FrameGrabber.Exception;import com.googlecode.javacv.cpp.opencv_core.IplImage;import com.googlecode.javacv.OpenCVFrameGrabber;public class CameraSever {public  CameraSever() {ServerSocket serversocket = null;Executor executor = null;OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);try {serversocket = new ServerSocket(8888);executor = Executors.newCachedThreadPool();grabber.start();while (!serversocket.isClosed()) {Socket acceptedSocket = serversocket.accept();executor.execute(new SendImageThread(acceptedSocket, grabber));}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {if (serversocket != null) {try {serversocket.close();grabber.stop();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}}}private class SendImageThread implements Runnable {Socket writeImageSocket;OpenCVFrameGrabber grabber;public SendImageThread(Socket socket, OpenCVFrameGrabber grabber) {this.writeImageSocket = socket;this.grabber = grabber;}public void run() {IplImage image=null;DataOutputStream dos=null;try {dos = new DataOutputStream(writeImageSocket.getOutputStream());while ((image = grabber.grab()) != null && writeImageSocket.isConnected()) {ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(image.getBufferedImage(), "jpg", baos );baos.flush();byte[] imageInByte = baos.toByteArray(); baos.close();dos.writeInt(imageInByte.length);dos.write(imageInByte,0,imageInByte.length);dos.flush();}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {if(dos!=null)dos.close();writeImageSocket.close();} catch (IOException e) {e.printStackTrace();}}}}public static void main(String[] args) {new CameraSever();}}

android客户端代码

package com.example.imagetest;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.OutputStream;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.net.Socket;import java.net.UnknownHostException;import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.media.Image;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.os.StrictMode;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {private Button connectButton = null;private Socket clientSocket = null;private Handler mHandler = null;private ReceiveThread mReceiveThread = null;private ImageView iv;private Bitmap bitmap;/** Called when the activity is first created. */@SuppressLint("NewApi")@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);connectButton = (Button) this.findViewById(R.id.connectbutton);iv = (ImageView) findViewById(R.id.iv);if (android.os.Build.VERSION.SDK_INT > 9) {StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();StrictMode.setThreadPolicy(policy);}connectButton.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {try {clientSocket = new Socket("127.0.0.1", 8888);//ip地址换成运行Camerasever.java程序的电脑的ip} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}displayToast("连接成功!");try {mReceiveThread = new ReceiveThread(clientSocket);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}mReceiveThread.start();}});// 消息处理mHandler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 1:iv.setImageBitmap(bitmap); // 在ImageView中显示Bitmapbreak;default:break;}super.handleMessage(msg);}};}// 显示Toast函数private void displayToast(String s) {Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}private class ReceiveThread extends Thread implements OnClickListener {private Socket s;private Button button;private PrintWriter writer;private Boolean flag = false;DataInputStream dataInput;public ReceiveThread(Socket s) throws IOException {this.s=s;dataInput = new DataInputStream(s.getInputStream());}public void run() {try {while (true) {Log.e("5555555555555", "11111111111");int size = dataInput.readInt();Log.e("size in client", Integer.toString(size));byte[] data = new byte[size];int len = 0;while (len < size) {len += dataInput.read(data, len, size - len);}ByteArrayOutputStream outPut = new ByteArrayOutputStream();bitmap = BitmapFactory.decodeByteArray(data, 0,data.length);bitmap.compress(CompressFormat.PNG, 100, outPut);Message message = new Message();message.what = 1;mHandler.sendMessage(message);//Thread.sleep(100);}} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubflag = true;}}}

JavaCV的简介

JavaCV是一个开源的java语言实现的视觉计算库,封装了OpenCV,FFmpeg,libdc1394等常用的视觉计算库,使用也比较简单,相关文件可以到

https://code.google.com/p/javacv/downloads/list?can=1&q=&colspec=Filename+Summary+Uploaded+ReleaseDate+Size+DownloadCount下载,下载最新版本即可,其中javacv-examples-0.7-src.zip是该库作者提供的例子,供使用者学习,该库暂时没有文档;javacv-0.7-bin.zip是打包好的jar文件,需要引入javacpp.jar,javacv.jar,以及一个javacv-*.jar取决于系统,我用的是Windows8.1,64位,我用的是javacv-windows-x86_64.jar;javacv-0.7-cppjars.zip,是opencv的各版本的jar包,也是按照系统选择;javacv-0.7-src.zip是javacv的源代码,使用时导入即可。





1 0