Android实现拍照 并裁剪图片功能
时间: 2024-02-19 21:49:53 浏览: 150
实现拍照并裁剪图片功能需要以下步骤:
1. 添加权限
在AndroidManifest.xml文件中添加以下权限:
```xml
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```
2. 创建布局文件
创建一个布局文件camera_preview.xml,并添加一个SurfaceView和一个Button,用于显示和拍照。
```xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button
android:id="@+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拍照"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
```
3. 实现拍照功能
在Activity中,获取Camera实例,并在SurfaceView上显示预览图像。当用户点击拍照按钮时,调用Camera.takePicture()方法拍照。拍照成功后,保存照片并显示裁剪界面。
```java
public class CameraActivity extends Activity implements SurfaceHolder.Callback {
private Camera mCamera;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Button mButtonCapture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_preview);
// 获取SurfaceView和Button实例
mSurfaceView = findViewById(R.id.surface_view);
mButtonCapture = findViewById(R.id.button_capture);
// 监听Button点击事件
mButtonCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 拍照
mCamera.takePicture(null, null, mPictureCallback);
}
});
// 获取SurfaceHolder实例,并添加回调监听
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 打开摄像头并设置预览
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("CameraTest", "Error setting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// 在SurfaceView上显示预览图像
if (mSurfaceHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
Log.d("CameraTest", "Error stopping camera preview: " + e.getMessage());
}
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d("CameraTest", "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 释放摄像头资源
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// 保存照片
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d("CameraTest", "Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("CameraTest", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("CameraTest", "Error accessing file: " + e.getMessage());
}
// 显示裁剪界面
Intent intent = new Intent(CameraActivity.this, CropActivity.class);
intent.putExtra("image_path", pictureFile.getPath());
startActivity(intent);
}
};
private File getOutputMediaFile() {
// 创建目录
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("CameraTest", "failed to create directory");
return null;
}
}
// 创建文件
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_" + timeStamp + ".jpg");
return mediaFile;
}
}
```
4. 实现裁剪功能
创建一个布局文件crop.xml,添加一个ImageView和一个Button,用于显示图片和保存裁剪后的图片。
```xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/crop_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"/>
<Button
android:id="@+id/button_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
```
在CropActivity中,获取传递过来的图片路径,并将图片显示在ImageView上。当用户点击保存按钮时,调用Bitmap.createBitmap()方法裁剪图片,并保存到相册。
```java
public class CropActivity extends Activity {
private ImageView mImageView;
private Button mButtonSave;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.crop);
// 获取ImageView和Button实例
mImageView = findViewById(R.id.image_view);
mButtonSave = findViewById(R.id.button_save);
// 获取传递过来的图片路径
Intent intent = getIntent();
String imagePath = intent.getStringExtra("image_path");
// 将图片显示在ImageView上
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
mImageView.setImageBitmap(bitmap);
// 监听Button点击事件
mButtonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 裁剪并保存图片
Bitmap croppedBitmap = getCroppedBitmap(bitmap);
saveBitmapToGallery(croppedBitmap);
Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show();
finish();
}
});
}
private Bitmap getCroppedBitmap(Bitmap bitmap) {
// 获取ImageView的尺寸
int viewWidth = mImageView.getWidth();
int viewHeight = mImageView.getHeight();
// 获取图片的尺寸
int imageWidth = bitmap.getWidth();
int imageHeight = bitmap.getHeight();
// 计算缩放比例
float scale = Math.min((float) viewWidth / imageWidth, (float) viewHeight / imageHeight);
// 计算裁剪区域
int cropWidth = (int) (viewWidth / scale);
int cropHeight = (int) (viewHeight / scale);
int x = (imageWidth - cropWidth) / 2;
int y = (imageHeight - cropHeight) / 2;
// 裁剪图片
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, cropWidth, cropHeight);
return croppedBitmap;
}
private void saveBitmapToGallery(Bitmap bitmap) {
// 创建目录
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("CameraTest", "failed to create directory");
return;
}
}
// 保存图片
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imagePath = mediaStorageDir.getPath() + File.separator +
"IMG_" + timeStamp + ".jpg";
File imageFile = new File(imagePath);
try {
FileOutputStream fos = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
Log.d("CameraTest", "Error accessing file: " + e.getMessage());
}
// 通知相册更新
MediaScannerConnection.scanFile(this, new String[]{imagePath}, null, null);
}
}
```
阅读全文