View Full Version : Limiting image size in ePub


eggheadbooks1
08-15-2012, 01:02 AM
I have several images that are around 600x800 pixels that when viewed in an ePub app like ADE or Sony Reader get cut off. Setting the height to 100% solves that problem.

However, I have several images that are smaller than the screen size of the average ereader but too wide to fit in a mobile app, for example. If I set them to 100% so they are not cut off on a mobile app, they are then upsized in a larger device or computer app and look like crap.

What I want is to contain the 100% height or width to the maximum of the image's native pixel dimensions so that small screens will not cut off the images and larger screens will not uprez them.

Having read a few posts I thought wrapping them in an SVG container would do the trick (I thought perhaps the "viewBox" referred to a container of sorts), but when tested in ADE, Nook for PC, Sony reader for PC, and Aldiko on Android, there was no difference between using the SVG container and simply setting the height to 100%. My small images are still uprezzing past their native dimensions.

In other words, there was no difference between this (the native code after inserting the image in Sigil with the height value added):

<p class="sgc-1"><img alt="" height="100%" src="../Images/1_Bookmark.jpg" /></p>

and this:

<div>
<svg xmlns="http://www.w3.org/2000/svg" height="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 293 333" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
<image height="333" width="293" xlink:href="../Images/1_Bookmark.jpg"></image>
</svg>
</div>

I also read you can set max-height or max-width but not only does it not work to limit the image size, some of the images become distorted.

Is there a way to do what I want?

JSWolf
08-15-2012, 08:54 AM
If you can, make the images larger.

eggheadbooks1
08-15-2012, 12:11 PM
Not possible in this case. So the question remains, is there a way to limit the uprezzing to the actual pixel dimensions?

mmat1
08-15-2012, 02:12 PM
What I want is to contain the 100% height or width to the maximum of the image's native pixel dimensions so that small screens will not cut off the images and larger screens will not uprez them.


1. You may try the max-width - attribute
2. You may follow JSWolf's advice, it's actually a good idea and i'll go to try out for myself. You can add "white -space" at the top and bottom of your picture to change the orientation from landscape to portrait, so the max-height 100% should always work...

eggheadbooks1
08-15-2012, 02:39 PM
Have been doing more experiments with images that are in the mid-size range, dimensions like 500 x 593, 490 x 768, and this is what I am finding:

The SVG wrapper helps to maintain the proper ratio; if only a height=100% or width=100% value is used, the one value causes the image to be uprezzed and the rest of the image is cut off.

I tried the max-height and max-width value; this distorted the images. Will try again in an SVG wrapper but will only set one max value and see if that works.

Any other suggestions greatly appreciated.Otherwise the default is to leave the images at their native dimensions and say to hell with it. In the dedicated readers and mobile device apps I tested,they all tended to do a much better job of downsizing images to fit when they are not in an SVG wrapper, and in the computer apps the downsampling is of such poor quality that the size issue becomes almost academic.

Jellby
08-16-2012, 04:38 AM
I tried the max-height and max-width value; this distorted the images.

Did you try with only max-height (for instance), no width, no max-width, just max-height.

With SVG, this works in my browser (Opera):

<div>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 600 800" preserveAspectRatio="xMidYMid meet">
<image width="600" height="800" xlink:href="images/Cover.jpg" />
</svg>
</div>

The numbers in "viewBox" and the image "width" and "height" must match, but they don't need to be the real pixel dimensions of the image, or even the same ratio.

The height="100%" does nothing in Opera, because there's no defined height for the containing block, but it might work in ebook readers.

With this, the image is never distorted, and it's always resized (up or down) to maximum possible size. To limit the maximum size, this works too:

<div style="max-width:600px; max-height:800px">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 600 800" preserveAspectRatio="xMidYMid meet">
<image width="600" height="800" xlink:href="images/Cover.jpg" />
</svg>
</div>

Now the "max-width" and "max-height" in the div are the image pixel dimensions. It also works (in Opera) if the style is put in the <svg> element instead of the <div>.

eggheadbooks1
08-16-2012, 01:00 PM
Thanks, will try that. I had found something similar on a blog about setting limits within the div style but it didn't give an example of how to actually do it.

I had tried using only one max-height or max-width value but either it had no effect or images were distorted on some devices or apps.

Will try to do this today and report back.

eggheadbooks1
08-16-2012, 02:13 PM
Jellby:

Almost there! Just one last hurdle:

My images were centered. In Sigil, this translated into a div class

<div class="sgc-2">

whereby sgc is

div.sgc-2 {text-align: center;}

I tried coding it like this:

<div class="sgc-2" style="max-width:293px; max-height:333px">

but Sigil then changes each style to a div.sgc and I end up with this

<div class="sgc-2 sgc-3">

whereby sgv 3 is

div.sgc-3 {max-width:293px; max-height:333px}

but the ereaders ignore the centering. So I get my max width or height (THANK YOU!) but I lose my centering.

I tried this:

<div class="sgc-2">
<div class="sgc-3">
<svg xmlns="http://www.w3.org/2000/svg" height="100%" max-width="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 293 333" xmlns:xlink="http://www.w3.org/1999/xlink">
<image height="333" width="293" xlink:href="../Images/Angel72.jpg"></image><br />
</svg>
</div>
</div>

but it didn't work.

I also tried opening the division with

<div class="sgc-2; sgc-3">

but that didn't work either. I'm not a programmer and I am out of ideas.

Any thoughts?

JSWolf
08-16-2012, 04:41 PM
To fix Sigil from changing things to those annoying sgc styles, run Sigil with no files loaded, turn off Tidy and then close Sigil. Now when you run Sigil, Tidy won't run and create those sgc styles.

eggheadbooks1
08-16-2012, 05:04 PM
Thanks. Turned off Tidy. But I still can't get my centering back. With

<div class="sgc-2" style="max-width:531px; max-height:800px">

the ereaders ignore the class and only read the style.

Jellby
08-17-2012, 04:58 AM
I tried coding it like this:

<div class="sgc-2" style="max-width:293px; max-height:333px">

but Sigil then changes each style to a div.sgc and I end up with this

<div class="sgc-2 sgc-3">

whereby sgv 3 is

div.sgc-3 {max-width:293px; max-height:333px}

That's OK, both things mean the same and should be rendered the same.

Your problem is that you don't want centering, but auto margins. Centering, as a text-align value, refers to the alignment of content inside the <div>, but it doesn't specify how the whole <div> will be placed in the page (or screen, or other containing block). That would be done by adding "margin-left: auto; margin-right: auto;" to the sgc-3 style, but readers are allowed to ignore auto margins (and Adobe does).

There are some things you could try, one of them is this, that you already tried:

<div class="sgc-2">
<div class="sgc-3">
<svg xmlns="http://www.w3.org/2000/svg" height="100%" max-width="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 293 333" xmlns:xlink="http://www.w3.org/1999/xlink">
<image height="333" width="293" xlink:href="../Images/Angel72.jpg"></image><br />
</svg>
</div>
</div>

(remove that <br/>, it's not doing any good, I'm not even sure it's allowed in SVG)

But add "display: inline" to the sgc-3 style. Normally a <div> is "display: block", which is rendered as a "paragraph", ignoring text-align, with "display: inline" you make it behave as "character" (of whatever size), and it should obey text-align.

Or you could skip a level and go with:

<div class="sgc-2">
<svg style="max-width:293px; max-height:333px" xmlns="http://www.w3.org/2000/svg" height="100%" max-width="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 293 333" xmlns:xlink="http://www.w3.org/1999/xlink" >
<image height="333" width="293" xlink:href="../Images/Angel72.jpg"></image>
</svg>
</div>

That is, set the maximum size for the <svg> element directly (again, it works in Opera). You could also try with class="sgc-3" instead. I'm not quite sure this is really compliant, but nothing is lost trying.

JSWolf
08-17-2012, 01:59 PM
Thanks. Turned off Tidy. But I still can't get my centering back. With

<div class="sgc-2" style="max-width:531px; max-height:800px">

the ereaders ignore the class and only read the style.

Turning Tidy off will only help with eBooks Tidy has not already screwed. With the one you already ran through Sigil, the only was to fix things is manually.

eggheadbooks1
08-19-2012, 05:41 PM
(remove that <br/>, it's not doing any good, I'm not even sure it's allowed in SVG)

Sorry about that. That was just lazy cutting and pasting...

And the winner is:

<div class="sgc-2">
<svg style="max-width:293px; max-height:333px" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 293 333" xmlns:xlink="http://www.w3.org/1999/xlink" >
<image height="333" width="293" xlink:href="../Images/Angel72.jpg"></image>
</svg>
</div>

Yeah!!! Works in ADE, Aldiko on Kindle Fire, Kobo Touch, Sony for PC, Nook for PC. (I had to take out the "max" in "max-width="100%" for a reason I don't understand. If it were left in some of the images didn't shrink correctly).

Thank you so much!

Just out of curiosity: what is the function of the viewBox as opposed to the max width and height of the svg style? When I first saw the SVG code I thought the viewBox would be a constraint of some sort; its name suggests so.

Jellby
08-20-2012, 04:19 AM
The viewBox sets the coordinates of the svg canvas, they are not pixels or mm or anything, just numbers. It's telling that one corner is at coordinates (0,0) and the opposite at (293,333), so that when you make your image's size 293333 it fills the whole space reserved for the SVG picture. You'll see why these numbers don't need to match the real pixel dimensions of the image.

JSWolf
08-20-2012, 06:37 PM
The viewBox sets the coordinates of the svg canvas, they are not pixels or mm or anything, just numbers. It's telling that one corner is at coordinates (0,0) and the opposite at (293,333), so that when you make your image's size 293333 it fills the whole space reserved for the SVG picture. You'll see why these numbers don't need to match the real pixel dimensions of the image.

Originally, Calibre had is using the numbers to fill the screen and if they were not the numbers for the image, the image would come out with the incorrect aspect ratio even if the code said to make the aspect correct. I pointed this out to Kovid and he fixed it so when Calibre generates the SVG code for the cover, it uses the numbers for the resolution of the cover. This could be a bug in ADE. But since most ePub is read using ADE, using different numbers (other then the resolution) may not work well.

eggheadbooks1
08-21-2012, 02:18 PM
Interesting, thanks.

A new but related question: I do not own a smartphone, just a tablet, so I cannot test... do the smartphone apps (Sony, Nook, Kobo, ADE) also cut off images not placed within an SVG wrapper but left at their original dimensions?

Kaylee Skylyn
09-10-2012, 05:21 PM
Hey all,

I thought the code here in post 13 would solve some major issues for me (I really really want something like this!) but I'm still running into issues. It works fine on the desktop, looks great in Calibre (after epubing) and in firefox (before epubing). Passes epub check but on the reader (both Sony PSR 350 and Android phone with Aldiko and BlueFire Reader) it puts each image on a separate page. I can see no reason for this. It seems to re-size the images like I wish but even a small two or three line high divider is given its own page. That is just not going to work.... I tried removing the DIV and it still gave each image its own page.

Any ideas why the SVG would give each image its own page?

I was really loving this resizing until now...ugh.

Jellby
09-11-2012, 04:29 AM
height="100%" width="100%" might have something to do.

Kaylee Skylyn
09-11-2012, 06:13 PM
Ok I mayhave misunderstood the thread then.

Removing one or the other may work....for now I'll keep width=100% and see if it works

Still darn annoyed the ePub does one thing on the desktop but totally different on the reader....this is exceedingly tiresome to transfer to the units to check every minor change. But eReader unpredictability is a different rant. :P

eggheadbooks1
09-27-2012, 05:41 PM
Jellby:

Urgent: just when I thought I had it all done: the SVG wrapper that we devised is working great except for one thing that has just revealed itself: it causes the image to always start on a new page. That was fine with large images but I just tried to put a smaller image (my logo) in a wrapper and now the logo sits on its own page. Not what I had intended. I have tried putting in a style="page-break-before:avoid" value in but to no avail. Any ideas?

eggheadbooks1
09-27-2012, 05:51 PM
I should add that the only solution I have come up with so far is that for images smaller than a mobile phone screen (the smallest screen the ebook would be viewed on) is to not put the image in a wrapper but to set a fixed pixel dimension.

eggheadbooks1
09-27-2012, 07:15 PM
Also, when I did my original tests, if two images were back to back, and if they fit two to the page, they appeared as such. This starting on a new page only happens when the images is bookended with text.

Jellby
09-28-2012, 04:10 AM
Unfortunately, SVG support is usually weak, and there are many issues in different readers. Moreover, there are many tricky interactions between HTML, CSS and SVG... Can we see you code? maybe there's something with it.

eggheadbooks1
09-28-2012, 03:08 PM
Hi Jellby:

This is the code we eventually came up with:

<div class="Main" style="text-align: center;">
<svg style="max-width:300px; max-height:600px"
xmlns="http://www.w3.org/2000/svg" height="100%" width="100%"
preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 300 600"
xmlns:xlink="http://www.w3.org/1999/xlink" ><image height="600" width="300"
xlink:href="../Images/Image1.jpg"></image>
</svg>
</div>

It works great in that it achieves its objective of downsizing images on small screens while limiting the potential upsizing of small images beyond their native dimensions, and it allowed me to center the images, but all surrounding text is pushed off screen. So something like my logo on my title page I have had to simply set a fixed pixel dimension. I can also do a percentage of screen height.

When I first did these tests, I had only images in my test file. Two small images would display together on the screen so I did not imagine that surrounding text would not behave the same way. Wrong. The SVG wrapper is essentially behaving like text jump text wrap.

If there's nothing that can be done, so be it. It's still the lesser of two evils. But if there is a way to fix this that would be great.

Jellby
09-29-2012, 03:57 AM
I assume you change the 600 and 300 numbers for each image in the three places (image size, viewbox and max dimensions).

I don't see right off what could be causing your problem, except that maybe max-width and max-height are not working in your reader, or there's something in the "Main" class. You could try adding borders to the <svg> and <div> styles and see if that helps with debugging (they would tell you the true size of the elements).

Kaylee Skylyn
09-30-2012, 02:05 PM
I was having similar issue but once one of the height="100%" width="100%" was removed it works fine. In my situation the images are all wider than tall so I removed the height="100%" from the code and it works fine on my Sony and Aldiko android app.
I think...can't find the right code at the moment....

I think this is the code that worked for me...For the opening banner, as it was much wider than tall:

<div class="cenimage">
<svg style="max-width:576px; max-height:288px" xmlns="http://www.w3.org/2000/svg" width="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 576 288" xmlns:xlink="http://www.w3.org/1999/xlink" >
<image height="288" width="576" xlink:href="images/masterpostbanner-1.png" ></image>
</svg>
</div>

Where the div is just:
div.cenimage {text-align: center;}

eggheadbooks1
10-03-2012, 01:21 PM
Kaylee: removing the height in this case worked perfect. Thanks!