您的位置:首页 > 移动开发 > Android开发

Android相机的基本使用与自定义相机

2016-07-25 22:32 507 查看
在项目中,经常会用到拍照获取图片以及从图库中选择图片,此篇文章就是自己的总结。

相机拍照

第一步:就是判断设备是否支持拍照:

Intent intentCamer = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(intentCamer.resolveActivity(getPackageManager()) == null) {
Toast.makeText(MainActivity.this, "No Cammer", Toast.LENGTH_SHORT).show();
} else {
startActivityForResult(intentCamer, REQUEST_IMAGE_CAPTURE);
}


第二步:调取系统自带的拍照界面

系统自带的拍照获取的图片可以是缩略图,也可以为原图,而其中的区别就在于intent的putExtra。

Get Photo Thumbnail

Intent intentCamer = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intentCamer.resolveActivity(getPackageManager()) == null) {
Toast.makeText(MainActivity.this, "No Cammer", Toast.LENGTH_SHORT).show();
} else {
startActivityForResult(intentCamer, REQUEST_IMAGE_CAPTURE);
}


Get Full Size Photo

Intent intentFullSize = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intentFullSize.resolveActivity(getPackageManager()) == null) {
Toast.makeText(MainActivity.this, "No Cammer", Toast.LENGTH_SHORT).show();
} else {
File photoFile = null;
try {
photoFile = createPhotoFile();
if (photoFile != null) {
Uri photoUri = FileProvider.getUriForFile(MainActivity.this, "com.example.android.fileprovider", photoFile);
intentFullSize.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intentFullSize, REQUEST_IMAGE_CAPTURE);
}
} catch (IOException e) {
e.printStackTrace();
}
}


private File createPhotoFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;

}


第三步:加入图库:

private void addToGallery() {
Intent intentToGallery = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
intentToGallery.setData(contentUri);
this.sendBroadcast(intentToGallery);
}


图库获取图片

Intent

Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
fileIntent.setType("image/*");
startActivityForResult(fileIntent, REQUEST_IMAGE_FILE);


我们知道,在OnActivityResult获取的值是一个uri,在android中我们经常遇到两种uri,一种是以content开头的,一种是以file开头的uri,而在图片处理的过程中以content开头的uri不能做任何操作,而在OnActivityResult获取的uri就是content开头的uri,所以我们应该把以content开头的uri转化为以file开头的uri。

private Uri convertUri(Uri uri) {
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
return saveBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}


此方法的参数是一个以content开头的uri,而返回值是一个以file开头的uri

private Uri saveBitmap(Bitmap bitmap) {
File temDir = new File(Environment.getExternalStorageDirectory() + "/text");
if (!temDir.exists()) {
temDir.mkdirs();
}
File img = null;
try {
img = createPhotoFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(img);
bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
return Uri.fromFile(img);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}


此方法主要是保存图片到本地,并返回一个以file开头的uri。

图片的裁剪

private void startImageZoon(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("return-data", true);
startActivityForResult(intent, REQUEST_IMAGE_ZOOM);
}


图片的上传

图片上传到服务器就是把bitMap转化为String,以Base64的方式提交给服务器。

private String bitMapToString(Bitmap bitmap){
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,85,byteArrayOutputStream);
byte[] bytes=byteArrayOutputStream.toByteArray();
return new String(Base64.encode(bytes,Base64.DEFAULT));
}


自定义相机

前面的内容都是利用系统自带的相机界面,有时业务的需求可能需要自定义相机界面。

而自定义相机的核心姿势是:Camera和SurfaceView

Camera API:

final void autoFocus(Camera.AutoFocusCallback cb)

Starts camera auto-focus and registers a callback function to run when the camera is focused.

static Camera open()

Creates a new Camera object to access the first back-facing camera on the device.

final void release()

Disconnects and releases the Camera object resources.

final void setDisplayOrientation(int degrees)

Set the clockwise rotation of preview display in degrees.

final void setPreviewDisplay(SurfaceHolder holder)

Sets the Surface to be used for live preview.

final void startPreview()

Starts capturing and drawing preview frames to the screen.

final void stopPreview()

Stops capturing and drawing preview frames to the surface, and resets the camera for a future call to startPreview().

final void takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg)

Equivalent to takePicture(shutter, raw, null, jpeg).

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
tools:context="com.example.administrator.myapplication.CustomCameraActivity">
<SurfaceView
android:id="@+id/sv_custom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_custom_camera_capture"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Capture"
android:gravity="center"/>
<TextView
android:id="@+id/tv_custom_camera_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Cancel"
android:gravity="center"/>
</LinearLayout>

</LinearLayout>


核心代码

public class CustomCameraActivity extends AppCompatActivity implements SurfaceHolder.Callback, View.OnClickListener {

@BindView(R.id.sv_custom)
SurfaceView svCustom;
@BindView(R.id.tv_custom_camera_capture)
TextView tvCustomCameraCapture;
@BindView(R.id.tv_custom_camera_cancel)
TextView tvCustomCameraCancel;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_camera);
ButterKnife.bind(this);
initView();
initListener();
}

private void initView() {
mSurfaceHolder = svCustom.getHolder();
mSurfaceHolder.addCallback(this);
}
private void initListener() {
tvCustomCameraCapture.setOnClickListener(this);
}

/**
*
* @return 摄像机对象
*/
private Camera getCamera() {
Camera camera;
camera = Camera.open();
return camera;
}

/**
*  摄像机与surfaceView的绑定
* @param camera
* @param surfaceHolder
*/
private void startPreview(Camera camera, SurfaceHolder surfaceHolder) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}

}

/**
* 释放资源
*/
private void releaseCamera() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}

}

@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
mCamera = getCamera();
if (mSurfaceHolder != null) {
startPreview(mCamera, mSurfaceHolder);
}
}
}

@Override
protected void onPause() {
super.onPause();
releaseCamera();
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
startPreview(mCamera, mSurfaceHolder);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mCamera.stopPreview();
startPreview(mCamera, mSurfaceHolder);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_custom_camera_capture:
/**
* 拍照功能
*/
Camera.Parameters parameters=mCamera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setPictureSize(800,400);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success){
mCamera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File file=new File(Environment.getExternalStorageDirectory(),"temp.jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(data);
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
});
break;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: