【问题标题】:How Can I Get Thumbnails For Picasa Images Selected From The Gallery?如何获取从图库中选择的 Picasa 图像的缩略图?
【发布时间】:2011-10-15 15:19:10
【问题描述】:

我正在开发一个应用程序,用户可以在该应用程序中选择文件,可以是来自相机的新图像、来自图库的图像,也可以是普通的旧文件。然后它会显示一个图标和所选项目的名称。我有一个例外。图库应用程序集成了 picasaweb 图片。如果用户从 picasa 相册中选择了一张图片,我无法获得它的缩略图。

我正在使用 MediaStore.Images.Thumbnails.getThumbnail() 方法,它适用于图库中的其他图像,但对于 picasaweb 文件,无论我尝试什么“类型”的缩略图,我都会得到得到(虽然 MICRO 是我所追求的):

ERROR/MiniThumbFile(2051): 读取魔法时出现异常,id = 5634890756050069570,磁盘已满还是以只读方式挂载?班级 java.lang.IllegalArgumentException

我注意到为所选文件提供的 URI 不同。本地图像文件如下所示:

content://media/external/images/media/6912

picasaweb 网址看起来像:

content://com.android.gallery3d.provider/picasa/item/5634890756050069570

我尝试使用查询来获取原始 THUMB_DATA,使用 Thumbnails.queryMiniThumbnails(),在投影数组中使用 Thumbnails.THUMB_DATA,但出现“没有这样的列”错误。

还有其他更好的获取缩略图的方法吗?当我尝试访问完整的图像数据时会遇到同样的问题吗?

【问题讨论】:

  • 我可以轻松确定 URI 中的差异,如果图像来自 picasa,则显示 Toast,但这并不完全理想。更好但仍然不完美的方法是从 ACTION_PICK 中排除 picasa 图像,但我也不知道该怎么做。
  • 我在 Android 错误跟踪器中为此创建了一个问题。 code.google.com/p/android/issues/…

标签: android android-gallery android-image


【解决方案1】:

我发现在我的 Galaxy Nexus 上,Picassa 的图像存储在 /sdcard/Android/data/com.google.android.apps.plus/cache 目录下的子目录之一中。当内容提供者是 com.google.android.gallery3d.provider 时,URL 中“item”后面的数字包含图像的名称(在上面的示例中为“5634890756050069570”)。此数据对应于 /sdcard/Android/data/com.google.android.apps.plus/cache 下的子目录之一中的文件,扩展名为“.screen”。如果您要使用 DDMS 从您的手机(在您的情况下为 5634890756050069570.screen)复制此图像并使用扩展名“.jpeg”重命名它,您可以打开它并在您的计算机上查看它。

下面的 onActivityResult 方法会检查这个内容提供者是否被返回,然后会递归地在 /sdcard/Android/data/com.google.android.apps.plus/cache 目录中搜索文件。私有成员变量fileSearchPathResults由递归搜索方法walkDirectoryRecursivelySearchingForFile()填充。

private String fileSearchPathResult = null;

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            String filePath = null;

            // This code is required to get the image path on content providers
            // on API > 10 where the image is from a picassa web album, since Google changed
            // the content provider in versions with API > 10
            if (selectedImage.toString().contains("com.google.android.gallery3d.provider")) {
                StringBuilder contentProviderPath = new StringBuilder(selectedImage.toString());
                int beginningIndex = contentProviderPath.lastIndexOf("/");
                String fileNameWithoutExt = contentProviderPath.subSequence(beginningIndex + 1,
                        contentProviderPath.length()).toString();
                Log.i(TAG, fileNameWithoutExt);
                try {
                    File path = new File("/sdcard/Android/data/com.google.android.apps.plus/cache");
                    if (path.exists() && path.isDirectory()) {
                        fileSearchPathResult = null;
                        walkDirectoryRecursivelySearchingForFile(fileNameWithoutExt, path);
                        if (fileSearchPathResult != null) {
                            filePath = fileSearchPathResult;
                        }
                    }
                } catch (Exception e) {
                    Log.i(TAG, "Picassa gallery content provider directory not found.");
                }
            }
    }


    public void walkDirectoryRecursivelySearchingForFile(String fileName, File dir) {
        String pattern = fileName;

        File listFile[] = dir.listFiles();
        if (listFile != null) {
            for (int i = 0; i < listFile.length; i++) {
                if (listFile[i].isDirectory()) {
                    walkDirectoryRecursivelySearchingForFile(fileName, listFile[i]);
                } else {
                    if (listFile[i].getName().contains(pattern)) {
                        fileSearchPathResult = listFile[i].getPath();
                    }
                }
            }
        }
    }

通过filePath,您可以使用以下代码创建图像的位图:

        Bitmap sourceImageBitmap = BitmapFactory.decodeFile(filePath);

【讨论】:

  • 我在 Galaxy Nexus 上查找 Picasa 文件时遇到了问题,这个解决方案对我有用。谢谢你。但是对谷歌字符串的引用似乎有点脆弱。它可以在其他手机上使用吗?有没有更通用的解决方案,不依赖于这些特定的硬编码字符串??
  • 这行得通,但问题是这个缓冲区可以在不同的区域。 AFAIK,这个新的内容提供商是由 Google 添加的,旨在为您的 Picasa 图片提供更高的安全性。读取 URL 时,您的应用会出现一次性使用异常。然后下一次,如果您再次使用该 URL,您的应用程序将会崩溃。如果您需要更多地使用图像,则必须将自己的副本复制到自己的缓存区域中(尽管如果您的区域是公开的,这会带来更多的安全漏洞)。
【解决方案2】:

ACTIVITYRESULT_CHOOSEPICTURE 是调用 startActivity(intent, requestCode); 时使用的 int;

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if(requestCode == ACTIVITYRESULT_CHOOSEPICTURE) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 4;
    final InputStream is = context.getContentResolver().openInputStream(intent.getData());
    final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
    is.close();
  }
}

该代码将加载整个图像。您可以将样本大小调整为合理的值以获得缩略图大小的图像。

【讨论】:

  • 显然核心问题是我要返回com.android.gallery3d.provider,它应该是com.google.android.gallery3d.provider。由于某种原因,这似乎在摩托罗拉 xoom 上被破坏了。
猜你喜欢
  • 2012-05-31
  • 2013-05-31
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
相关资源
最近更新 更多