Android获取本地相册图片和拍照获取图片的实现方法

这篇文章主要为大家详细介绍了Android获取本地相册图片和拍照获取图片的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

需求:从本地相册找图片,或通过调用系统相机拍照得到图片。

容易出错的地方:

1、当我们指定了照片的uri路径,我们就不能通过data.getData();来获取uri,而应该直接拿到uri(用全局变量或者其他方式)然后设置给imageView

imageView.setImageURI(uri);

2、我发现手机前置摄像头拍出来的照片只有几百KB,直接用imageView.setImageURI(uri);没有很大问题,但是后置摄像头拍出来的照片比较大,这个时候使用imageView.setImageURI(uri);就容易出现 out of memory(oom)错误,我们需要先把URI转换为Bitmap,再压缩bitmap,然后通过imageView.setImageBitmap(bitmap);来显示图片。

3、将照片存放到SD卡中后,照片不能立即出现在系统相册中,因此我们需要发送广播去提醒相册更新照片。

4、这里用到了sharepreference,要注意用完之后移除缓存。

代码:

MainActivity:

 package com.sctu.edu.test; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.ImageView; import com.sctu.edu.test.tools.ImageTools; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity { private static final int PHOTO_FROM_GALLERY = 1; private static final int PHOTO_FROM_CAMERA = 2; private ImageView imageView; private File appDir; private Uri uriForCamera; private Date date; private String str = ""; private SharePreference sharePreference; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Android不推荐使用全局变量,我在这里使用了sharePreference sharePreference = SharePreference.getInstance(this); imageView = (ImageView) findViewById(R.id.imageView); } //从相册取图片 public void gallery(View view) { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, PHOTO_FROM_GALLERY); } //拍照取图片 public void camera(View view) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); uriForCamera = Uri.fromFile(createImageStoragePath()); sharePreference.setCache("uri", String.valueOf(uriForCamera)); /** * 指定了uri路径,startActivityForResult不返回intent, * 所以在onActivityResult()中不能通过data.getData()获取到uri; */ intent.putExtra(MediaStore.EXTRA_OUTPUT, uriForCamera); startActivityForResult(intent, PHOTO_FROM_CAMERA); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //第一层switch switch (requestCode) { case PHOTO_FROM_GALLERY: //第二层switch switch (resultCode) { case RESULT_OK: if (data != null) { Uri uri = data.getData(); imageView.setImageURI(uri); } break; case RESULT_CANCELED: break; } break; case PHOTO_FROM_CAMERA: if (resultCode == RESULT_OK) { Uri uri = Uri.parse(sharePreference.getString("uri")); updateDCIM(uri); try { //把URI转换为Bitmap,并将bitmap压缩,防止OOM(out of memory) Bitmap bitmap = ImageTools.getBitmapFromUri(uri, this); imageView.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); } removeCache("uri"); } else { Log.e("result", "is not ok" + resultCode); } break; default: break; } } /** * 设置相片存放路径,先将照片存放到SD卡中,再操作 * * @return */ private File createImageStoragePath() { if (hasSdcard()) { appDir = new File("/sdcard/testImage/"); if (!appDir.exists()) { appDir.mkdirs(); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); date = new Date(); str = simpleDateFormat.format(date); String fileName = str + ".jpg-600"; File file = new File(appDir, fileName); return file; } else { Log.e("sd", "is not load"); return null; } } /** * 将照片插入系统相册,提醒相册更新 * * @param uri */ private void updateDCIM(Uri uri) { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(uri); this.sendBroadcast(intent); Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath()); MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "", ""); } /** * 判断SD卡是否可用 * * @return */ private boolean hasSdcard() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { return true; } else { return false; } } /** * 移除缓存 * * @param cache */ private void removeCache(String cache) { if (sharePreference.ifHaveShare(cache)) { sharePreference.removeOneCache(cache); } else { Log.e("this cache", "is not exist."); } } } 

ImageTools:

 package com.sctu.edu.test.tools; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class ImageTools { /** * 通过uri获取图片并进行压缩 * * @param uri * @param activity * @return * @throws IOException */ public static Bitmap getBitmapFromUri(Uri uri, Activity activity) throws IOException { InputStream inputStream = activity.getContentResolver().openInputStream(uri); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; options.inDither = true; options.inPreferredConfig = Bitmap.Config.ARGB_8888; BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); int originalWidth = options.outWidth; int originalHeight = options.outHeight; if (originalWidth == -1 || originalHeight == -1) { return null; } float height = 800f; float width = 480f; int be = 1; //be=1表示不缩放 if (originalWidth > originalHeight && originalWidth > width) { be = (int) (originalWidth / width); } else if (originalWidth  height) { be = (int) (originalHeight / height); } if (be <= 0) { be = 1; } BitmapFactory.Options bitmapOptinos = new BitmapFactory.Options(); bitmapOptinos.inSampleSize = be; bitmapOptinos.inDither = true; bitmapOptinos.inPreferredConfig = Bitmap.Config.ARGB_8888; inputStream = activity.getContentResolver().openInputStream(uri); Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, bitmapOptinos); inputStream.close(); return compressImage(bitmap); } /** * 质量压缩方法 * * @param bitmap * @return */ public static Bitmap compressImage(Bitmap bitmap) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); int options = 100; while (byteArrayOutputStream.toByteArray().length / 1024 > 100) { byteArrayOutputStream.reset(); //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流 bitmap.compress(Bitmap.CompressFormat.JPEG, options, byteArrayOutputStream); options -= 10; } ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); Bitmap bitmapImage = BitmapFactory.decodeStream(byteArrayInputStream, null, null); return bitmapImage; } } 

AndroidMainfest.xml:

      

activity_main.xml:

   

效果图:

 

或许有人会问,在Android6.0上面怎么点击拍照就出现闪退,那是因为我设置的最高SDK版本大于23,而我现在还没对运行时权限做处理,也许我会在下一篇博客里处理这个问题。谢谢浏览,希望对你有帮助!


以上就是Android获取本地相册图片和拍照获取图片的实现方法的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动