Image Pixels, Points, and the CSS Reference Pixel

From this post: viewtopic.php?p=256769#p256769

Scrivener correctly uses a 72DPI to convert pixels to points. But when it compiles to HTML it uses the assumption that CSS pixels also obey a 72DPI rule, but they do not.

w3.org/TR/CSS22/syndata.html#values

Therefore I think it needs to slight change the maths. Lets take a 1080image-pixel 300DPI image. You correctly convert this to become 259points in the editor [300 / 72 = 4.167 | 1080 / 4.167 = 259 points], which you directly export to the CSS px values when compiled to a HTML based format — BUT it actually should use [300 / 96 = 3.125 | 1080 / 3.125 = 346 px].

??

I’m not doing any conversion for px when adding image sizes to epub etc, just using Apple’s image size width and height. Essentially, if the pixel width/height of the image does not match the points width/height, then Scrivener knows the image uses a non-72 DPI and then adds the point width/height as the pixel height/width for the HTML. i.e.:

if (img.pixelsWide != img.pointsWide || img.pixelsHigh != img.pointsWide) ... include "w=[img.pointsWide]px" etc.

If I understand you correctly, you are saying that this should be more like this:

int imgWide = img.pointsWide * (96/72)

That would mean including width/height for all images even if they aren’t scaled…

Hi Keith, from the linked epic thread, I feel this should apply only to cases where an image has a non-standard DPI and is exported to a HTML based format (and the rules where width=100% doesn’t apply). In my tests I imported a 900x1300 300DPI image into Scrivener, then exported to an EPub3 and I got CSS embedded values that were equivalent to points. Exactly as you say, in this case the more accurate conversion to CSS pixels would be int imgWide = img.pointsWide * (96/72)

The problem is if I compile the scaled image to a print document and to ePub3, the DOCX and RTF get the correctly scaled version but the ePub3 does not.

(Copied from the other thread)

The problem as I see it at this point is that the Edit Image/Scale Image dialogue is confusing. I loaded a 1000x1000 image of my smiling mug into my document. Apparently, I do not have any DPI metadata in it, as when I open the Scale Image dialog I see it reporting 1000 x 1000 pixels (96 DPI), and it is currently set to scale at 750x750 points.

Okay, open up the calculator and do the math: 1000 / 96 * 72 = 750. So that explains where 750 x 750 points is coming from.

So now I move the sliders so that it’s 375 x 375 points. It now says 1000 x 1000 pixels (192) DPI, which makes sense – half the physical size = twice the physical density. If I compile this to RTF or DOCX my image will still be there as a 1000 x 1000 pixel image but set to scale as 375 x 375 points (or 5.21 inches which is the corresponding size), correct?

What I am seeing in Word 2016 for DOCX and RTF is that the image in the file is now physically a 781 x 781 pixel image. 5.21" x 5.21" is the 100% size for this picture, now. Okay, not what I was expecting – it’s the intended target size, but the image has been downsampled, so I have to fix the scaling in Scrivener and recompile if I change my mind on the size.

Okay, so on to ePub3 (had to download Sigil and learn how to use it).

What I am expecting is that the file will be inserted as a 1000 x 1000 pixel image but set to scale as 375 points, or 500 pixels. Why 500 pixels? I don’t expect DPI to matter because this is HTML/CSS, but I do expect that since I scaled the image down 50% from its starting point, Scrivener will pass that same scaling ratio through as it did with DOCX and RTF formats.

What I get is a 1000 x 1000 pixel image (yeah!) with height: 375px; width: 375px; which gives me an image that doesn’t match to any size relationship I can figure out. 375 / 72 * 96 = 500 px ; 375 / 72 * 192 = 1000 px. I’ve used the slider to scale this image to 50% of its physical size, but what I end up with in my ePub CSS is 37.5% of the size.

At least the full image is there so I can fix the height and width and use percentage…

Since Scrivener is ignoring the DPI information, shouldn’t it be doing the math conversion so that the same amount of scaling is happening regardless of my compile format?

I have created a test project with three 1000 x 600 images at 72DPI, 96DPI and 300DPI. I have each image linked twice, once at the default editor points value assigned by Scrivener, and the same image scaled by 50% of this original value.

Compiling to Word 2016 (15.41) and everything is correct, all values I calculated from Scrivener are correctly expressed in the physical inches values given in Word.

For EPub3, as already mentioned, image widths larger than 600px are assigned a 100% width, but for images smaller than that they are assigned CSS pixel values that are incorrect and that is easily understandable by the fact Scrivener coverts points to CSS pixels with a multiplier of 1 when it should use 1.33 (96/72).

DPI.scriv.zip (825 KB)

Devin: it sounds to me like your image did have embedded metadata if it was at 96DPI. My 1000x600@96DPI image ends up at 375 CSS px width when resized 50% in the editor, this is expected from the calculations…

That’s where I am having trouble. It may be expected, but I am not convinced it is correct, and maybe this needs to be a toggle in the Scale Image dialog box (if we want to get completely granular per-image) or Compile settings (if we want to pick a standard on a per-project basis). I don’t think it’s reasonable to say “Scale my image this much” in the editor (which is supposed to be format-agnostic) and then not have it be consistent between compile formats without me telling it to be different. Even just a simple “Use percentage for all image scaling” in Compile would be grand.

Devin: the current rescale UI does not say it uses %, only that it uses points transformed by DPI from the image resolution, you are doing the % calculations yourself and this is where the ambiguity arises. Hopefully the 96/72DPI issue to generate CSS pixels correctly will be fixed and perhaps we can have an explicit slider to scale by % with the dialog showing the resultant calculated points and CSS pixels.

I didn’t say it did use %. With the additional information in the other thread that Scrivener is actually changing the DPI metadata in the image file, I actually understand what is going on and why. I think there are some assumptions there that need re-examined, but at least it’s being reviewed by The Powers That Be now. :slight_smile:

Nontroppo, have you done extensive testing of the 96/72 math on physical systems? I have been running tests to ascertain whether this or straight 72 dpi math is best for producing a WYSIWYG result, and in nearly every platform I’ve tested the results are clearly more accurate with straight 72—the way images are currently produced.

The test was simple: drop in a 72 dpi image so that no resizing is done to it in the HTML, and alongside it a 300 DPI image that has been scaled to look the same as a 72 DPI image in the editor. A second copy of the 300 DPI image was manipulated in post-compile to be resized using the 96/72 approach. The test is then compiled to ePub and Mobi formats and loaded in various viewers and physical devices. To test for parity simple eyeball tests of sizes are done.

Out of seven devices and readers tested, only one produces a result where the image resized using 96/72 math matched the original scaling in the editor: Kobo for iOS. Everything else was a direct, and to my eye anyway, precise reproduction of the visual size of the image in the editor for the 72 dpi image—and the 96/72 test image was clearly and obviously the wrong size.

So unless I’m missing something, my tentative conclusion here is that most eBook readers are going to be assuming sizes calculated of off simple 72 dpi math, and will be calculating the length of a display pixel in such a way as to provide a consistent appearance for that image whether it is viewed on a MacBook screen, iPad, iPhone or Kindle eInk screen.

That isn’t to say that what you’re talking about doesn’t exist—rather the 96 dpi thing is part of the equation I’m referring to above, done in the system itself to take a standard measurement and factor it according to the device resolution so that each pixel is modified by that ratio between intended appearance (300px) and how many literal pixels it takes for the device to produce that appearance. The 96 dpi reference point is derived from an angular measurement of the smallest visible dot at arm’s length, as a gold standard for how large 300px should look. Thus to directly manipulate HTML toward that standard within the context of a system not expecting that would be to overcorrect. That is at least what I seemed to be observing.

My point is purely technical, I don’t own any eReaders or use any eReader apps other than Calibre (macOS) / Marvin (iOS).

But if the viewers are compensating somehow you would expect CSS px would be equivalent to pt right? That is not the case, at least in Chrome / Calibre / iBooks. See the attached screenshot from iBooks, I’ve sized a 1000x720 image using 4 CSS methods, and the inches, point and (96/72) modified CSS pixels all look the same :

The values that comes from Scrivener (where px are given the same values as points), is visibly smaller than the other sizes.

I’ve done this for a 72DPI and 300DPI source image and there is no difference of the embedded metadata in any viewer I have. Find the EPub3 attached:

DPI.epub.zip (283 KB)

Is this similar to your tests?

Okay yes, I do see what you mean here. When comparing the image set using print measurements with CSS, either inches or points, then the version using 72dpi pixel conversion is smaller, which does indicate that various viewers are internally reckoning points and inches using 96/72 math. So my original tests were limited in only considering Scrivener as the point of reference.

But to that end, all three of those samples are larger than the image in Scrivener at 100% magnification. I think that’s the main thing my mind keeps coming back to: if the idea is to make the image look like it does in the editor, then wouldn’t the formula that does precisely that in most contexts be the best? If you drag the slider and make the picture the size an index card, and then compile that to ePub, AirDrop it to iBooks on your iPad and open it up to find an image the size of an index card—isn’t that the desired result? So while Scrivener’s 240px output is smaller than the rest, if you drop your sample file into Scrivener’s editor, it’s the only one out of the batch that matches.

Or is it a better to try and match the result one gets when using print-world measurements in CSS (something that should be avoided in the first place)?

The discrepancy is because Scrivener assumes a 72DPI baseline, which comes from a traditional Mac desktop OS perspective (pre-retina). Windows and most linux desktops traditionally assumed a 96DPI perspective IIRC. I really don’t know what one could consider the ground-truth, I think there isn’t one that is universal. Different OSes over different time frames, different monitors, and different apps all seem to have different interpretations of a base DPI…

The question is, why should Scrivener stick to 72DPI? The strongest argument for me is compatibility with itself, and perhaps that is the most valid reason to stick here and also “subvert” the CSS reference pixel from the officially correct to scrivener-relative size. Does Windows Scrivener also adopt the Mac baseline scaling, or use the more common 96DPI for that platform?