31

In some web browsers, huge images are automatically resized to fit the screen.

Is it possible to do the same in an Android WebView?

The web page just contains the image, maybe adding some JavaScript could do the trick?
Anybody has already done this?

Note: I don't know the size of the image in advance.

Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373

8 Answers8

68

Yes, it's possible. You can try setting the WebView Layout using the code below. It resizes all Images (Greater than the Device Screen Width) to the Screen Width. This works for both Orientations (Portrait and Landscape)

webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

You can add extra margins/padding later to get the spacing right.

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
  • 1
    +1 I haven't tried yet, but it sounds perfect, better than using JavaScript. – Nicolas Raoul Sep 08 '12 at 05:03
  • 2
    Works, tested on 2.2.1, 3.2 and 4.0.3. `minSdkVersion="8"` `targetSdkVersion="15"` and `android-support-v4.jar`. Very simple and effective! – Ruben Sep 12 '12 at 10:02
  • 4
    I like this solution, but I've found that SINGLE COLUMN is deprecated. If someone know why, please, point it out. – m039 Feb 19 '13 at 13:41
  • For example, I've experimentally found that if this option is enabled embedded youtube movie doesn't play. Please, correct me. – m039 Feb 19 '13 at 19:46
  • 2
    @m039 - SINGLE_COLUMN is deprecated, but that's the only way without using CSS. As far as YouTube videos are concerned, they are working fine on my devices. (Tested on Nexus 7 (4.1) and Galaxy Nexus (4.0, 4.1, 4.2)) – Sheharyar Feb 20 '13 at 15:25
  • 1
    It is not working for me.. :( here is my code. wv.loadUrl("file://" + imageFile); wv.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); I have also tried loadUrl() AFTER setLayoutAlgorithm() – M. Usman Khan Jul 13 '13 at 05:36
  • @usman - Instead of loading your image directly from file try embedding it into the page as an html object. `setLayoutAlgorithm()` works for html pages only. See this for help: http://stackoverflow.com/questions/10843178/android-adding-a-image-in-html-webview – Sheharyar Jul 13 '13 at 15:05
  • @sheharyar.. i just tried that, didnt work. I wrote "" in an html file, and then loaded the html file wv.loadUrl("file://" + htmlFile); It still is showing the huge image. – M. Usman Khan Jul 16 '13 at 10:08
  • @SheharyarNaseer I tried your code but I have problem with displaying YouTube videos inside WebView with LayoutAlgorithm.SINGLE_COLUMN. Can you help me? Take a look here: http://stackoverflow.com/questions/17791984/android-webview-one-column-doesnt-work-with-youtube-videos – Zookey Jul 22 '13 at 17:46
  • 5
    So.. Android 4.4 killed this by killing LayoutAlgorithm.SINGLE_COLUMN. Anyone find an alternative? – Brayden Nov 11 '13 at 18:02
  • with "loadDataWithBaseURL" and after use "setLayoutAlgorithm" not work –  Oct 14 '15 at 10:00
  • Thank you for your solution. but SINGLE_COLUMN is deprecated and is not working anymore – Amin Sep 23 '19 at 12:38
  • alternative with CSS here: https://stackoverflow.com/a/20192803/3032209 – Yair Kukielka Sep 25 '19 at 06:36
42
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

works but is deprecated. This is another solution without LayoutAlgorithm.SINGLE_COLUMN, using CSS:

@SuppressLint("NewApi")
private openWebView() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING);
    } else {
        webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
    }
    String data = "<div> your HTML content </div>";
    webView.loadDataWithBaseURL("file:///android_asset/", getHtmlData(data), "text/html", "utf-8", null);
}

private String getHtmlData(String bodyHTML) {
    String head = "<head><style>img{max-width: 100%; width:auto; height: auto;}</style></head>";
    return "<html>" + head + "<body>" + bodyHTML + "</body></html>";
}
Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373
Yair Kukielka
  • 10,686
  • 1
  • 38
  • 46
  • 2
    +1 Indeed `LayoutAlgorithm.SINGLE_COLUMN` seems to be deprecated, so Sheharyar's solution becomes less attractive... – Nicolas Raoul Nov 27 '13 at 09:04
  • 3
    The extra line of css with auto width/height does the magic on 5.0 Lollipop – lini sax Jul 01 '15 at 18:41
  • 1
    Best solution.. works great thanks.. :) But i also get stuck in youtube link.. this code does best with image and text but it can not change width of youtube link .. can you help me out. – Reshma Jul 01 '16 at 09:16
  • 1
    This works. I added `webview_image.settings.builtInZoomControls = true` to allow the user to zoom in and out too. – Aphex Jul 12 '18 at 21:36
  • it works fine but notice if you have iFrame in your Html you should manage that as well.in that case, using the previous solution solves that problem too. I mean using Jsoup library – Amin Sep 23 '19 at 13:09
  • Nice one so its actually the style in the head that is doing the magic. – Mubashir Murtaza Aug 02 '21 at 06:37
20

You could use this:

WebView webView = (WebView) findViewById(R.id.myWebView);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);

Found this solution here: How to set the initial zoom/width for a webview

Community
  • 1
  • 1
AndyB
  • 1,896
  • 2
  • 22
  • 32
15

You can have the browser resize the image for you to fit the maximum width of the screen:

<img src="huge-image.jpg" width="100%" />

Resizing its height to WebView's viewport is possible too:

<img src="huge-image.jpg" height="100%" />

However, resizing both width and height would result in a stretched image. To either resize the width or height depending of what side fits best you may consider a bit of JavaScript, like this:

<img src="huge-image.jpg" onload="resize(this);" />


<script type="text/javascript">

    function resize(image)
    {
        var differenceHeight = document.body.clientHeight - image.clientHeight;
        var differenceWidth  = document.body.clientWidth  - image.clientWidth;
        if (differenceHeight < 0) differenceHeight = differenceHeight * -1;
        if (differenceWidth  < 0) differenceWidth  = differenceWidth * -1;

        if (differenceHeight > differenceWidth)
        {
            image.style['height'] = document.body.clientHeight + 'px';
        }
        else
        {
            image.style['width'] = document.body.clientWidth + 'px';
        }

        // Optional: remove margins or compensate for offset.
        image.style['margin'] = 0;
        document.body.style['margin'] = 0;
    }

</script>
3

I faced the same problem and used Jsoup to help me out and add the required respected CSS. You can easily add attributes or CSS. I my case, I download from many sources various different HTML files, save them and then display them in a Webview. Here is how I parse the HTML before I save it to the database with Kotlin:

// Parse your HTML file or String with Jsoup
val doc = Jsoup.parse("<html>MY HTML STRING</html>")

// doc.select selects all tags in the the HTML document
doc.select("img").attr("width", "100%") // find all images and set with to 100%
doc.select("figure").attr("style", "width: 80%") // find all figures and set with to 80%
doc.select("iframe").attr("style", "width: 100%") // find all iframes and set with to 100%
// add more attributes or CSS to other HTML tags

val updatedHTMLString = doc.html()
// save to database or load it in your WebView

Add Jsoup to your project

Have fun!

Paul Spiesberger
  • 5,630
  • 1
  • 43
  • 53
2

If your WebView width is fill_parent then you can use this code:

Display display=getWindowManager().getDefaultDisplay();
int width=display.getWidth();
String data="<img src='http://example.com/image.jpg' style='width:"+width+"px' />";
webView.loadData(data, "text/html", "utf-8");

And zoom still working!

Same method if height is fill_parent.

Dmitry Zaytsev
  • 23,650
  • 14
  • 92
  • 146
0

My favorite's :

String data = "<html><body ><img id=\"resizeImage\" src=\""+PictureURL+"\" width=\"100%\" alt=\"\" align=\"middle\" /></body></html>";  
webview.loadData(data, "text/html; charset=UTF-8", null);
Michael Assraf
  • 111
  • 2
  • 3
-1

You could send the size you want in the request parameters and let the server set the width/height in the img element for you.

Roland
  • 1,109
  • 13
  • 15