Camera trong Android



Có hai cách bạn có thể sử dụng Camera trong ứng dụng:

  • Sử dụng ứng dụng Android Camera đang tồn tại trong ứng dụng của chúng ta.

  • Trực tiếp sử dụng Camera API được cung cấp bởi Android.

Sử dụng ứng dụng Android Camera đang tồn tại

Quảng cáo

Bạn sẽ sử dụng MediaStore.ACTIOn_IMAGE_CAPTURE để chạy một ứng dụng camera đang tồn tại đã được cài đặt trên điện thoại của bạn. Cú pháp là:

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

Ngoài ta, MediaStore còn cung cấp một số Intent khác, được liệt kê dưới đây.

Stt Intent type and Miêu tả
1 ACTION_IMAGE_CAPTURE_SECURE

Trả về hình ảnh được chụp từ camera

2 ACTION_VIDEO_CAPTURE

Nó gọi ứng dụng video đang tồn tại trong Android để quay video

3 EXTRA_SCREEN_ORIENTATION

Nó được sử dụng để thiết lập hướng của màn hình là vertical hay landscape

4 EXTRA_FULL_SCREEN

Nó được sử dụng để điều khiển giao diện UI của ViewImage

5 INTENT_ACTION_VIDEO_CAMERA

Intent này được sử dụng để chạy camera trong chế độ video

6 EXTRA_SIZE_LIMIT

Nó được sử dụng để xác định giới hạn kích cỡ của video hoặc hình ảnh được quay/chụp

Bây giờ bạn sẽ sử dụng hàm startActivityForResult() để chạy Activity này và đợi kết quả. Cú pháp là:

startActivityForResult(intent,0)

Phương thức này đã được định nghĩa trong lớp Activity. Chúng ta đang gọi nó từ Main Activity. Lớp Activity này cũng định nghĩa một số phương thức khác mà thực hiện công việc tương tự, nhưng được sử dụng khi bạn không gọi từ Activity đó mà gọi từ nơi khác. Chúng được liệt kê trong bảng dưới:

Stt Miêu tả
1 startActivityForResult(Intent intent, int requestCode, Bundle options)

Bắt đầu một Activity, nhưng có thể nhận các tùy chọn extra với nó

2 startActivityFromChild(Activity child, Intent intent, int requestCode)

Chạy Activity khi activity của bạn là con của bất cứ Activity nào khác

3 startActivityFromChild(Activity child, Intent intent, int requestCode, Bundle options)

Nó làm việc như trên, nhưng nó có thể nhận các giá trị extra

4 startActivityFromFragment(Fragment fragment, Intent intent, int requestCode)

Chạy Activity từ Fragment mà hiện tại bạn đang ở bên trong

5 startActivityFromFragment(Fragment fragment, Intent intent, int requestCode, Bundle options)

Nó không chỉ chạy Activity từ Fragment mà còn có thể nhận các giá trị exra

Sẽ không có vấn đề gì với hàm nào bạn lựa chọn để sử dụng để chạy Activity, tất cả chúng trả về kết quả. Kết quả có thể được thu nhận bởi ghi đè hàm onActivityResult..

Ví dụ

Quảng cáo

Dưới đây là một ví dụ minh họa cách chạy ứng dụng camera đang tồn tại để chụp một hình ảnh và hiển thị kết quả trong dạng Bitmap.

Để thử nghiệm ví dụ, bạn cần chạy trên thiết bị thực sự mà hỗ trợ camera.

Sau đây là nội dung của Main Activity file đã được sửa đổi: src/MainActivity.java.

package com.example.sairamkrishna.myapplication;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;

import android.graphics.Bitmap;
import android.os.BatteryManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;

import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Set;

public class MainActivity extends ActionBarActivity {
   Button b1,b2;
   ImageView iv;
   
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      
      b1=(Button)findViewById(R.id.button);
      iv=(ImageView)findViewById(R.id.imageView);
      
      b1.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent, 0);
         }
      });
   }
   
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      // TODO Auto-generated method stub
      super.onActivityResult(requestCode, resultCode, data);
      
      Bitmap bp = (Bitmap) data.getExtras().get("data");
      iv.setImageBitmap(bp);
   }
   
   @Override
   protected void onDestroy() {
      super.onDestroy();
   }
   
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return true;
   }
   
   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar will
      // automatically handle clicks on the Home/Up button, so long
      // as you specify a parent activity in AndroidManifest.xml.
      
      int id = item.getItemId();
      
      //noinspection SimplifiableIfStatement
      if (id == R.id.action_settings) {
         return true;
      }
      return super.onOptionsItemSelected(item);
   }
}

Sau đây là nội dung của res/layout/activity_main.xml file

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
   android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
   
   <TextView android:text="Camera Example" android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/textview"
      android:textSize="35dp"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true" />
      
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point"
      android:id="@+id/textView"
      android:layout_below="@+id/textview"
      android:layout_centerHorizontal="true"
      android:textColor="#ff7aff24"
      android:textSize="35dp" />
      
   <ImageView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageView"
      android:src="@drawable/abc"
      android:layout_below="@+id/textView"
      android:layout_centerHorizontal="true" />
      
   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="camera"
      android:id="@+id/button"
      android:layout_below="@+id/imageView"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="86dp" />
      
</RelativeLayout>

Sau đây là nội dung của res/values/strings.xml to define one new constants

<resources>
   <string name="app_name">My Application</string>
   <string name="hello_world">Hello world!</string>
   <string name="action_settings">Settings</string>
</resources>

Sau đây là nội dung mặc định của AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.camera"
   android:versionCode="1"
   android:versionName="1.0" >

   <application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      
      <activity
         android:name="com.example.sairamkrishna.myapplication.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>
</manifest>

Cuối cùng, bạn chạy ứng dụng Android vừa tạo ở trên.

Camera trong Android

Chọn thiết bị mobile và sau đó kiểm tra thiết bị sẽ hiển thị màn hình sau: −

Camera trong Android

Bây giờ bật camera và chụp một hình. Sau khi chụp, hai nút sẽ hiển thị hỏi bạn xem nên loại bỏ hay giữ nó.

Camera trong Android

Nhấn nút giữ và đặt hình đã chụp thay cho Android icon.

Camera trong Android

Trực tiếp sử dụng Camera API được cung cấp bởi Android

Chúng ta sẽ sử dụng Camera API để tích hợp Camera trong ứng dụng.

Đầu tiên bạn cần khởi tạo đối tượng Camera bởi sử dụng phương thức static được cung cấp bởi API gọi là Camera.open. Cú pháp như sau:

Camera object = null;
object = Camera.open(); 

Ngoài hàm trên, lớp Camera còn cung cấp một số hàm khác, như sau:

Stt Phương thức & Miêu tả
1 getCameraInfo(int cameraId, Camera.CameraInfo cameraInfo)

Nó trả về thông tin về một camera cụ thể

2 getNumberOfCameras()

Nó trả về một số nguyên xác định các camera có sẵn trên thiết bị

3 lock()

Được sử dụng để khóa camera, vì thế các ứng dụng khác không thể truy cập nó

4 release()

Được sử dụng để mở khóa hay giải phóng camera đã khóa, và các ứng dụng khác có thể truy cập nó

5 open(int cameraId)

Được sử dụng để mở một camera cụ thể khi hỗ trợ nhiều camera

6 enableShutterSound(boolean enabled)

Được sử dụng để enable/disable cửa chớp (shutter) của khung chụp hình

Bây giờ bạn cần tạo một lớp riêng và kế thừa nó từ SurfaceView và triển khai SurfaceHolder Interface.

Hai lớp đã được sử dụng cho mục đích sau:

Class Miêu tả
Camera Được sử dụng để điều khiển Camera và chụp các hình hoặc ghi video từ camera
SurfaceView Được sử dụng để biểu diễn một live camera tới người dùng

Bạn phải gọi phương thức Preview của lớp Camera để bắt đầu preview tới người dùng.

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {
   private Camera theCamera;
   
   public void surfaceCreated(SurfaceHolder holder) {
      theCamera.setPreviewDisplay(holder);
      theCamera.startPreview();
   }
   
   public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3){
   }
   
   public void surfaceDestroyed(SurfaceHolder arg0) {
   }
}	

Ngoài preview, ngoài ra còn có một số tùy chọn khác của camera có thể được thiết lập bởi sử dụng các hàm được cung cấp bởi Camera API.

Stt Phương thức & Miêu tả
1 startFaceDetection()

Hàm này bắt đầu dò tìm bề mặt của Camera

2 stopFaceDetection()

Được sử dụng để dừng sự dò tìm bề mặt mà đã được kích hoạt bởi phương thức trên

3 startSmoothZoom(int value)

Nó nhận một giá trị nguyên và zoom màn hình camera về giá trị đó

4 stopSmoothZoom()

Nó được sử dụng để dừng việc zoom

5 stopPreview()

Nó được sử dụng để dừng preview

6 takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg)

Nó được sử dụng để kích hoạt/vô hiệu hóa shutter sound của việc ghi hình

Ví dụ

Ví dụ sau minh họa sự sử dụng của Camera API trong ứng dụng.

Để thực nghiệm ví dụ này, bạn cần thiết bị Mobile thực sự được trang bị phiên bản Android OS mới nhất, bởi vì có thể Camera không được hỗ trợ bởi Emulator.

Sau đây là nội dung của Main Activity file đã được sửa đổi: src/MainActivity.java.

package com.example.sairamkrishna.myapplication;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;

import android.graphics.Bitmap;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;

import android.os.BatteryManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;

import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Set;

public class MainActivity extends Activity implements SurfaceHolder.Callback {
   Camera camera;
   SurfaceView surfaceView;
   SurfaceHolder surfaceHolder;
   
   Camera.PictureCallback rawCallback;
   Camera.ShutterCallback shutterCallback;
   Camera.PictureCallback jpegCallback;
   
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      
      surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
      surfaceHolder = surfaceView.getHolder();
      
      surfaceHolder.addCallback(this);
      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      
      jpegCallback = new PictureCallback() {
         
         @Override
         public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;
               try {
                  outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                  
                  outStream.write(data);
                  outStream.close();
               }
               
               catch (FileNotFoundException e) {
                  e.printStackTrace();
               }
               
               catch (IOException e) {
                  e.printStackTrace();
               }
               
               finally {
               }
               
               Toast.makeText(getApplicationContext(), "Picture Saved", Toast.LENGTH_LONG).show();
               refreshCamera();
            }
         };
      }
      
      public void captureImage(View v) throws IOException {
         camera.takePicture(null, null, jpegCallback);
      }
      
      public void refreshCamera() {
         if (surfaceHolder.getSurface() == null) {
            return;
         }
         
         try {
            camera.stopPreview();
         }
         
         catch (Exception e) {
         }
         
         try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
         }
         catch (Exception e) {
      }
   }
   
   @Override
   protected void onDestroy() {
      super.onDestroy();
   }
   
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return true;
   }
   
   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar 
      // automatically handle clicks on the Home/Up button, so long
      // as you specify a parent activity in AndroidManifest.xml.
      
      int id = item.getItemId();
      
      //noinspection SimplifiableIfStatement
      if (id == R.id.action_settings) {
         return true;
      }
      return super.onOptionsItemSelected(item);
   }
   
   @Override
   public void surfaceCreated(SurfaceHolder holder) {
      try {
         camera = Camera.open();
      }
      
      catch (RuntimeException e) {
         System.err.println(e);
         return;
      }
      
      Camera.Parameters param;
      param = camera.getParameters();
      param.setPreviewSize(352, 288);
      camera.setParameters(param);
      
      try {
         camera.setPreviewDisplay(surfaceHolder);
         camera.startPreview();
      }
      
      catch (Exception e) {
         System.err.println(e);
         return;
      }
   }
   
   @Override
   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
      refreshCamera();
   }
   
   @Override
   public void surfaceDestroyed(SurfaceHolder holder) {
      camera.stopPreview();
      camera.release();
      camera = null;
   }
}

Sửa đổi nội dung của the res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
   android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
   
   <TextView android:text="Camera Example" android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/textview"
      android:textSize="35dp"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true" />
      
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point"
      android:id="@+id/textView"
      android:layout_below="@+id/textview"
      android:layout_centerHorizontal="true"
      android:textColor="#ff7aff24"
      android:textSize="35dp" />
      
   <SurfaceView
      android:id="@+id/surfaceView"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"/>
      
</RelativeLayout>

Sửa đổi nội dung của the res/values/string.xml

<resources>
   <string name="app_name">My Application</string>
   <string name="hello_world">Hello world!</string>
   <string name="action_settings">Settings</string>
</resources>

Sửa đổi nội dung của the AndroidManifest.xml và thêm permission như sau.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.camera1"
   android:versionCode="1"
   android:versionName="1.0" >
   
   <uses-permission android:name="android.permission.CAMERA" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-feature android:name="android.hardware.camera" />
   <uses-feature android:name="android.hardware.camera.autofocus" />

   <application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      
      <activity
         android:name="com.example.sairamkrishna.myapplication.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>
</manifest>

Cuối cùng, bạn chạy ứng dụng Android vừa tạo ở trên.

Đã có app VietJack trên điện thoại, giải bài tập SGK, SBT Soạn văn, Văn mẫu, Thi online, Bài giảng....miễn phí. Tải ngay ứng dụng trên Android và iOS.

Theo dõi chúng tôi miễn phí trên mạng xã hội facebook và youtube:

Các bạn có thể mua thêm khóa học JAVA CORE ONLINE VÀ ỨNG DỤNG cực hay, giúp các bạn vượt qua các dự án trên trường và đi thực tập Java. Khóa học có giá chỉ 300K, nhằm ưu đãi, tạo điều kiện cho sinh viên cho thể mua khóa học.

Nội dung khóa học gồm 16 chuơng và 100 video cực hay, học trực tiếp tại https://www.udemy.com/tu-tin-di-lam-voi-kien-thuc-ve-java-core-toan-tap/ Bạn nào có nhu cầu mua, inbox trực tiếp a Tuyền, cựu sinh viên Bách Khoa K53, fb: https://www.facebook.com/tuyen.vietjack

Follow facebook cá nhân Nguyễn Thanh Tuyền https://www.facebook.com/tuyen.vietjack để tiếp tục theo dõi các loạt bài mới nhất về Java,C,C++,Javascript,HTML,Python,Database,Mobile.... mới nhất của chúng tôi.




Tài liệu giáo viên