Android拍照、图库裁剪图片(兼容版)

原创 2015年11月18日 14:27:24

<p>一个简单的Android拍照、图库、裁剪示例,兼容华为、三星手机</p><p>先看Mainactivity</p>
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private ImageView iv;

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

		iv = (ImageView) findViewById(R.id.iv);

		findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				ImageUtils.openCameraImage(MainActivity.this);
			}
		});
		findViewById(R.id.btn2).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				ImageUtils.openGallery(MainActivity.this);
			}
		});
	}


	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_CANCELED) {
			return;
		}

		switch (requestCode) {
		// 拍照获取图片
		case ImageUtils.GET_IMAGE_BY_CAMERA:
			
			// 自定义Uri(ImageUtils.imageUriFromCamera),用于保存拍照后图片地址
			if (ImageUtils.imageUriFromCamera != null) {
				// 可以直接显示图片,或者进行其他处理(如压缩或裁剪等)
				// iv.setImageURI(ImageUtils.imageUriFromCamera);
				// 对图片进行裁剪
				ImageUtils.cropImage(this, ImageUtils.imageUriFromCamera);
				break;
			}

			break;
		// 手机相册获取图片
		case ImageUtils.GET_IMAGE_FROM_PHONE:
			if (data != null && data.getData() != null) {
				
				// 可以直接显示图片,或者进行其他处理(如压缩或裁剪等)
				// iv.setImageURI(data.getData());

				// 对图片进行裁剪
				ImageUtils.cropImage(this, data.getData());
			}
			break;
			
		// 裁剪图片后结果
		case ImageUtils.CROP_IMAGE:
			if (ImageUtils.cropImageUri != null) {
				// 可以直接显示图片,或者进行其他处理(如压缩等)
				iv.setImageURI(ImageUtils.cropImageUri);
			}
			break;
		}
	}
}

ImageUtils类

mport java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;

public class ImageUtils {

	public static final int GET_IMAGE_BY_CAMERA = 5001;
	public static final int GET_IMAGE_FROM_PHONE = 5002;
	public static final int CROP_IMAGE = 5003;
	public static Uri imageUriFromCamera;
	public static Uri cropImageUri;

	public static void openCameraImage(final Activity activity) {
		ImageUtils.imageUriFromCamera = ImageUtils.createImagePathUri(activity);

		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		// MediaStore.EXTRA_OUTPUT参数不设置时,系统会自动生成一个uri,但是只会返回一个缩略图
		// 返回图片在onActivityResult中通过以下代码获取
		// Bitmap bitmap = (Bitmap) data.getExtras().get("data");
		intent.putExtra(MediaStore.EXTRA_OUTPUT, ImageUtils.imageUriFromCamera);
		activity.startActivityForResult(intent, ImageUtils.GET_IMAGE_BY_CAMERA);
	}

	/**
	 * 打开图库
	 */
	public static void openGallery2(final Activity activity) {
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		activity.startActivityForResult(intent, ImageUtils.GET_IMAGE_FROM_PHONE);
	}

	/**
	 * 打开图库-兼容华为
	 */
	public static void openGallery(final Activity activity) {

		Intent intent = new Intent(Intent.ACTION_PICK);
		intent.setType("image/*");
		activity.startActivityForResult(intent, ImageUtils.GET_IMAGE_FROM_PHONE);
	}

	public static void cropImage(Activity activity, Uri srcUri) {
		ImageUtils.cropImageUri = ImageUtils.createImagePathUri(activity);

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(srcUri, "image/*");
		intent.putExtra("crop", "true");

		// aspectX aspectY 是裁剪框宽高的比例(0-不保持比例)
		intent.putExtra("aspectX", 1);
		intent.putExtra("aspectY", 1);
		// outputX outputY 是裁剪后生成图片的宽高
		// intent.putExtra("outputX", 300);
		// intent.putExtra("outputY", 100);

		// return-data为true时,会直接返回bitmap数据,但是大图裁剪时会出现问题,推荐下面为false时的方式
		// return-data为false时,不会返回bitmap,但需要指定一个MediaStore.EXTRA_OUTPUT保存图片uri
		intent.putExtra(MediaStore.EXTRA_OUTPUT, ImageUtils.cropImageUri);
		intent.putExtra("return-data", false);

		activity.startActivityForResult(intent, CROP_IMAGE);
	}

	/**
	 * 创建一条图片地址uri,用于保存拍照后的照片
	 * 
	 * @param context
	 * @return 图片的uri
	 */
	private static Uri createImagePathUri(Context context) {
		Uri imageFilePath = null;
		String status = Environment.getExternalStorageState();
		SimpleDateFormat timeFormatter = new SimpleDateFormat(
				"yyyyMMdd_HHmmss", Locale.CHINA);
		long time = System.currentTimeMillis();
		String imageName = timeFormatter.format(new Date(time));
		// ContentValues是我们希望这条记录被创建时包含的数据信息
		ContentValues values = new ContentValues(3);
		values.put(MediaStore.Images.Media.DISPLAY_NAME, imageName);
		values.put(MediaStore.Images.Media.DATE_TAKEN, time);
		values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
		if (status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机存储
			imageFilePath = context.getContentResolver().insert(
					MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
		} else {
			imageFilePath = context.getContentResolver().insert(
					MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
		}
		Log.i("", "生成的照片输出路径:" + imageFilePath.toString());
		return imageFilePath;
	}

}

布局文件

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:background="@android:color/white"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/btn"
        android:text="拍照"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" />
    <Button
        android:id="@+id/btn2"
        android:text="图库"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" />
    
    <ImageView
        android:id="@+id/iv"
        android:background="@android:color/black"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content" />

</LinearLayout>

最后还有权限

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

源码下载


相关文章推荐

图库/拍照获取图片后裁剪处理(兼容4.4+)

图库/拍照获取图片后裁剪处理(兼容4.4+) 需求: - 从图库或调用系统相机拍照获取图片 - 复制图片至新目录 - 使用新目录下的图片裁剪 遇到的问题: - Android 6.0+ 无法使...

Android拍照、调用系统图库、裁剪图片到指定大小后输出

在这两天开发过程中要实现一个更换封面的功能,图片可以从系统图库或者照相机拍照,虽然可以通过Intent意向传递简单获取系统功能,但是在处理图片的时候还是遇到了很多问题。 首先我们创建一个uri指向图片...

Android拍照或从图库选择图片并裁剪

今天看《第一行代码》上面关于拍照和从相册选取图片那一部分,发现始终出不来效果,所以搜索其他资料学习一下相关知识,写一个简单的Demo。...

对图片裁剪框架 ucrop 的二次封装的工具类,添加从图库选择和拍照获取图片,项目中可直接使用,十分便捷

对图片裁剪框架 ucrop 的二次封装的工具类,添加从图库选择和拍照获取图片,项目中可直接使用,十分便捷...

Android 拍照,从图库选择照片,并裁剪,上传到服务器

整个例子的功能包括:通过照相机拍照,并把照片保存到SD卡中,或者通过图库选择图片。选择后,经过裁剪,再保存,显示,最后上传到服务器。内容知识点: 1、URI 分为两种: content 类型的 和...

Android拍照及选择图片及裁剪及兼容6.0权限实现

来到新公司接手项目之后,测试总是给我测出拍照,选择图片,裁剪的各种bug,比如换个手机就不行了,或者换个6.0的系统就不行了等等这样的问题,因为这个代码是之前的一个同事写的,代码很乱,改来改去,硬是没...

Android拍照及图片裁剪、调用系统相册(兼容6.0以上权限处理及7.0以上文件管理)

最近工作修改较旧的项目时,涉及到了图片相关功能 ,在使用安卓6.0手机及7.1手机拍照时,遇到了因权限及文件管理导致程序崩溃等问题。 刚好把功能修改完,把代码简单地贴一下,方便以后使用。...
  • donkor_
  • donkor_
  • 2017年10月25日 14:51
  • 407

调用相机拍照或者从图库里选择图片裁剪后设置到界面

拍照或者从相册中挑选图片设置头像是很常见的功能。同样是网上搜索了资料,知道了可以调用系统的功能实现,然后就试着开始写了。先是布局文件,就是一个ImageView和一个TextView。 ...

Android 调用系统相机、图库 ,取图片并裁剪、保存sd卡

布局只有一个ImageView就不给出了 package com.example.setimage; import java.io.File; import java.io.FileInputStr...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android拍照、图库裁剪图片(兼容版)
举报原因:
原因补充:

(最多只允许输入30个字)