代码之家  ›  专栏  ›  技术社区  ›  chakrit Dutchie432

有没有一种方法可以从android中的文件中加载并部分绘制位图?

  •  8
  • chakrit Dutchie432  · 技术社区  · 14 年前

    假设我在磁盘上有一个较大的位图(即不适合大多数手机的内存)。我只想在屏幕上以不按比例(即 inSampleSize == 1 )

    有没有办法只加载/绘制我想要的部分 Rect 指定区域而不加载整个位图内容?

    4 回复  |  直到 10 年前
        1
  •  9
  •   chakrit Dutchie432    12 年前

    我非常确信这是可能的,因为您可以将一个非常大的位图文件加载到 ImageView 没有问题,所以必须有某种内置的方法来处理大位图…经过几次尝试,我找到了一个解决方案:

    不是加载整个位图并自己手动绘制,而是将其作为 Drawable 相反:

    InputStream mapInput = getResources().openRawResource(
            R.drawable.transit_map);
    _map = Drawable.createFromStream(mapInput, "transit_map");
    
    _map.setBounds(0, 0, _mapDimension.width(), _mapDimension.height());
    

    我正在使用资源文件,但由于您可以使用 Drawable.createFromStream 从任意 InputStream ,它应该与任意位图一起使用。

    然后,使用 Drawable.draw 方法将其绘制到所需画布上,如下所示:

    int left = -(int) contentOffset.x;
    int top = -(int) contentOffset.y;
    int right = (int) (zoom * _mapDimension.width() - contentOffset.x);
    int bottom = (int) (zoom * _mapDimension.height() - contentOffset.y);
    
    _map.setBounds(left, top, right, bottom);
    _map.draw(canvas);
    

    与上面的情况一样,您也可以通过操作Drawable的边界来缩放和转换位图,并且只有位图的相关部分将被加载并绘制到 Canvas .

    结果是只从一个200kb的位图文件中得到一个可缩小的视图。我还用一个22mbpng文件测试了这个,它仍然可以在没有任何 OutOfMemoryError 包括屏幕方向改变时。

        2
  •  4
  •   Vadim    12 年前

    现在它非常相关: BitmapRegionDecoder .

    注:自Android SDK 10起提供

        3
  •  3
  •   suckgamony    10 年前

    使用 RapidDecoder .

    import rapid.decoder.BitmapDecoder;
    
    Rect bounds = new Rect(10, 20, 30, 40);
    Bitmap bitmap = BitmapDecoder.from("your-file.png")
                                 .region(bounds)
                                 .decode();
    imageView.setImageBitmap(bitmap);
    

    它支持Android 2.2(API级别8)。

        4
  •  1
  •   Marcelo Cantos    14 年前

    一般来说,这是不可能的,尤其是因为大多数图像格式都是压缩的,所以在提取未压缩的表单之前,您甚至不知道要读取哪个字节。

    将您的图像拆分成小图块,然后只加载需要覆盖运行时要显示区域的图块。为了避免不稳定的滚动,您可能还需要在后台线程上预加载刚刚看不到的图块(与可见图块边界的图块)。