Google Code Prettify

2016年11月1日 星期二

[Android] Snapshot 擷取IP Cam 影像

大家好~~

在上篇  [Android] ImageView顯示網路圖片 有說到使用擷取照片的方式取得IP CAM 的影像

基本上 如果你的 Web Cam / IP Cam 如果有支援

  • RTSP stream
  • MJPEG stream
  • asf stream
  • snapshot


其實使用 RTSP  /  MJPEG  ,在影像流暢度會好上許多,

但為何Farmer卻使用 snapshot (快照) 呢??


目前Farmer 因為專案有限時間,所以看到 MJPEG 有些複雜度,
沒辦法直接理解應用,需要花更長的時間去撰寫並了解 ,

而 RTSP 發現,我連網路上的APP抓取後,都沒有辦法連結到IPCam,
不知道是不是設定錯誤,還是有其他問題,所以我直接取消念頭,
況且 MJPEG 我發現我比較喜歡這種串流方式~~~ (個人偏好?

Farmer發現  snapshot 就直接套用上一篇做法就可以了,簡單應用~ 懶人必備 

但有很大的缺點就是沒有辦法很快的處理,所以影像會有延遲的狀況。

等有時間 Farmer 一定會去研究 MJPEG ,網路上也有很多文章,大家可以去找Google大神

這次會比較複雜些,因為Farmer把class分為兩種

1. Main 
2. IPCam SurfaceView 

這樣大家就可以直接把  IPCam SurfaceView .class 複製到您的 Main.Class 同個資料夾使用

Manifest File

    <!-- 網路權限 -->
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <!-- 允許應用訪問網路上訊息 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

    <!-- 允許改變網路連接狀態 -->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>

Layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"



        android:orientation="vertical"


        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <TextView android:text="IP"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </TextView>

        <EditText android:layout_width="match_parent"
            android:id="@+id/editIP"
            android:layout_height="wrap_content"
            android:text=">">
        </EditText>

        <TextView
            android:text="Port"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </TextView>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/editPort"
            android:layout_height="wrap_content"
            android:text="80"
            ></EditText>

        <Button android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="go">
        </Button>

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/drawLayout">

        </LinearLayout>

    </LinearLayout>


Main

  • MainActivity
import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;


import android.view.View;

import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    EditText edIP,edPort;
    Button button1;
    public static String CameraIp;
    IPCamSurfaceView r;
    public static LinearLayout DrawLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        edIP=(EditText)findViewById(R.id.editIP);
        edPort=(EditText)findViewById(R.id.editPort);
        button1=(Button)findViewById(R.id.button1);
        DrawLayout = (LinearLayout)findViewById(R.id.drawLayout);

        
        edIP.setText("//snapshot 網址");

        CameraIp =edIP.getText().toString();

        button1.setOnClickListener(new  Button.OnClickListener()
        {
            public void onClick(View v) {
                // TODO Auto-generated method stub

                r=new IPCamSurfaceView(MainActivity.this);
                r.GetCameraIP(CameraIp);
                DrawLayout.addView(r);
            }

        });
    }
}

  • IPCamSurfaceView

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.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.animation.Animation;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class IPCamSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{

    SurfaceHolder SFH;
    Thread THread;
    Canvas canvas;
    Paint paint;
    int ScreenW, ScreenH;
    URL VideoUrl;
    String Url;
    HttpURLConnection Connection;
    Bitmap bmp;

    public IPCamSurfaceView(Context context) {
        super(context);
        THread = new Thread(this);
        SFH = this.getHolder();
        SFH.addCallback(this);

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        // 螢幕恆亮
        this.setKeepScreenOn(true);

    }

    // 動畫 -> 單張照片快速更換
    @Override
    public void startAnimation(Animation animation) {
        super.startAnimation(animation);
    }

    public void surfaceCreated(SurfaceHolder holder) {

        // 擷取DrawLayout宽度
        ScreenH = MainActivity.DrawLayout.getHeight();
        ScreenW = MainActivity.DrawLayout.getWidth();

        THread.start();
    }

    public void run() {
        while (true) {
            DrawPic();
        }
    }

    private void DrawPic() {
        try {
            InputStream inputstream  = null;;

            VideoUrl = new URL(Url);
            Connection = (HttpURLConnection)VideoUrl.openConnection();
            Connection.setDoInput(true);
            Connection.connect();
            inputstream = Connection.getInputStream();
            bmp = BitmapFactory.decodeStream(inputstream);

            //通過 canvas 繪製修改 SurfaceHolder
            canvas = SFH.lockCanvas();
            //背景顏色
            canvas.drawColor(Color.WHITE);
            canvas.drawBitmap(bmp, 0, 0, paint);

            //釋放同步canvas
            SFH.unlockCanvasAndPost(canvas);
            Connection.disconnect();


        } catch (Exception ex) {

        }
    }

    public void GetCameraIP(String ip){
        Url = ip ;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

}


程式下載區 點我~點我~~

沒有留言:

張貼留言