如何拍摄照片并获取图像和缩略图?

8
我简直不能相信我已经为这个简单的问题挣扎了几个小时了,但是我无法使它正常运行。原则上,我想要的功能是:
用户点击按钮。触发一个ACTION_IMAGE_CAPTURE意图并打开默认的相机应用程序。用户拍照后返回到我的应用程序。我的应用程序显示缩略图。点击缩略图会打开图像查看器。
实际上非常简单。通过这个指南,似乎只需要复制和粘贴就可以了:https://developer.android.com/training/camera/photobasics.html。但魔鬼在细节中。
目前,它确实可以工作,但性能很差,因为我会即时创建缩略图(在我的实际应用程序中,我为RecyclerView中每个条目显示多个缩略图)。我希望有一种简单的方法,我在浏览了数十个Stack Overlow问题后忽略了它。
理想情况下,我希望触发我的ACTION_IMAGE_CAPTURE意图,让默认的相机应用程序生成缩略图,在系统的缩略图和图像内容提供程序中存储缩略图和图像,并最终在onActivityResult()中获取相应的content:// URIs。那将是非常好的……
现在,我面临的问题如下:
1.调用onActivityResult()中的结果意图的getData()时收到的URI始终为null,无论是否给出MediaStore.EXTRA_OUTPUT值。
2.当省略MediaStore.EXTRA_OUTPUT额外时,我会以位图形式而不是content:// URI形式获得缩略图。因此,如果不想在下次启动我的活动时生成它,我必须自己保存缩略图。
3.如果将内容:// URI传递给相机以保存图像,则不理解为什么我不会获得缩略图。我的意思是,相机已经将图像加载到内存中,并可以轻松生成缩略图。但是,相反,我必须再次从磁盘加载多个MB才能生成缩略图。即使在之后保存缩略图,这似乎也是一种巨大的浪费。
4.我读过一些相机应用程序实际上会在任何情况下创建缩略图并将其提供给画廊或其他东西。但是似乎没有标准化。
所以,我想我的两个content:// URIs的愿望根本行不通。但是,在我继续自己生成(最终重复)缩略图并在我的应用程序中进行持久化和缓存之前,我想问:
有没有我不知道的简单方法?是否可能检索图像和缩略图,还是我必须自己生成缩略图?
注意:我希望通过让安卓将其添加到媒体数据库中,使我的应用程序拍摄的照片可以在画廊中使用。我无法想象每个访问该媒体数据库(如画廊)的应用程序都会创建自己的缩略图集合,对吧?
提前感谢!
2个回答

5
在调用onActivityResult()中的getData()时,无论是否使用MediaStore.EXTRA_OUTPUT值,我收到的URI始终为空。
如果提供了EXTRA_OUTPUT,ACTION_IMAGE_CAPTURE不会返回Uri。如果您知道图像应该驻留的位置,请去那里查找它。
当省略MediaStore.EXTRA_OUTPUT参数时,我以位图形式而不是content:// URI形式获得缩略图。
正确。
如果我传递一个content:// URI给相机来保存图像,我不明白为什么我没有获得缩略图。
这不是ACTION_IMAGE_CAPTURE协议documented的方式。您要么通过EXTRA_OUTPUT获得完整大小的照片,要么通过"data"额外获得缩略图,不能同时得到两者。
我的意思是,相机已经将图像加载到内存中,可以轻松生成缩略图。

没有一个单一的"相机"。有数百个相机应用程序 - 预装和用户安装的 - 可能会响应您的ACTION_IMAGE_CAPTURE请求,在大约10000个设备型号和20亿台设备上。

是否可以同时检索图像和缩略图?

不能通过ACTION_IMAGE_CAPTURE实现。

我是否需要自己生成缩略图?

也许可以向MediaStore请求缩略图。我没有尝试从MediaStore检索图像,但据我所知,它准备了索引的图像的缩略图。但是,请记住,您对索引(例如,MediaScannerConnection.scanFile())的请求是异步的。您可能需要暂时自己管理捕获的这个应用程序运行期间的缩略图,并依靠MediaStore获取所有其他图像的缩略图。

我无法想象每个访问该媒体数据库(例如画廊)的应用程序都创建自己的缩略图集合

我想很多应用程序请求全尺寸的图像,并让其图像加载库(Glide、Picasso等)将图像缩放到所需大小。

谁会想要拍照只得到缩略图呢?

ACTION_IMAGE_CAPTURE协议已经存在了十年。在2008年,移动设备的一切都很昂贵:CPU、内存和带宽。即使在2018年,在世界上许多地方,相对于收入水平,这些东西仍然很昂贵。仅因为您想要完整大小和缩略图像,并不意味着每个人都需要。


0

你可以像这样从你的实际图像生成缩略图:

final int thumbSize = 64;

Bitmap thumbBitmap= ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(actualImagePath), 
                    thumbSize, thumbSize);

如果可能的话,我想避免自己生成缩略图,而是使用相机创建的缩略图。 - Tobias Uhmann
1
实际上,在onActivityResult中,Bitmap photo = (Bitmap) data.getExtras().get("data")并不会获取拍摄的原始图像,而是获取拍摄图像的缩略图。 - Aj 27
2
是的,不幸的是,如果我不提供一个URI来保存我的图像,缩略图位图只会被捆绑在一起。但是,这样我就无法访问我的全尺寸图像。这让我疯狂!谁会想拍照只得到缩略图呢?为什么API设计者不返回图像URI呢?... - Tobias Uhmann

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