I have a textview in which I am showing content of a forum post, which is entered on website using rte, the content involves images, both of type web url and of type Base64
.. The default implementation of Html.fromHtml replaces all the img
tags with small square..
I looked on SO for solution to load images from url using Html.fromHtml method, turns out there is way to do it, we can pass a ImageGetter to the function.. I found this awesome answer which implements the url fetch part, but this fails and crashes the app when the content has an image of Base64
..
I looked a way to create images for Base64
src but none of the solutions are working, If anyone has implemented the whole solution its great. If someone has just the Base64
part please provide that I'll integrate both..
Finally after spending hours on this I have found the solution to the Base64
image.. I am posting the complete solution here..
I would once again like to thank https://stackoverflow.com/a/15617341/1114536 for the base answer..
Turns out the answer I was using as reference was just copy of 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;
}
}
}
}
Usage:
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));
If anyone knows better regex for the Base64
, please reply I will update the answer..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With