Scale images.

Description

Image mummifiers need the ability to scale images if they are beyond some configurable threshold.

A user will likely want to dump a bunch of full-size, original images into the source tree without bothering to individually scale or otherwise manipulate them. But they probably don't want the full-size image being deployed to the size, primarily because of file size. Thus there needs to be some configurable threshold, probably based on file size, above which the image mummifier would automatically scale the image.

Environment

None

Activity

Show:
Garret Wilson
October 25, 2020, 4:12 PM

The Apache Commons Imaging seems like a new library that might eventually providing scaling and such, with independence from AWT. For the moment it's only in alpha and it's not immediately clear if it provides scaling yet.

Garret Wilson
November 8, 2020, 12:50 AM

I found something on Stack Overflow related to resizing an image on ImageJ.

Nobody on Stack Overflow seemed to know how to scale image with Apache Common Imaging, even though I offered a bounty on my question.

Garret Wilson
December 12, 2020, 10:47 PM

Although I found an interesting history of aspect ratios, if we maintain the original aspect ratio when scaling down the aspect ratio of the constraining bounds is of little interest; if we want merely to constrain the maximum dimension of the image (not knowing in advance if it is in portrait or landscape orientation), then we can simply constrain to a square area that matches a resolution matching the higher range of modern monitors. Thus we can simply scale images down to a constrained square of 2560 x 2560. This will still give a good quality image and probably ensure that the image file is reduced somewhat.

Garret Wilson
December 13, 2020, 4:26 PM

In addition to scaleThresholdSize, we need to configure the width/height for scaling as discussed previously. Using "length" as a general term for geometrical extent, we can have a configuration scaleLength of 2560.

Garret Wilson
December 13, 2020, 5:46 PM

Perhaps it would be helpful to be clear that we are scaling to try to reduce file size:

Garret Wilson
December 13, 2020, 5:58 PM
Edited

I just realized that instead of mummy.page.namesBare we have mummy.pageNamesBare. 😮

But now that we are having artifact type-specific settings, mummy.page.namesBare may be more appropriate. I'll go ahead and use the separate mummy.image.scale… config settings for this ticket, and we may want to go back and change mummy.pageNamesBare to make it consistent.

We might also want to consider renaming the entire mummy section to mummify, which would correspond to the factoring out of the io.guise.mummy.mummify classes (e.g. for ….page and ….image), and also would be more consistent with the deploy section in the config. This might (or might not) mean that we would rename the in-source-directory .guise-mummy.turf file.

On the other hand, if Guise becomes a larger building, deploying, and even orchestration platform, then maybe the deploy config section (and in fact the entire deployment subsystem) might be split out into a separate subproject. Thus mummy would be an appropriate name for the config section, and we might even move the artifact types down to the io.guise.mummy level, e.g. io.guise.mummy.image and io.guise.mummy.page. If that happens then Guise project settings such as mummy.page.namesBare and mummy.image.scaleThresholdFileSize would make perfect sense. So let's stick with a mummy.image config section for now.

Garret Wilson
December 13, 2020, 6:53 PM

I'm thinking that the "length" as a general term for either width or height could be confusing. Moreover I'm reconsidering something I discussed above:

… if we maintain the original aspect ratio when scaling down the aspect ratio of the constraining bounds is of little interest; if we want merely to constrain the maximum dimension of the image (not knowing in advance if it is in portrait or landscape orientation), then we can simply constrain to a square area that matches a resolution matching the higher range of modern monitors.

While it is true that the aspect ratio of the end-user's monitor will not affect the aspect ratio of the scaled image, this does not necessarily mean that the dimensions of the end monitor is of no consequence at all. Put another way, it would be useful to know the typical width and typical height of monitors and their rough aspect ratio (insofar as it affects whether they are portrait or landscape). If most monitors are landscape, it would not be helpful to scale a portrait image down with extra height to accommodate landscape monitor widths.

But now that I think about modern displays, it's clear that many phones and tablets are portrait and have very high vertical resolutions, so we would not want to unnecessarily scale down portrait images thinking they would go on landscape monitors. Thus the original idea of scaling to a 2560 x 2560 area seems right after all.

Now I just need to decide for sure what to call it.

Garret Wilson
December 13, 2020, 11:40 PM

Wow, I'm impressed at the result! It's taking an ~8MB full-color 5467 x 3644 JPEG file and at 80% compression quality it's turning out a 2560 x 1706 file that's only ~330K. If you zoom in a lot you can see some JPEG blocky effects, but at that resolution I wouldn't expect it to be noticeable on a normal screen, and especially not on a mobile phone. This is really good—better than I expected, especially since I haven't worked with this image scaling code in well over a decade.

Garret Wilson
December 20, 2020, 10:12 PM

It's tempting to want to lower the default scaleMaxLength down to 1280 because that would undoubtedly bring a big savings in file space. But in worldwide desktop screen stats a width of over 1280 pixels is almost ubiquitous. And photo sites such as Flickr have lightboxes that show full screen on big monitors. So at least 2560 is probably best. Maybe another approach would be to add some facility for automatically generating preview versions of only 1024 or something. We would need to work out how we indicate whether previews are generated or not.

Garret Wilson
December 20, 2020, 10:16 PM

Already there is some sort of a semantic overloading of scaleThresholdFileSize as a toggle for reducing photo size, with a toggle for general photo processing. Maybe we should change this to be processThresholdFileSize as a threshold for general processing. The idea is that we only want to process big images; presumably the smaller images are of a different type or role (icons? previews?) and area already "the way we want them". This processThresholdFileSize might be the most typical way to turn on image processing across the board, but may be too coarse in some cases; another way to turn processing on or off for individual images would be useful. The scaleMaxLength setting would also make more sense, as we may want to process the image but may wind up not scaling it if it is already small enough.

This new way of looking at the toggle will fit will with the realization that we probably need to update the destination metadata of the scaled images. In the current development implementation, all metadata is being stripped.

Garret Wilson
February 14, 2021, 10:52 PM
Edited

As discussed in GUISE-169, here are some sample image compression sizes, assuming embedded metadata and a max scale length of 2560:

Image

Quality 0.8

Quality 0.6

Quality 0.5

Quality 0.4

ad3-1089.jpg

336KB

239KB

218KB

198KB

am4-3213.jpg

802KB

591KB

537KB

483KB

ashd1-7696.jpg

417KB

288KB

256KB

226KB

IMG_0525.jpg

528KB

339KB

300KB

265KB

IMG_0743.jpg

492KB

408KB

361KB

317KB

IMG_3527.jpg

630KB

418KB

366KB

313KB

Dropping down to a max scale length of 1920 drastically reduces the image size:

Image

2560 Quality 0.8

2560 Quality 0.6

1920 Quality 0.8

1920 Quality 0.6

ad3-1089.jpg

336KB

239KB

215KB

156KB

am4-3213.jpg

802KB

591KB

533KB

392KB

ashd1-7696.jpg

417KB

288KB

272KB

193KB

IMG_0525.jpg

528KB

339KB

347KB

239B

IMG_0743.jpg

492KB

408KB

379KB

263KB

IMG_3527.jpg

630KB

418KB

396KB

265KB

As 1080p is 1920x1080, and WUXGA is 1920x1080 (see TV resolution confusion: 1080p, 2K, UHD, 4K, 8K, and what they all mean), it might be beneficial to drop the default scale settings to a scale length of 1920 and a compression quality of 0.6. If more and more people have 4K displays, users can always change the settings (or we can raise the defaults) and regenerate the images.

Fixed

Assignee

Garret Wilson

Reporter

Garret Wilson

Labels

None

Epic Link

Components

Fix versions

Priority

Major