获取图像输入流的大小

5

我需要获取输入流中图像的高度和宽度。以下是我的操作:

private Boolean testSize(InputStream inputStream){
        BitmapFactory.Options Bitmp_Options = new BitmapFactory.Options();
        Bitmp_Options.inJustDecodeBounds = true;
        BitmapFactory.decodeResourceStream(getResources(), new TypedValue(), inputStream, new Rect(), Bitmp_Options);
        int currentImageHeight = Bitmp_Options.outHeight;
        int currentImageWidth = Bitmp_Options.outWidth;
        Bitmp_Options.inJustDecodeBounds = false;
    if(currentImageHeight < 200 || currentImageWidth < 200){
        Object obj = map.remove(pageCounter);
        Log.i("Page recycled", obj.toString());
        return true;
    }
    return false;}

跳转到问题点:

即使在下面的第二种方法计算后将其强制为false,它还是会改变BitmapFactory.Options。

private Bitmap getBitmap(InputStream InpStream){
    Bitmap originalBitmap = BitmapFactory.decodeStream(InpStream);//Null.
    return originalBitmap;
}

现在我的问题是,有没有其他方法从输入流中获取图像的大小和宽度?我真的需要帮助,非常感激任何帮助。
                ZipInputStream zip = null;
                zip = new ZipInputStream(new FileInputStream(getFileLocation()));
                for(ZipEntry zip_e = zip.getNextEntry(); zip_e != null ; zip_e = zip.getNextEntry()){
                    if(zip_e.isDirectory()) {
                        continue;
                    }
                    String file_zip = zip_e.getName();
                    String comparison = map.get(pageCounter).getHref();
                    if(file_zip.endsWith(comparison)){
                        SpannableString Spanable_String = new SpannableString("abc");
                        if(testSize(zip)){
                            map.remove(pageCounter);
                            return false;
                        }
                        Bitmap bitmap = getBitmap(zip);
                        if(bitmap == null){
                            map.remove(pageCounter);
                            return false;
                        }
                        image_page.put(zip_e.getName(), zip);
                        Drawable drawable_image = new FastBitmapDrawable(bitmap);
                        drawable_image.setBounds(0,0,drawable_image.getIntrinsicWidth(), drawable_image.getIntrinsicHeight());
                        ImageSpan imageSpan = new ImageSpan(drawable_image, ImageSpan.ALIGN_BASELINE);
                        Spanable_String.setSpan(imageSpan, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        tv.setText(Spanable_String);
                        return false;
                    }
                }   

你是说将Bitmp_Options.inJustDecodeBounds设置为true会在后续调用BitmapFactory.decodeStream()时保留吗? - nEx.Software
是的,我说的是真的。由于某些原因,如果没有testSize方法,它将正常工作,输入流和源相同。我发现这是非常奇怪的行为,所以我不得不将其报告为错误。 - Donkey King
是的,我可以肯定地说这绝对不是预期的行为。我不确定是否有其他(好的)方法从输入流中获取图像大小。 - nEx.Software
你能贴出调用这些函数的代码吗? - Geobits
我会做,但由于公司的保密原因,我不能透露大部分内容。 - Donkey King
1个回答

11
主要问题不在于 `BitmapFactory.Options`,而是在于 `InputStream`。由于流是顺序读取的,因此当你仅为了获取图像大小而读取流以解码图像时,指针在流中移动。接下来,当你再次调用 `decode` 来实际解码位图时,流指针不再位于位图开头,因此你会得到 `null`,因为无法解码部分流。
你需要重置流。根据流的类型,你可能可以在其上使用 `mark` 和 `reset` 方法。基本上,你需要像这样做:
private Boolean testSize(InputStream inputStream) {
    BitmapFactory.Options Bitmp_Options = new BitmapFactory.Options();
    Bitmp_Options.inJustDecodeBounds = true;

    inputStream.mark(inputSteram.available());

    BitmapFactory.decodeResourceStream(getResources(), new TypedValue(), inputStream, new Rect(), Bitmp_Options);

    inputSteram.reset();

    int currentImageHeight = Bitmp_Options.outHeight;
    int currentImageWidth = Bitmp_Options.outWidth;
    Bitmp_Options.inJustDecodeBounds = false;

    if(currentImageHeight < 200 || currentImageWidth < 200){
        Object obj = map.remove(pageCounter);
        Log.i("Page recycled", obj.toString());
        return true;
    }

    return false;
}

您可以通过调用流的markSupported方法来检查您的InputStream是否支持此操作。如果返回值为true,则可以使用上述技术。如果返回值为false,则上述方法将无法正常工作,并且您实际上需要在解码完整位图之前关闭并重新打开流。


谢谢。你帮我省了很多时间去尝试解决这个问题。再次感谢你告诉我它是顺序的。 - Donkey King
啊,我没意识到你是在同一个输入流实例上调用它。这很有道理。 - nEx.Software
好的回答!不幸的是,在我的情况下,markSupported被设置为false :( - Zhar
@zhar 如果这些InputStreams(不支持mark/reset)可以简单地包装成BufferedInputStream。 - Sachin Gupta

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