Android Camera 相机程序编写

  

  要自己写一个相机应用直接使用相机硬件,首先应用需要一个权限设置,在AndroidManifest.xml中加上使用设备相机的权限

<uses-permission android:name="android.permission.CAMERA" />

  为你的应用创建自定义的相机,一般步骤如下:

  1.检测相机硬件并获取访问

  2.建立一个Preview类:需要一个相机预览的类,继承 SurfaceView 类,并实现SurfaceHolder接口。

  3.建立预览的布局。

  4.为拍照建立监听。

  5.拍照并且存储文件。

  6.释放相机。

  因为相机是一个共享资源,所以应该被谨慎管理,这样应用之间才不会发生冲突。

  所以使用完相机之后应该调用 Camera.release()来释放相机对象。

  如果不释放,后续的使用相机请求(其他应用或本应用)都会失败。

检测相机硬件

  如果你的程序没有在manifest的声明中要求有相机,那么你应该在运行时检查相机的存在与否,主要用了 PackageManager.hasSystemFeature() 方法。比如:

    /** Check if this device has a camera */
private boolean checkCameraHardware(Context context)
{
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA))
{
// this device has a camera
return true;
}
else
{
// no camera on this device
return false;
}
}

  设备上可能有多个相机,Android 2.3以后可以使用 Camera.getNumberOfCameras()来查看相机的数目。

  如下面这段程序用于检测设备中的相机,并得到默认相机的索引号:

    private int getDefaultCameraId()
{
int defaultId = -1; // Find the total number of cameras available
mNumberOfCameras = Camera.getNumberOfCameras(); // Find the ID of the default camera
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < mNumberOfCameras; i++)
{
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
{
defaultId = i;
}
}
if (-1 == defaultId)
{
if (mNumberOfCameras > 0)
{
// 如果没有后向摄像头
defaultId = 0;
}
else
{
// 没有摄像头
Toast.makeText(getApplicationContext(), R.string.no_camera,
Toast.LENGTH_LONG).show();
}
}
return defaultId;
}

  看了Camera类的代码实现后,其中不带参数的open()方法:

    public static Camera open()
{
int numberOfCameras = getNumberOfCameras();
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < numberOfCameras; i++)
{
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
{
return new Camera(i);
}
}
return null;
}

  说明open方法默认是打开第一个后向摄像头的。

访问相机

  当检测到设备上有相机之后,必须获取其访问权,获取一个 Camera 类的对象。

  要获取主要的相机,可以使用 Camera.open() 方法,注意异常处理。

  在使用这个方法的时候一定要检查异常,如果相机正在被使用或者不存在,没有处理异常,将会使得应用被系统关闭。

  如:

    /** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance()
{
Camera c = null;
try
{
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e)
{
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}

  Android 2.3之后,可以使用Camera.open(int)来获取特定的相机。

检查相机特性

  可以使用Camera.getParameters()方法来检查相机的特性。

  API Level 9之后,可以使用 Camera.getCameraInfo()来查看相机是在设备前面还是后面,还可以得到图像的方向。

建立Preview类

  为了有效地拍照或录像,用户必须要看到相机能看到的图像。

  相机的preview类是一个 SurfaceView ,展示了相机正在捕捉的图像。

  下面是一个预览类的例子(来自官网):

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera; public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera; // Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
} public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
} public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it. if (mHolder.getSurface() == null){
// preview surface does not exist
return;
} // stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
} // set preview size and make any resize, rotate or
// reformatting changes here // start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview(); } catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}

  注意要设置尺寸的话需要放在surfaceChanged()方法里,调用 setPreviewSize()方法,并且应该使用 getSupportedPreviewSizes()返回的值,而不要使用任意的尺寸。

把Preview放在布局里面

  布局时可以使用FrameLayout,这样其他的按钮或者元素可以叠加在预览图像上。

  对于大多数设备来说,相机预览的默认方向是横放的(landscape)。

  从Android 2.2 (API Level 8)开始,可以使用 setDisplayOrientation()来设置预览图像的方向。

  如果需要在用户改变设备方向的时候改变预览图像的方向,可以在 surfaceChanged()方法中,首先用 Camera.stopPreview() 停止预览,改变方向,然后用Camera.startPreview()开启新的预览。

  当然你也可以直接在manifest中设置好方向,如下:

<activity android:name=".CameraActivity"
android:label="@string/app_name" android:screenOrientation="landscape">
<!-- configure this activity to use landscape orientation --> <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

拍照

  在应用里面,必须为用户控制加上监听,来响应用户拍照的动作。

  为了得到图像,要使用 Camera.takePicture()方法。

  这个方法接收三个参数,用于从相机获取图像。

  为了接收到JPEG格式的数据,需要实现Camera.PictureCallback接口用来接收图像数据并且写入文件。

  下面的代码展示了一个最基本的实现:

private PictureCallback mPicture = new PictureCallback() {

    @Override
public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " +
e.getMessage());
return;
} try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};

  照相动作可以用按钮控制,如下:

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);

释放相机

  相机是设备资源,被所有应用共享,当应用不使用相机时应当及时释放,应当在Activity.onPause()中释放。

  如果不及时释放,后续的相机请求(包括你自己的应用和其他的应用发出的)都将失败并且导致应用退出。

实验程序

  完整的照相程序需要考虑相机切换、预览图像的尺寸设置、焦距变换、缩放、白平衡的相机参数设置。

  请查阅文后的参考资料进行进一步学习。

  附上一个粗糙待完善的自定义相机程序(2013/4/6)

  预览图像类: 

package com.example.hellocustomcamera;

import java.io.IOException;
import java.util.List; import android.R.integer;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView; /**
* 相机图片预览类
*
* @author
*
*/
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback
{ private SurfaceHolder mHolder;
private Camera mCamera;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes; public CameraPreview(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
} public CameraPreview(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
} public CameraPreview(Context context)
{
super(context);
init();
} /**
* 初始化工作
*
*/
private void init()
{
Log.d(AppConstants.LOG_TAG, "CameraPreview initialize"); // Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void setCamera(Camera camera)
{ mCamera = camera;
if (mCamera != null)
{
mSupportedPreviewSizes = mCamera.getParameters()
.getSupportedPreviewSizes();
requestLayout();
}
} @Override
public void surfaceCreated(SurfaceHolder holder)
{
Log.d(AppConstants.LOG_TAG, "surfaceCreated");
// The Surface has been created, now tell the camera where to draw the
// preview.
try
{
if (null != mCamera)
{
mCamera.setPreviewDisplay(holder);
}
}
catch (IOException e1)
{
e1.printStackTrace(); Log.d(AppConstants.LOG_TAG,
"Error setting camera preview display: " + e1.getMessage());
}
try
{
if (null != mCamera)
{
mCamera.startPreview();
} Log.d(AppConstants.LOG_TAG, "surfaceCreated successfully! ");
}
catch (Exception e)
{
Log.d(AppConstants.LOG_TAG,
"Error setting camera preview: " + e.getMessage());
}
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{ Log.d(AppConstants.LOG_TAG, "surface changed");
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it. if (null == mHolder.getSurface())
{
// preview surface does not exist
return;
} // stop preview before making changes
try
{
if (null != mCamera)
{
mCamera.stopPreview();
}
}
catch (Exception e)
{
// ignore: tried to stop a non-existent preview
} // set preview size and make any resize, rotate or
// reformatting changes here if (null != mCamera)
{
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); requestLayout(); mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
Log.d(AppConstants.LOG_TAG, "camera set parameters successfully!: "
+ parameters); }
// 这里可以用来设置尺寸 // start preview with new settings
try
{
if (null != mCamera)
{ mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} }
catch (Exception e)
{
Log.d(AppConstants.LOG_TAG,
"Error starting camera preview: " + e.getMessage());
}
} @Override
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.d(AppConstants.LOG_TAG, "surfaceDestroyed"); if (null != mCamera)
{
mCamera.stopPreview();
} } @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec); // We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(),
widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(),
heightMeasureSpec);
setMeasuredDimension(width, height); if (mSupportedPreviewSizes != null)
{
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,
height);
}
} private Size getOptimalPreviewSize(List<Size> sizes, int w, int h)
{
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null; Size optimalSize = null;
double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size
for (Size size : sizes)
{
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
} // Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null)
{
minDiff = Double.MAX_VALUE;
for (Size size : sizes)
{
if (Math.abs(size.height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
} }

  主要的Activity类:

package com.example.hellocustomcamera;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date; import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast; public class HelloCustomCameraActivity extends Activity
{ private Camera mCamera;
private CameraPreview mPreview; int mNumberOfCameras;
int mCameraCurrentlyLocked; // The first rear facing camera
int mDefaultCameraId; int mScreenWidth, mScreenHeight; @Override
public void onCreate(Bundle savedInstanceState)
{
Log.d(AppConstants.LOG_TAG, "onCreate");
super.onCreate(savedInstanceState); // 无标题栏的窗口
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置布局
setContentView(R.layout.activity_hello_custom_camera); // 得到屏幕的大小
WindowManager wManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wManager.getDefaultDisplay();
mScreenHeight = display.getHeight();
mScreenWidth = display.getWidth(); // Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); // 将相机预览图加入帧布局里面
preview.addView(mPreview, 0); // 使用按钮进行拍摄动作监听
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}); // 得到默认的相机ID
mDefaultCameraId = getDefaultCameraId();
mCameraCurrentlyLocked = mDefaultCameraId; } @Override
protected void onResume()
{
Log.d(AppConstants.LOG_TAG, "onResume");
super.onResume(); // Open the default i.e. the first rear facing camera.
mCamera = getCameraInstance(mCameraCurrentlyLocked); mPreview.setCamera(mCamera);
} @Override
protected void onPause()
{
Log.d(AppConstants.LOG_TAG, "onPause");
super.onPause(); // Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera != null)
{
mPreview.setCamera(null);
Log.d(AppConstants.LOG_TAG, "onPause --> Realease camera");
mCamera.release();
mCamera = null;
} } @Override
protected void onDestroy()
{
Log.d(AppConstants.LOG_TAG, "onDestroy");
super.onDestroy(); } /**
* 得到默认相机的ID
*
* @return
*/
private int getDefaultCameraId()
{
Log.d(AppConstants.LOG_TAG, "getDefaultCameraId");
int defaultId = -1; // Find the total number of cameras available
mNumberOfCameras = Camera.getNumberOfCameras(); // Find the ID of the default camera
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < mNumberOfCameras; i++)
{
Camera.getCameraInfo(i, cameraInfo);
Log.d(AppConstants.LOG_TAG, "camera info: " + cameraInfo.orientation);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
{
defaultId = i;
}
}
if (-1 == defaultId)
{
if (mNumberOfCameras > 0)
{
// 如果没有后向摄像头
defaultId = 0;
}
else
{
// 没有摄像头
Toast.makeText(getApplicationContext(), R.string.no_camera,
Toast.LENGTH_LONG).show();
}
}
return defaultId;
} /** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(int cameraId)
{
Log.d(AppConstants.LOG_TAG, "getCameraInstance");
Camera c = null;
try
{
c = Camera.open(cameraId); // attempt to get a Camera instance
}
catch (Exception e)
{
// Camera is not available (in use or does not exist)
e.printStackTrace();
Log.e(AppConstants.LOG_TAG, "Camera is not available");
}
return c; // returns null if camera is unavailable
} public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2; /** Create a File for saving an image or video */
private static File getOutputMediaFile(int type)
{
Log.d(AppConstants.LOG_TAG, "getOutputMediaFile");
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this. File mediaStorageDir = null;
try
{
// This location works best if you want the created images to be
// shared
// between applications and persist after your app has been
// uninstalled.
mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp"); Log.d(AppConstants.LOG_TAG,
"Successfully created mediaStorageDir: " + mediaStorageDir); }
catch (Exception e)
{
e.printStackTrace();
Log.d(AppConstants.LOG_TAG, "Error in Creating mediaStorageDir: "
+ mediaStorageDir);
} // Create the storage directory if it does not exist
if (!mediaStorageDir.exists())
{
if (!mediaStorageDir.mkdirs())
{
// 在SD卡上创建文件夹需要权限:
// <uses-permission
// android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Log.d(AppConstants.LOG_TAG,
"failed to create directory, check if you have the WRITE_EXTERNAL_STORAGE permission");
return null;
}
} // Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
}
else if (type == MEDIA_TYPE_VIDEO)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
}
else
{
return null;
} return mediaFile;
} private PictureCallback mPicture = new PictureCallback()
{ @Override
public void onPictureTaken(byte[] data, Camera camera)
{
Log.d(AppConstants.LOG_TAG, "onPictureTaken"); File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null)
{
Log.d(AppConstants.LOG_TAG,
"Error creating media file, check storage permissions: ");
return;
} try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
}
catch (FileNotFoundException e)
{
Log.d(AppConstants.LOG_TAG, "File not found: " + e.getMessage());
}
catch (IOException e)
{
Log.d(AppConstants.LOG_TAG,
"Error accessing file: " + e.getMessage());
} // 拍照后重新开始预览
mCamera.stopPreview();
mCamera.startPreview();
}
}; /** Check if this device has a camera */
private boolean checkCameraHardware(Context context)
{
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA))
{
// this device has a camera
return true;
}
else
{
// no camera on this device
return false;
}
} }

  布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <FrameLayout
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" > <Button
android:id="@+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:text="Capture" /> </FrameLayout> </LinearLayout>

  Manifest文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hellocustomcamera"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".HelloCustomCameraActivity"
android:label="@string/title_activity_hello_custom_camera" > <!-- android:screenOrientation="landscape" -->
<!-- configure this activity to use landscape orientation --> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

  三星S5660上测试可以拍照用,其他手机未知。

  

参考资料

  Reference: Camera

  http://developer.android.com/reference/android/hardware/Camera.html

  相机参数:

  http://developer.android.com/reference/android/hardware/Camera.Parameters.html

  API Guides: Camera

  http://developer.android.com/guide/topics/media/camera.html

  API Demos:

  com.example.android.apis.graphics包下的CameraPreview

  实例教程:Android设备功能之Camera教程篇:

  http://www.eoeandroid.com/thread-167870-1-1.html

http://www.cnblogs.com/mengdd/archive/2013/04/06/3002975.html

Android Camera 相机程序编写的更多相关文章

  1. .NET 开源了,Visual Studio 开始支持 Android 和 iOS 程序编写并自带 Android 模拟器

    .NET 开源了,Visual Studio 开始支持 Android 和 iOS 程序编写并自带 Android 模拟器 北京时间今天凌晨的 Connect(); 大会上,多少程序员的假想成为现实. ...

  2. android Camera相机类

    Camera相机类相关的几个流程方法 Camera.open(cameraId) 打开相机 camera.setDisplayOrientation(0) 设置相机水平方向 mCamera.setPr ...

  3. 【转】Android Camera 相机开发详解

    在Android 5.0(SDK 21)中,Google使用Camera2替代了Camera接口.Camera2在接口和架构上做了巨大的变动, 但是基于众所周知的原因,我们还必须基于 Android ...

  4. Android Camera相机功能实现 拍照并保存图片

    AndroidManifest.xml <uses-feature android:name="android.hardware.camera"/> <uses- ...

  5. [Android] 实现简单的相机程序

    好久没写了,有些东西做过都快忘了,赶紧记一下. 现在来实现一个简单的相机程序. 原文地址http://www.cnblogs.com/rossoneri/p/4246134.html 当然需要的话可以 ...

  6. Android Camera 使用小结。两种方法:一是调用系统camera app,二是自己写camera程序。

    源文链接:http://www.cnblogs.com/franksunny/archive/2011/11/17/2252926.html Android Camera 使用小结 Android手机 ...

  7. Android Camera解析(上) 调用系统相机拍摄照片

    开发中我们常须要通过相机获取照片(拍照上传等).一般通过调用系统提供的相机应用就可以满足需求:有一些复杂需求还须要我们自己定义相机相关属性,下篇我们会涉及到. 首先我们来研究怎样简单调用系统相机应用来 ...

  8. 基于qml创建最简单的android机图像采集程序

    前提是在已经搭建为android编写程序的qt平台上面,我们只需要简单几部就可以搭建最简单的android机图像采集程序 1.生成新的ququick app 2.在配置中添加 multimedia,因 ...

  9. Android Camera 使用小结

    Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发,我们可以使用两类方法:一是借助Inten ...

随机推荐

  1. 7、C#基础整理(类)

    String类 概念:是一个class类型的类,里面包含许多处理字符串的方法和属性 1.length方法. 例: string s = "hello"; Console.Write ...

  2. PHP 安全

    作为PHP程序员,特别是新手,对于互联网的险恶总是知道的太少,对于外部的入侵有很多时候是素手无策的,他们根本不知道黑客是如何入侵的.提交入侵.上传漏洞.sql 注入.跨脚本攻击等等.作为最基本的防范你 ...

  3. centOS5下安装redis make报错

    1:/tmp/redis-2.6.14/src/zmalloc.c:223:undefined reference to '__sync_add_and_fetch' make时加参数: make C ...

  4. php中将文中关键词高亮显示,快捷方式可以用正则

    php将文中关键词高亮显示,可以用正则表达式 $text = "Sample sentence from AnsonCheung.tk, regular expression has bec ...

  5. Flume NG 简介及配置实战

    Flume 作为 cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应用.Flume 初始的发行版本目前被统称为 Flume OG(original generation),属于 clo ...

  6. QEMU Guest Agent

    QEMU Guest Agent It is a daemon program running inside the domain which is supposed to help manageme ...

  7. Canvas 获取颜色值

    Canvas 是 HTML5 的画布元素,按照像素绘制图像.有时需要用户点击鼠标的时候获取像素值. 获取画布元素 var canvas = document.getElementById(" ...

  8. signtool对EXE进行签名

    https://msdn.microsoft.com/zh-cn/library/9sh96ycy(VS.80).aspx .NET Framework 2.0   其他版本   文件签名工具使用 A ...

  9. Radiobutton编辑

    package com.example.yuekao3; import java.util.ArrayList;import java.util.List; import com.baidu.farm ...

  10. 计算2的N次方

    总时间限制:  1000ms 内存限制:  65536kB 描述 任意给定一个正整数N(N<=100),计算2的n次方的值. 输入 输入一个正整数N. 输出 输出2的N次方的值. 样例输入 5 ...