Load Images In Html.fromhtml In Textview (http Url Images, Base64 Url Images)
Solution 1:
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;
publicclassURLDrawableextendsBitmapDrawable {
// the drawable that you need to set, you could set the initial drawing// with the loading image if you need toprotected Drawable drawable;
@Overridepublicvoiddraw(Canvas canvas) {
// override the draw to facilitate refresh function laterif(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;
publicclassURLImageParserimplementsImageGetter {
Context context;
View container;
publicURLImageParser(View container, Context context) {
this.context = context;
this.container = container;
}
public Drawable getDrawable(String source) {
if(source.matches("data:image.*base64.*")) {
Stringbase_64_source= source.replaceAll("data:image.*base64", "");
byte[] data = Base64.decode(base_64_source, Base64.DEFAULT);
Bitmapbitmap= BitmapFactory.decodeByteArray(data, 0, data.length);
Drawableimage=newBitmapDrawable(context.getResources(), bitmap);
image.setBounds(0, 0, 0 + image.getIntrinsicWidth(), 0 + image.getIntrinsicHeight());
return image;
} else {
URLDrawableurlDrawable=newURLDrawable();
ImageGetterAsyncTaskasyncTask=newImageGetterAsyncTask(urlDrawable);
asyncTask.execute(source);
return urlDrawable; //return reference to URLDrawable where We will change with actual image from the src tag
}
}
publicclassImageGetterAsyncTaskextendsAsyncTask<String, Void, Drawable> {
URLDrawable urlDrawable;
publicImageGetterAsyncTask(URLDrawable d) {
this.urlDrawable = d;
}
@Overrideprotected Drawable doInBackground(String... params) {
Stringsource= params[0];
return fetchDrawable(source);
}
@OverrideprotectedvoidonPostExecute(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 {
InputStreamis= (InputStream) newURL(urlString).getContent();
Drawabledrawable= Drawable.createFromStream(is, "src");
drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0 + drawable.getIntrinsicHeight());
return drawable;
} catch (Exception e) {
returnnull;
}
}
}
}
Usage:
TextViewcomment_content_container= ((TextView)findViewById(R.id.comment_content));
comment_content_container.setText(Html.fromHtml(comment.content, newURLImageParser(comment_content_container, this), null));
If anyone knows better regex for the Base64
, please reply I will update the answer..
Solution 2:
As an extra to Rajat Singhal's answer (sorry, i don't have enough reputation to post a comment):
My drawable was having the wrong size (it was smaller), because drawables take into account the screen density. In order to preserve the original image size, I ended up doing this, in the fetchDrawable method:
public Drawable fetchDrawable(String urlString) {
try {
InputStreamis= (InputStream) newURL(urlString).getContent();
Bitmapbmp= BitmapFactory.decodeStream(is);
Drawabledrawable=newBitmapDrawable (context.getResources(), bmp);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
return drawable;
} catch (Exception e) {
returnnull;
}
}
Solution 3:
I just wanted to fix the size of the image from Rajat's answer, the image will take the full width of the textview and keeps the aspect ratio for the height. here's my update:
public Drawable getDrawable(String source)
{
if(source.matches("data:image.*base64.*"))
{
Stringbase_64_source= source.replaceAll("data:image.*base64", "");
byte[] data = Base64.decode(base_64_source, Base64.DEFAULT);
Bitmapbitmap= BitmapFactory.decodeByteArray(data, 0, data.length);
Drawableimage=newBitmapDrawable(context.getResources(), bitmap);
floatratio= container.getWidth() / image.getIntrinsicWidth();
intwidth= container.getWidth();
intheight= Math.round(image.getIntrinsicHeight() * ratio);
image.setBounds(0, 0, width, height);
return image;
}
else
{
....
}
}
publicclassImageGetterAsyncTaskextendsAsyncTask<String, Void, Drawable>
{
....
@OverrideprotectedvoidonPostExecute(Drawable result)
{
if(result != null)
{
floatratio= container.getWidth() / result.getIntrinsicWidth();
intwidth= container.getWidth();
intheight= 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
{
InputStreamis= (InputStream) newURL(urlString).getContent();
Bitmapbmp= BitmapFactory.decodeStream(is);
Drawabledrawable=newBitmapDrawable (context.getResources(), bmp);
floatratio= container.getWidth() / drawable.getIntrinsicWidth();
intwidth= container.getWidth();
intheight= Math.round(drawable.getIntrinsicHeight() * ratio);
drawable.setBounds(0, 0, width, height);
return drawable;
}
catch (Exception e)
{
returnnull;
}
}
}
}
However, Ranjat's solution shows only 1 image. If you wanna show multiple images then you need to use ImageSpan
inside SpannableStringBuilder
if you need an example let me know in a comment.
Post a Comment for "Load Images In Html.fromhtml In Textview (http Url Images, Base64 Url Images)"