如何在Android中将没有文件扩展名的图像从URL加载到ImageView

时间:2019-12-02 22:50:15

标签: java android imageview android-imageview networkimageview

我有这个URL https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3。在Blob存储中的该URL地址上有一个PNG图像,可访问,而REST API上没有任何标头(通常)。通常会通过网络浏览器(例如Chrome)打开。但是,将其在Java Android应用程序中加载到ImageView的任何尝试都将失败。我尝试了Volley,Picasso,Glide,Retrofit和手动方法。我包括一些我尝试过的代码。我最接近它的位置会产生此错误消息D/skia: --- Failed to create image decoder with message 'unimplemented'。问题在于内容类型为image/png,但是我无法在任何地方指定它,并且由于URL不包含任何扩展名,因此解码起来非常麻烦。如果您通过API客户端(例如Postman)运行GET请求,它将返回一个PNG文件。

此URL https://speakyfox-api-qa.herokuapp.com/api/v1/files/7b6f4529-256f-43a4-ac45-8613d96c505e存在相同的问题。它包含一个简短的MP3文件,我希望将其放入MediaPlayer对象中。

在大声疾呼它是一个衬纸之前,不胜感激,您尝试将图像显示在ImageView中。问题是该链接用于html,而不是直接指向数据。

// Getting reference to ImageView object
ImageView imageView = (ImageView)findViewById(R.id.imageView);

// Loading using Picasso
Picasso.get().load("https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3").into(imageView);

// Loading using Glide
Glide.with(MainActivity.this).load("https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3").into(imageView);

// Loading using HttpURLConnection/InputStream/Bitmap executed in Async task
java.net.URL url = new java.net.URL("https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
imageView.setImageBitmap(myBitmap);

// Using Volley [ImageRequest]
RequestQueue queue = Volley.newRequestQueue(this);
ImageRequest request = new ImageRequest("https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3", new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap response) {
            imageView.setImageBitmap(response);
        }
    }, 0, 0, Bitmap.Config.RGB_565, null){
        /** Passing some request headers* */
        @Override
        public Map getHeaders() {
            HashMap headers = new HashMap();
            headers.put("Content-type","image/png");
            return headers;
        }
queue.add(request);

// Using Volley [NetworkImageView]
NetworkImageView networkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
RequestQueue mRequestQueue = Volley.newRequestQueue(this);
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
        private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
        public void putBitmap(String url, Bitmap bitmap) {
            mCache.put(url, bitmap);
        }
        public Bitmap getBitmap(String url) {
            return mCache.get(url);
        }
    });
networkImageView.setImageUrl("https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3", mImageLoader);

// Using Volley [StringRequest]
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest getRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            byte[] decodedString = Base64.decode(response, Base64.URL_SAFE);
            Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
            imageView.setImageBitmap(decodedByte);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {}
    }) {
        /** Passing some request headers* */
        @Override
        public Map getHeaders() {
            HashMap headers = new HashMap();
            headers.put("Content-type","image/png");
            return headers;
        }
    };
queue.add(getRequest);

但是,此代码有效(但是很丑)...

WebView webView = findViewById(R.id.webview);
webView.loadUrl("https://speakyfox-api-qa.herokuapp.com/api/v1/files/7b6f4529-256f-43a4-ac45-8613d96c505e");

不过,我需要使其与ImageView一起使用。

编辑:我尝试使用此代码通过OkHttp下载文件

Request request = new Request.Builder().url(url).addHeader("Content-Type", "image/png").build();

OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
call.enqueue(new Callback() {
    public void onResponse(Call call, Response response) throws IOException {
        Log.e("",response.body().string());
    }
    public void onFailure(Call call, IOException e) {}
});

响应正文为

  

{“ code”:{“ group”:3,“ internalCode”:200,“ statusCode”:200},“ data”:{“ type”:“ Image”,“ imageType”:“ Whole”,“名称”:“ I and you.png”,“大小”:67710,“ contentType”:“ image / png”,“ id”:“ db296f16-3283-4ba5-a32b-52b9feb64764”,“修改”:“ 2019- 10-16T20:44:20.468276Z“}}

3 个答案:

答案 0 :(得分:0)

该图片的图像为PNG大小为1.6MB,大小为5610 x 3963像素。特别注意:

  • 目前没有主流Android设备具有该分辨率(或类似分辨率)的屏幕

  • 该映像将占用约85MB的堆空间

您的问题很可能是图像太大,无法为解码图像分配85MB的内存块。要么:

答案 1 :(得分:0)

  
    

问题在于该链接用于html,而不是直接指向数据。

  

的确。而且ImageView不会显示html。

所以你知道原因。

这是第一个链接的html:

<html><head><meta name="viewport" content="width=device-width; height=device-height;"><link rel="stylesheet" href="resource://content-accessible/ImageDocument.css"><link rel="stylesheet" href="resource://content-accessible/TopLevelImageDocument.css"><link rel="stylesheet" href="chrome://global/skin/media/TopLevelImageDocument.css"><title>be28dcec-4912-4f58-8cb8-12b9b2948fc3 (PNG-afbeelding, 5610&nbsp;×&nbsp;3963 pixels) - Geschaald (13%)</title></head><body><img src="https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3" alt="https://speakyfox-api-qa.herokuapp.com/api/v1/files/be28dcec-4912-4f58-8cb8-12b9b2948fc3" class="transparent shrinkToFit" width="746" height="527"></body></html>

您最好使用WebView。

答案 2 :(得分:0)

我找到了解决方案。我复制了所有在邮递员中自动添加的请求标头。我只剩下两个。标头使服务器不返回html,而是返回图像本身。我无法使其适用于上面指定的大多数方法,但是其中一种方法就可以了。


RequestQueue queue = Volley.newRequestQueue(this);
ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() {
    @Override
    public void onResponse(Bitmap response) {
        imageView.setImageBitmap(response);
    }
}, 0, 0, ImageView.ScaleType.CENTER_INSIDE, null, null){
    /** Passing some request headers* */
    @Override
    public Map getHeaders() {
        HashMap headers = new HashMap();
        headers.put("Accept","*/*");
        headers.put("Cache-Control","no-cache");
        return headers;
    }
};
queue.add(request);

还有另一个构造函数(没有ImageView.ScaleType.CENTER_INSIDE),但已被标记为已弃用。 即使使用较大的图像(如指定URL中的图像),它也可以很好地工作(尽管加载需要一秒钟)。唯一的问题是OkHttp发出的警告说连接正在泄漏。