17

I've got the following

String urlStr = "http://example.com/my.jpg"
String mimeType = "image/jpeg";
String encoding = null;
String pageData = ""; // This is data read in from an HttpURLConnection
webview.loadDataWithBaseURL(urlStr, pageData, mimeType, encoding, urlStr);

but when I run this, all I see is a blue question mark instead of my image. What is the proper way to handle displaying an image in a WebView with loadData?

Edit: Is there a way to do this without passing pageData as <img src="http://example.com/my.jpg/"> ? It seems silly that loadData takes a mime-type if it can only handle "text/html". Especially since the javadoc lists "image/jpeg" as an example mime-type that you might pass in.

Carlos Rendon
  • 6,174
  • 5
  • 34
  • 50

2 Answers2

41

It is possible to embedd the base64 encoded imagedata direct into the <img>-tag:

  <img src="data:image/jpeg;base64,base64DataHere" />

Here an example for creating the <img>-tag (I use an byte-array instead the String for raw-data, because in my tests an String as source didn't work - I assume that String can't handle binary-data):

  byte[] imageRaw = yourImage;
  String image64 = Base64.encodeToString(imageRaw, Base64.DEFAULT);
  String pageData = "<img src=\"data:image/jpeg;base64," + image64 + "\" />";

The Base64-class was introduced with API v.2.2 - for older API-versions you can copy the sourcefile from git and integrate it in your app. It should work with older API-versions.

Or you can use one of the alternative classes for base64-encoding like Base64Coder.


And here the complete working code for retrieving, converting and showing the image:

  byte[] imageRaw = null;
  try {
     URL url = new URL("http://some.domain.tld/somePicture.jpg");
     HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     ByteArrayOutputStream out = new ByteArrayOutputStream();

     int c;
     while ((c = in.read()) != -1) {
         out.write(c);
     }
     out.flush();

     imageRaw = out.toByteArray();

     urlConnection.disconnect();
     in.close();
     out.close();
  } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
  }

  String image64 = Base64.encodeToString(imageRaw, Base64.DEFAULT);

  String urlStr   = "http://example.com/my.jpg";
  String mimeType = "text/html";
  String encoding = null;
  String pageData = "<img src=\"data:image/jpeg;base64," + image64 + "\" />";

  WebView wv;
  wv = (WebView) findViewById(R.id.webview);
  wv.loadDataWithBaseURL(urlStr, pageData, mimeType, encoding, urlStr);
MacGucky
  • 2,494
  • 17
  • 17
  • At least this avoids fetching the data twice. It still doesn't address the issue of mimetype in the API if it is always "text/html". – Carlos Rendon Mar 17 '11 at 16:46
  • I had a problem where an image fetched from the net was not being rendered at all in the webview (using – sami Jul 28 '11 at 19:55
  • 1
    When using code based on the above, I've noticed Logcat deprecation warnings from Chromium regarding support for linefeeds in the URL, something which I'm guessing it has only started warning about in recent months. The warnings state that support for URLs with linefeeds will possibly be blocked by August 2017. Those warnings no longer occur when I use `Base64.NO_WRAP` to avoid those linefeeds. – Trevor Jul 10 '17 at 13:07
3

Use this.. solve the problem of images load in webview.

    WebView  webView = (WebView)findViewById(R.id.webView1);
    webView.getSettings().setBuiltInZoomControls(true);
    webView.getSettings().setJavaScriptEnabled(true);

    String url ="Path of image";

    String imgSrcHtml = "<html><img src='" + url + "' /></html>";
    webView.loadData(imgSrcHtml, "text/html", "UTF-8");
Shailendra Madda
  • 20,649
  • 15
  • 100
  • 138
Sandy
  • 428
  • 1
  • 5
  • 16