设置相机大小-参数 vs 意图?

13

我目前正在使用一个意图来拍照,就像这样:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
intent.putExtra("return-data", true);
startActivityForResult(intent, CAMERA_REQUEST);

但是我真的需要将图像大小尽可能地设为正方形。因此,在研究后,似乎需要这样做:

Camera camera = Camera.open();
Parameters params = camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();

// Once you will see the supported Sizes, you can define them with the method :

setPictureSize(int width, int height);

我的问题是,这些方法能一起使用吗?还是只能选其一?哪种方法最适合我的需求?

我有一个用户个人资料图片96px x 96px的框。在用户拍照后,我希望图片填满整个框而不会被拉伸。最好的方法是在拍照时设置大小,还是在事后更改imageViewbitmap(或者其他方法...)?或者,我应该让用户进行裁剪,并定义裁剪区域的尺寸?

编辑:请参见悬赏问题以获取更新的问题。


1
这些是否可以一起使用还是只能二选一?后者是指自己使用Camera拍照。前者是指其他应用程序代表您使用Camera本身拍照。 - CommonsWare
4个回答

16

这段代码允许我从图库中选择图片,进行裁剪并使用我的宽高比。我也写了类似的代码来使用相机。用户拍摄照片后,它会立即启动一个活动来对照片进行裁剪。

  Intent photoPickerIntent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                photoPickerIntent.setType("image/*");
                photoPickerIntent.putExtra("crop", "true");
                photoPickerIntent.putExtra("outputX", 150);
                photoPickerIntent.putExtra("outputY", 150);
                photoPickerIntent.putExtra("aspectX", 1);
                photoPickerIntent.putExtra("aspectY", 1);
                photoPickerIntent.putExtra("scale", true);
                photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
                photoPickerIntent.putExtra("outputFormat",
                        Bitmap.CompressFormat.JPEG.toString());
                startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);

2
使用 Intent photoPickerIntent = new Intent("android.media.action.IMAGE_CAPTURE"); 来启动相机,然后移除 photoPickerIntent.setType("image/*");。 - Felipe
@FelipeMicaroniLalli 你能解释一下这里的区别是什么吗? - TheLettuceMaster
2
如果您想从相机中获取而不是从图库中获取 - Felipe
这个解决方案不能帮助我直接从相机加载裁剪图片...有没有其他的解决方案?谢谢。 - Avijeet
这个解决方案不起作用。在Android模拟器上使用相机应用程序会导致崩溃。 - Sergei Bubenshchikov
当用户在预览拍照前查看相机所看到的内容时,会看到修改后的纵横比,还是默认的纵横比? - Lealo

6
您可以使用 Bitmap.createScaledBitmap(Bitmap src, int destWidth, int destHeight, boolean filter) 来调整位图大小。

这样做的唯一问题是它不能正确缩放图片。我认为我需要像这样做,但让用户在相机应用程序中裁剪完美的正方形图片。然后,如果我做类似这样的事情,我可以缩小图片? - TheLettuceMaster
你可以使用上面的代码来压缩,但你真正想要的是剪切,对吗? - Moesio
是的,我需要裁剪。实际上我已经解决了...会将最终代码发布为答案。感谢您对此的建议...最终我采用了使用相机拍摄普通照片,然后立即启动新的意图进行裁剪...请查看答案。 - TheLettuceMaster
如果图像的各边比例不相等,这将会扭曲图像。 - Farid

3
这两种方法不能同时使用,它们是互斥的。哪一种方法更适合我的需求呢?
当您使用Intent与相机一起使用时,您是在请求系统为您拍照(即用户会看到默认相机应用程序并拍摄照片或从画廊中选择照片)。
当您使用第二种方法时,您将创建自己的Camera对象,这比第一种更可定制化。
对于第一种方法,您需要在之后调整图像的尺寸,而对于第二种方法,您可以直接以正确的大小拍摄照片,因此主要区别在于第一种是由Android控制,而第二种是由您的应用程序直接控制,所以如果您不想之后再调整大小,建议使用第二种方法。 如果无论如何都要调整大小(请参阅下文),则采用哪种方法拍摄照片并不重要,在这种情况下,使用默认应用程序即可。
取决于您的需求。如果您选择第一种情况,您的应用程序会更改拍摄的图片,因此您可以选择要素库的最终96x96图片。但是,这种方法的问题在于,您可能会意外地裁剪/伸展/操作图像,使得用户感到困惑或至少是出乎意料的(例如,删除部分面部)。
当您使用第二种方法时,您为用户提供了选择想要的图片一部分的自由。
如果您能够自动检测原始图像的最佳部分,则应采用第一种方法,但实际上您询问的是哪种方法更好,因此您应该选择第二种方法,因为它为最终用户提供了更多的灵活性

2

(1) 如何自动裁剪以适应我的ImageView(96dp x 96dp)

看起来你已经有了解决方案来正确获取裁剪。如果你想将像素密度单位转换为对应于手机的像素单位,你需要使用:

public int dpToPixel(int dp) {
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
}

所以您可以使用以下作为额外的内容
photoPickerIntent.putExtra("outputX", dpToPixel(96));
photoPickerIntent.putExtra("outputY", dpToPixel(96));

(2) 如何缩小图片大小(制作新位图?)这些需要快速加载到ListViews上。所以,我不需要上传1MB的图片,而是需要一个大约为2,000k的图片。
如果您使用的是大小约为96dp的图像,则无需担心图像大小。在尝试在活动中创建和销毁多个新位图时,通常会出现非常危险的问题。例如,“内存不足”问题。因此,更建议使用Uri。因此,请保存您正在将其放入意图中的uri,并制作要按照所需方式在listview上显示的uri列表。
对于imageview,可以使用setImageURI(Uri uri)。
希望这回答了您所有的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接