1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 选择手机中的一张照片或拍照上传图片(超高清晰度)

选择手机中的一张照片或拍照上传图片(超高清晰度)

时间:2021-03-02 20:09:27

相关推荐

选择手机中的一张照片或拍照上传图片(超高清晰度)

本文借鉴了多位前辈的代码,在自己的项目使用中根据需求做了一些修改,为了以后再次使用类似功能的时候方便一些,特把主要的代码流程部分贴出来

首先在activity中定义几个常量

private static final String IMAGE_UNSPECIFIED = "image/*";private static final int TAKE_PICTURE = 0;//拍照private static final int CHOOSE_PICTURE = 1;//手机内单选private static final int MULTIPLE_CHOICE = 2;//手机内多选private static final int SCALE = 5;// 照片缩小比例//临时图片的位置,主要是为了得到tempUriFile tempFile = new File(Environment.getExternalStorageDirectory(), "temp.jpg");Uri tempUri = Uri.fromFile(tempFile);

然后在你需要添加图片的操作里面加入如下选项

switch (position) {case TAKE_PICTURE://拍照Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "temp.jpg"));// 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(openCameraIntent, TAKE_PICTURE);break;case CHOOSE_PICTURE://单选Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);openAlbumIntent.setType("image/*");startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);break;case MULTIPLE_CHOICE:// 多选Intent intent = new Intent(AddGoodsActivity.this, PhotoWallActivity.class);intent.putExtra("size", 8 - dgv_add_goods_imgs2.getChildCount());startActivityForResult(intent, MULTIPLE_CHOICE);break;default:break;}

多选的操作需要跳一个自定义的activity,不在本文讨论,因为是直接使用的/books1958/article/details/41010077中的例子,只是稍作修改,想看多选操作的请移步

拍照会调用相机拍照后在内存卡根目录存一张临时图片,单选会选择一张图片后返回图片路径,这两个都是取的文件路径,而不是bitmap,因为要保证清晰度,最好是自己去重绘bitmap,特别是你需要切图的,切完之后不能直接返回bitmap,而是将切完之后的图保存成临时文件,然后重绘

拍完选完之后会自动调用当前activity的onActivityResult,在onActivityResult处理返回的图片

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {Bitmap bitmap = null;Bitmap newBitmap = null;switch (requestCode) {case TAKE_PICTURE://拍照if (isgood) {startPhotoZoom(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/temp.jpg")));} else {// 将保存在本地的图片取出并缩小后显示在界面上bitmap = ImageTools.getSmallBitmap(Environment.getExternalStorageDirectory() + "/temp.jpg");newBitmap = ImageTools.zoomBitmap(bitmap,bitmap.getWidth() / SCALE > 0 ? bitmap.getWidth() / SCALE : bitmap.getWidth(),bitmap.getHeight() / SCALE > 0 ? bitmap.getHeight() / SCALE : bitmap.getHeight());// 由于Bitmap内存占用较大,这里需要回收内存,否则会报out of memory异常AddImg2DGV(newBitmap);bitmap.recycle();}break;case CHOOSE_PICTURE://单选ContentResolver resolver = getContentResolver();// 照片的原始资源地址Uri originalUri = data.getData();try {// 使用ContentProvider通过URI获取原始图片bitmap = MediaStore.Images.Media.getBitmap(resolver, originalUri);if (bitmap != null) {if (isgood) {startPhotoZoom(Uri.fromFile(new File(getPath(originalUri))));} else {// 为防止原始图片过大导致内存溢出,这里先缩小原图显示,然后释放原始Bitmap占用的内存newBitmap = ImageTools.zoomBitmap(bitmap,bitmap.getWidth() / SCALE > 0 ? bitmap.getWidth() / SCALE : bitmap.getWidth(),bitmap.getHeight() / SCALE > 0 ? bitmap.getHeight() / SCALE : bitmap.getHeight());AddImg2DGV(newBitmap);}// 释放原始图片占用的内存,防止out of memory异常发生bitmap.recycle();}} catch (Exception e) {e.printStackTrace();}break;case MULTIPLE_CHOICE:// 多选ArrayList<String> paths = data.getStringArrayListExtra("paths");for (int i = 0; i < paths.size(); i++) {// 将保存在本地的图片取出并缩小后显示在界面上bitmap=ImageTools.getSmallBitmap(paths.get(i));newBitmap = ImageTools.zoomBitmap(bitmap,bitmap.getWidth() / SCALE > 0 ? bitmap.getWidth() / SCALE : bitmap.getWidth(),bitmap.getHeight() / SCALE > 0 ? bitmap.getHeight() / SCALE : bitmap.getHeight());// 由于Bitmap内存占用较大,这里需要回收内存,否则会报out of memory异常AddImg2DGV(newBitmap);bitmap.recycle();}break;default:bitmap = ImageTools.getSmallBitmap(Environment.getExternalStorageDirectory() + "/temp.jpg");AddImg2DGV(bitmap);break;}}}

AddImg2DGV(newBitmap);方法是将得到的bitmap显示出来,isgood是用来判断是不是需要切图的,default中执行的是切图后的返回数据

切图后并没有返回bitmap而是把切图后的图作为一个临时文件存储了起来

切图代码:

public void startPhotoZoom(Uri uri) {Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, IMAGE_UNSPECIFIED);intent.putExtra("crop", "true");// aspectX aspectY 是宽高的比例intent.putExtra("aspectX", 14);intent.putExtra("aspectY", 10);// outputX outputY 是裁剪图片宽高intent.putExtra("outputX", 640);intent.putExtra("outputY", 450);intent.putExtra("return-data", false);intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);startActivityForResult(intent, PHOTORESOULT);}

根据路径取出缩小后的bitmap:

public static Bitmap getSmallBitmap(String path){//new 出来一个bitmap的参数BitmapFactory.Options options=new BitmapFactory.Options();//设置为true,不会生成bitmao对象,只是读取尺寸和类型信息options.inJustDecodeBounds=true;BitmapFactory.decodeFile(path, options);//得到这个比例 并赋予option里面的inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, 450, 640);//设置为false,即将要生成bitmap对象啦options.inJustDecodeBounds = false;//有了这个option,我们可以生成bitmap对象了Bitmap bitmap=BitmapFactory.decodeFile(path, options);return bitmap;}

public static int calculateInSampleSize(BitmapFactory.Options options,int reqHeight,int reqWidth){//得到原始图片宽高 int height=options.outHeight;int width=options.outWidth;//默认设置为1,即不缩放int inSampleSize=1;//如果图片原始的高大于我们期望的高,或者图片的原始宽大于我们期望的宽,换句话意思就是,我们想让它变小一点if (height > reqHeight || width > reqWidth) {//原始的高除以期望的高,得到一个比例final int heightRatio = Math.round((float) height/ (float) reqHeight);//原始的宽除以期望的宽,得到一个比例final int widthRatio = Math.round((float) width / (float) reqWidth);//取上面两个比例中小的一个,返回这个比例inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;}return inSampleSize;}

根据原始bitmap再次缩小:

public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {int w = bitmap.getWidth();int h = bitmap.getHeight();Matrix matrix = new Matrix();float scaleWidth = ((float) width / w);float scaleHeight = ((float) height / h);matrix.postScale(scaleWidth, scaleHeight);Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);return newbmp;}

有人要问为什么要这么写?

ImageTools.zoomBitmap(bitmap,bitmap.getWidth() / SCALE > 0 ? bitmap.getWidth() / SCALE : bitmap.getWidth(),bitmap.getHeight() / SCALE > 0 ? bitmap.getHeight() / SCALE : bitmap.getHeight());

因为这个长宽取的是int,如果图片本来的长宽就很小,除一下就会变0,这时候是会报异常的

再贴一些关于biemap的各种操作方法:

Drawable转bitmap:

public static Bitmap drawableToBitmap(Drawable drawable) {int w = drawable.getIntrinsicWidth();int h = drawable.getIntrinsicHeight();Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888: Bitmap.Config.RGB_565;Bitmap bitmap = Bitmap.createBitmap(w, h, config);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, w, h);drawable.draw(canvas);return bitmap;}

bitmap转Drawable:

public static Drawable bitmapToDrawable(Bitmap bitmap) {return new BitmapDrawable(bitmap);}

InputStream流转bitmap:

public static Bitmap inputStreamToBitmap(InputStream inputStream)throws Exception {return BitmapFactory.decodeStream(inputStream);}

byteArray转bitmap:

public static Bitmap byteToBitmap(byte[] byteArray) {if (byteArray.length != 0) {return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);} else {return null;}}

byteArray转Drawable:

public static Drawable byteToDrawable(byte[] byteArray) {ByteArrayInputStream ins = null;if (byteArray != null) {ins = new ByteArrayInputStream(byteArray);}return Drawable.createFromStream(ins, null);}

bitmap转byteArray:

public static byte[] bitmapToBytes(Bitmap bm) {byte[] bytes = null;if (bm != null) {ByteArrayOutputStream baos = new ByteArrayOutputStream();press(pressFormat.PNG, 100, baos);bytes = baos.toByteArray();}return bytes;}

Drawable转byteArray:

public static byte[] drawableToBytes(Drawable drawable) {BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;Bitmap bitmap = bitmapDrawable.getBitmap();byte[] bytes = bitmapToBytes(bitmap);;return bytes;}

图片Uri转路径:

public String getPath(Uri originalUri) {try {String[] proj = { MediaStore.Images.Media.DATA };// 好像是Android多媒体数据库的封装接口,具体的看Android文档Cursor cursor = managedQuery(originalUri, proj, null, null, null);// 按我个人理解 这个是获得用户选择的图片的索引值int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);// 将光标移至开头 ,这个很重要,不小心很容易引起越界cursor.moveToFirst();// 最后根据索引值获取图片路径return cursor.getString(column_index);} catch (Exception e) {return "";}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。