【问题标题】:Load an image from assets folder从 assets 文件夹加载图像
【发布时间】:2012-07-28 21:45:03
【问题描述】:

我正在尝试从asset 文件夹加载图像,然后将其设置为ImageView。我知道如果我为此使用R.id.* 会更好,但前提是我不知道图像的ID。基本上,我试图通过其文件名动态加载图像。

例如,我在database 中随机检索一个元素,比如说一个'cow',现在我的应用程序要做的是显示一个'cow'的图像 通过ImageView。对于database 中的所有元素也是如此。 (假设是,对于每个元素都有一个等效的图像)

提前致谢。

编辑

忘记问题了,如何从asset 文件夹加载图片?

【问题讨论】:

    标签: android image assets


    【解决方案1】:

    查看此code。在本教程中,您可以了解如何从资产文件夹加载图像。

    //加载图片

    try 
    {
        // get input stream
        InputStream ims = getAssets().open("avatar.jpg");
        // load image as Drawable
        Drawable d = Drawable.createFromStream(ims, null);
        // set image to ImageView
        mImage.setImageDrawable(d);
      ims .close();
    }
    catch(IOException ex) 
    {
        return;
    }
    

    【讨论】:

    • 使用后不应该关闭流吗?
    • 我认为最好的方法是try-with-resources。这将确保流始终关闭而无需全部写出
    • @NicolasTyler 当执行离开当前范围并且没有更多对该对象的引用时,InputStream 对象会自动销毁。
    • @gregn3 据我所知,当流超出范围时,垃圾收集器不会关闭流。正如 Elliotte Rusty Harold 的 Java I/O books.google.co.za/… 中所述
    • @NicolasTyler 我无法访问付费链接,但我找到了另一个SO discussion:So yes, you should close it yourself if you want to write clean code. The GC will close it eventually, if it gets around to calling the finalize() method (shown below) on the stream, but you shouldn't rely on that. Always close your resources, that's the only way to be sure.
    【解决方案2】:

    你来了,

      public Bitmap getBitmapFromAssets(String fileName) throws IOException {
        AssetManager assetManager = getAssets();
    
        InputStream istr = assetManager.open(fileName);
        Bitmap bitmap = BitmapFactory.decodeStream(istr);
        istr.close();
    
        return bitmap;
    }
    

    【讨论】:

    • 别忘了:istr.close()
    【解决方案3】:

    如果你知道代码中的文件名,调用它就不会有问题:

    ImageView iw= (ImageView)findViewById(R.id.imageView1);  
    int resID = getResources().getIdentifier(drawableName, "drawable",  getPackageName());
    iw.setImageResource(resID);
    

    您的文件名将与 drawableName 同名,因此您不必处理资产。

    【讨论】:

    • 不,您不必包含扩展名,只要它是有效的图像扩展名并且图像是可绘制的。
    • 差别不大。我想说的是,由于索引和避免在编译时出现错误命名问题,使用资源使它更快更实用。此外,大多数 api 使用资源 ID。除了索引之外,Drawables 还为您提供了与屏幕密度碎片作斗争的选项,并且资产不应依赖于密度。在较小的屏幕和/或较低规格的手机(RAM、CPU)上显示大图片可能会导致真正的麻烦并影响可用性和应用程序的响应性。资产对我来说更偶然。
    • 它真的适用于 assets 文件夹吗?它肯定适用于 res 文件夹,但这是我见过的唯一一个说它也可以在资产上工作的参考资料。它对我不起作用 - 有人验证过吗?
    • 它只在drawableName中没有扩展名的情况下工作。
    • @uval 对,为什么这是选择的答案?问题是关于从“资产”文件夹加载。我猜OP并不真正关心文件的实际位置。有关使用“assets”文件夹的示例,请参阅 osayilgan 和 Chirag Raval 的答案。
    【解决方案4】:

    其中一些答案可能会回答这个问题,但我从不喜欢其中任何一个,所以我最终写了这个,这是我对社区的帮助。

    从资产中获取Bitmap

    public Bitmap loadBitmapFromAssets(Context context, String path)
    {
        InputStream stream = null;
        try
        {
            stream = context.getAssets().open(path);
            return BitmapFactory.decodeStream(stream);
        }
        catch (Exception ignored) {} finally
        {
            try
            {
                if(stream != null)
                {
                    stream.close();
                }
            } catch (Exception ignored) {}
        }
        return null;
    }
    

    从资产中获取Drawable

    public Drawable loadDrawableFromAssets(Context context, String path)
    {
        InputStream stream = null;
        try
        {
            stream = context.getAssets().open(path);
            return Drawable.createFromStream(stream, null);
        }
        catch (Exception ignored) {} finally
        {
            try
            {
                if(stream != null)
                {
                    stream.close();
                }
            } catch (Exception ignored) {}
        }
        return null;
    }
    

    【讨论】:

      【解决方案5】:

      根据 Android 开发人员文档,使用 位图 加载会降低应用程序的性能。这里是 a link!所以 doc 建议使用 Glide 库。

      如果您想从 assets 文件夹中加载图片,那么使用 Glide 库会帮助您轻松很多。

      只需从 https://github.com/bumptech/glide 向 build.gradle (Module:app) 添加依赖项

       dependencies {
        implementation 'com.github.bumptech.glide:glide:4.9.0'
        annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
      }
      

      示例:

      // For a simple view:
      @Override public void onCreate(Bundle savedInstanceState) {
        ...
        ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
      
        Glide.with(this).load("file:///android_asset/img/fruit/cherries.jpg").into(imageView);
      }
      

      如果上述方法不起作用:将 this 对象替换为下面代码中的 view 对象(仅当您在代码中应用了如下 Inflate 方法时)。

       LayoutInflater mInflater =  LayoutInflater.from(mContext);
              view  = mInflater.inflate(R.layout.book,parent,false);
      

      【讨论】:

      • 这里资产文件夹的Url表示为:file:///android_asset/,img是资产内的文件夹(Assets/img)跨度>
      【解决方案6】:
      public static Bitmap getImageFromAssetsFile(Context mContext, String fileName) {
              Bitmap image = null;
              AssetManager am = mContext.getResources().getAssets();
              try {
                  InputStream is = am.open(fileName);
                  image = BitmapFactory.decodeStream(is);
                  is.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return image;
          }
      

      【讨论】:

        【解决方案7】:

        这在我的用例中有效:

        AssetManager assetManager = getAssets();
        ImageView imageView = (ImageView) findViewById(R.id.imageView);
        try (
                //declaration of inputStream in try-with-resources statement will automatically close inputStream
                // ==> no explicit inputStream.close() in additional block finally {...} necessary
                InputStream inputStream = assetManager.open("products/product001.jpg")
        ) {
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            imageView.setImageBitmap(bitmap);
        } catch (IOException ex) {
            //ignored
        }
        

        (另见https://javarevisited.blogspot.com/2014/10/right-way-to-close-inputstream-file-resource-in-java.html

        【讨论】:

          【解决方案8】:
          WebView web = (WebView) findViewById(R.id.webView);
          web.loadUrl("file:///android_asset/pract_recommend_section1_pic2.png");
          web.getSettings().setBuiltInZoomControls(true);
          

          【讨论】:

          • TS 询问 ImageView,而不是 WebView 容器。嵌入网络浏览器以显示图像的开销非常巨大
          • @ruX 使用 WebView 不应该是开销。您无需嵌入 Web 浏览器即可使用 WebView。此外,如果您想为图像或文本添加缩放/平移功能,WebView 是一个不错的选择。
          • @njs 证明? WebView 是嵌入式网络浏览器。
          猜你喜欢
          • 1970-01-01
          • 2015-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-20
          相关资源
          最近更新 更多