【问题标题】:Load images in Html.fromHtml in textview (http url images, Base64 url images)在 textview 中加载 Html.fromHtml 中的图像(http url 图像,Base64 url​​ 图像)
【发布时间】:2014-05-21 03:02:18
【问题描述】:

我有一个文本视图,我在其中显示论坛帖子的内容,该内容是使用 rte 在网站上输入的,内容涉及图像,包括 web url 类型和Base64.. Html 的默认实现。 fromHtml 用小方块替换所有img 标签..

我在 SO 上寻找使用 Html.fromHtml 方法从 url 加载图像的解决方案,结果有办法做到这一点,我们可以将 ImageGetter 传递给函数。我发现 this 很棒的答案,它实现了 url获取部分,但是当内容具有Base64 的图像时,这会失败并使应用程序崩溃..

我寻找了一种为Base64 src 创建图像的方法,但没有一个解决方案有效,如果有人实施了整个解决方案,那就太好了。如果有人只有Base64 部分,请提供我会整合两者..

【问题讨论】:

  • 阅读我的问题,我已经使用了这个答案。我要求解决方案失败并导致应用程序崩溃的情况。我什至在我的问题中强调了这部分......似乎您已删除您的评论..
  • 查看这两个链接:Use webview to show base64 imagesthis one
  • @jitainsharma 我没有使用 webview,也没有回答你在上一条评论中提供的答案的那个人,我已经在使用它了..请阅读上下文.. thnx 寻求帮助无论如何..:)

标签: android


【解决方案1】:

在花了几个小时之后,我终于找到了Base64 图像的解决方案。我在这里发布了完整的解决方案。

我要再次感谢https://stackoverflow.com/a/15617341/1114536 的基本答案..

原来我用作参考的答案只是this asnwer..的副本。

URLDrawable.java

import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

public class URLDrawable extends BitmapDrawable {
    // the drawable that you need to set, you could set the initial drawing
    // with the loading image if you need to
    protected Drawable drawable;

    @Override
    public void draw(Canvas canvas) {
        // override the draw to facilitate refresh function later
        if(drawable != null) {
            drawable.draw(canvas);
        }
    }
}

URLImageParser.java

import java.io.InputStream;
import java.net.URL;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.text.Html.ImageGetter;
import android.util.Base64;
import android.view.View;

public class URLImageParser implements ImageGetter {
    Context context;
    View container;

    public URLImageParser(View container, Context context) {
        this.context = context;
        this.container = container;
    }

    public Drawable getDrawable(String source) {   
        if(source.matches("data:image.*base64.*")) {
            String base_64_source = source.replaceAll("data:image.*base64", "");
            byte[] data = Base64.decode(base_64_source, Base64.DEFAULT);
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                
            Drawable image = new BitmapDrawable(context.getResources(), bitmap);
            image.setBounds(0, 0, 0 + image.getIntrinsicWidth(), 0 + image.getIntrinsicHeight()); 
            return image;
        } else {
            URLDrawable urlDrawable = new URLDrawable();
            ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(urlDrawable);
            asyncTask.execute(source);          
            return urlDrawable; //return reference to URLDrawable where We will change with actual image from the src tag
        }        
    }

    public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
        URLDrawable urlDrawable;

        public ImageGetterAsyncTask(URLDrawable d) {
            this.urlDrawable = d;
        }

        @Override
        protected Drawable doInBackground(String... params) {
            String source = params[0];
            return fetchDrawable(source);
        }

        @Override
        protected void onPostExecute(Drawable result) {         
            urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0 + result.getIntrinsicHeight()); //set the correct bound according to the result from HTTP call            
            urlDrawable.drawable = result; //change the reference of the current drawable to the result from the HTTP call          
            URLImageParser.this.container.invalidate(); //redraw the image by invalidating the container
        }

        public Drawable fetchDrawable(String urlString) {
            try {
                InputStream is = (InputStream) new URL(urlString).getContent();
                Drawable drawable = Drawable.createFromStream(is, "src");
                drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0 + drawable.getIntrinsicHeight()); 
                return drawable;
            } catch (Exception e) {
                return null;
            } 
        }
    }
}

用法:

TextView comment_content_container = ((TextView)findViewById(R.id.comment_content));
comment_content_container.setText(Html.fromHtml(comment.content, new URLImageParser(comment_content_container, this), null));

如果有人知道Base64 的更好正则表达式,请回复我会更新答案..

【讨论】:

  • 这个真的很好。第一次工作,开箱即用。干得好。
  • URLImageParser$ImageGetterAsyncTask.onPostExecute(URLImageParser.java:56) 它崩溃了
  • 我试过了,效果很好,但是我的图像太小了(大约 5 x 5 像素,通常应该是 50 x 50 像素)。
  • 优秀的答案。拯救了我的一天。
  • 我遇到了这个问题 ::: The inline style not applied , like style=color:red;"
【解决方案2】:

作为 Rajat Singhal 回答的补充(抱歉,我没有足够的声誉来发表评论):

我的可绘制对象的尺寸错误(它更小),因为可绘制对象考虑了屏幕密度。为了保留原始图像大小,我最终在 fetchDrawable 方法中这样做了:

public Drawable fetchDrawable(String urlString) {
        try {
            InputStream is = (InputStream) new URL(urlString).getContent();
            Bitmap bmp = BitmapFactory.decodeStream(is);
            Drawable drawable = new BitmapDrawable (context.getResources(), bmp);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            return drawable;
        } catch (Exception e) {
            return null;
        }
    }

【讨论】:

  • 这也很有效,但我的图像只比极小的尺寸略大。它至少是可读的,但它比我使用 WebView 时要小。我希望它更大。此外,它与图像正上方的一行文本部分重叠,尽管在实施 Rajat 的答案时图像超小时它没有重叠。
【解决方案3】:

我只是想从 Rajat 的回答中修复图像的大小,图像将占据 textview 的整个宽度并保持高度的纵横比。这是我的更新:

    public Drawable getDrawable(String source)
    {
        if(source.matches("data:image.*base64.*"))
        {
            String base_64_source = source.replaceAll("data:image.*base64", "");
            byte[] data = Base64.decode(base_64_source, Base64.DEFAULT);
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            Drawable image = new BitmapDrawable(context.getResources(), bitmap);

            float ratio = container.getWidth() / image.getIntrinsicWidth();
            int width = container.getWidth();
            int height = Math.round(image.getIntrinsicHeight() * ratio);

            image.setBounds(0, 0, width, height);
            return image;
        }
        else
        {
            ....
        }
    }

    public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable>
    {
        ....

        @Override
        protected void onPostExecute(Drawable result)
        {
            if(result != null)
            {
                float ratio = container.getWidth() / result.getIntrinsicWidth();
                int width = container.getWidth();
                int height = Math.round(result.getIntrinsicHeight() * ratio);
                urlDrawable.setBounds(0, 0, width, height); //set the correct bound according to the result from HTTP call
                urlDrawable.drawable = result; //change the reference of the current drawable to the result from the HTTP call
                URLImageParser.this.container.invalidate(); //redraw the image by invalidating the container
            }
        }

        public Drawable fetchDrawable(String urlString)
        {
            try
            {
                InputStream is = (InputStream) new URL(urlString).getContent();
                Bitmap bmp = BitmapFactory.decodeStream(is);
                Drawable drawable = new BitmapDrawable (context.getResources(), bmp);

                float ratio = container.getWidth() / drawable.getIntrinsicWidth();
                int width = container.getWidth();
                int height = Math.round(drawable.getIntrinsicHeight() * ratio);

                drawable.setBounds(0, 0, width, height);
                return drawable;
            }
            catch (Exception e)
            {
                return null;
            }
        }

    }
}

但是,Ranjat 的解决方案仅显示 1 张图片。如果您想显示多张图片,则需要在 SpannableStringBuilder 中使用 ImageSpan,如果您需要示例,请在评论中告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2018-01-10
    相关资源
    最近更新 更多