Jump to content

Image quality problem on resize


humanafterall
 Share

Recommended Posts

Hi,

I'm using the on the fly image resizing in Processwire to create suitable image sizes for different viewports (using Foundation's Image Interchange).

All seemed to be working fine but I'm having real trouble with the quality of the outputted image.

This is the orginal image:

bafta-film-awards-campaign-2014.jpg

This is an example of a resized image:

bafta-film-awards-campaign-2014.768x436.

It looks like it's losing colour information in the process of being resized.

I've tried setting the default quality to 100% (in the wire/core/ImageSizer.php) but to no avail.

Could anyone share any light on what might be happening here?

Link to comment
Share on other sites

Hi humanafterall,

I had a similar problem with the resizing function and posterization in dark image areas, my workaround was to comment out the gamma correction in the Imagesizer.php (lines 247 & 387). I’m not sure what that function is good for, but now everything looks good.

There is a similar discussion going on over here.

Link to comment
Share on other sites

Hi Soma,

Odd - actually you may have viewed it when I was updating the images linked to in the original post.

Can you try a refresh and see if the images above look the same now?

Also here's a grab of the second image. Are you definitely not seeing any posterization on the gradient?

posterization.png

Link to comment
Share on other sites

Yeah I see that too, now that you mention it. Well I'm not surprized really, as such gradients get posterizes real quick and with GD lib it's almost certain. This is kinda nit picking for me, as I wouldn't expect a better quality from a "GD resize" for a thumb of that type of image having dark, subtle gradients (I'm kinda expecting it). ImageMagic would be better in that regard, though could imagine you would get a poster too. But that's not supported anyway, so I'm not sure what to tell as I'm no expert with image resizing on server software. Best bet would be to resize them with a program and upload them at the right size already. Or does commenting out those lines you guys tell help in that regard?

Link to comment
Share on other sites

 I had a similar problem with the resizing function and posterization in dark image areas, my workaround was to comment out the gamma correction in the Imagesizer.php (lines 247 & 387). I’m not sure what that function is good for, but now everything looks good.

 There is a similar discussion going on over here.

@robert: if you are interested in what it does, you may read the link that is posted in the thread you linked to: http://www.4p8.com/eric.brasseur/gamma.html#introduction

There is an error in most photography scaling algorithms. All software tested (August 2007) had the problem: The Gimp, Adobe Photoshop, CinePaint, Nip2, ImageMagick, GQview, Eye of Gnome, Paint and Krita. Also three different operating systems were used: Linux, Mac OS X and Windows. (Software that don't have the problem are listed in the Solutions chapter.)

Photographs that have been scaled with these software have been degradated (see the examples). The degradation is often faint but probably most pictures contain at least an array where the degradation is clearly visible. I suppose this happens since the first versions of these software, maybe 20 years ago.

In fact with first linearizing to 1 and after resizing linearizing back result in correct images. They are brigther in comparision to the ones resized with gamma errors. These ones results in to darkened images. If you want try it on your own images, you may incorporate a grayscale and / or other colortargets and check the results by the histograms or with the colorchecker in photoshop. But the explanation with examples from Eric Brasseur are really good and detailed I think.

Could it be that the posterization is allready in the original images? At a very low scale, but allready there? And yes if you then darken the images together with resizing you end up not seeing it that strong. Sounds possible, right? But I'm not sure. If you have a look to the original image from chrizz in the other thread, you see that it has allready some artefacts, so visually tolerable, but they are allready there.

Maybe there are better solutions available then disabling gamma correction. I really would have a closer look to that and test with other sharpening methods.

Would you be so kind and send me one of your original images where you get better results without gamma correction? Also usefull a resized one with and one without linearizing and the information what sharpening mode you have used. (I can pm you my emailadress if you want)

It is not good that exactly people who do a lot work on their images run in this problems whereas the overall common cases gets better results with it.

Link to comment
Share on other sites

I am not sure on the whole GD vs Imagemagick quality issue. I know years ago IM was ahead, but not sure if that is still the case. From reading around it sounds like they each have their strengths and weaknesses. That said I have always used IM until I started using PW.

For the sake of experimenting, I quickly threw this module together as a way to test IM within PW. It replaces the resize method, so it will work from the admin and also template calls like: $image->size(400,0)

It doesn't do anything more than the resizing at the moment - it currently ignores all quality settings, cropping etc. I doesn't try to do any sharpening either, but it's a starting point that we can play with. I need to get back to real work, but thought one of you guys might be keen to play around with and tweak settings and see what you can come up with.

Obviously you need imagemagick on your server and also the iMagick extension.

ImagickResizer.module

  • Like 3
Link to comment
Share on other sites

...  Could anyone share any light on what might be happening here?

Hi @humanafterall. additionally to that what I have replied to @robert, it has nothing to do with linearization (gamma correction). The artefacts comes from sharpening the images. Attached is a test with sharpening set to 'none', the default 'soft' and the third image is a rezied version where I have added some noise to yout original image with photoshop. This is common usage: if you have technical gradients with pixel formats use the filter "add noise". How much and if monochrome or colored you may test, but that's the only way I know to avoid these artefacts.

humanafterall_test_sharpening-none.jpg

You can set / send options in your template like this:

		$img = $page->images->first();
		$img->removeVariations();

		$options = array(
			'cropping' => true,
			'sharpening' => 'none',
			);
		$img = $img->size(768, 436, $options);

EDIT: added more clearly that I have added noise to the original image and resized it in PW with GD-lib.

Edited by horst
  • Like 2
Link to comment
Share on other sites

For the sake of experimenting, I quickly threw this module together as a way to test IM within PW. It replaces the resize method, so it will work from the admin and also template calls like: $image->size(400,0)

It doesn't do anything more than the resizing at the moment - it currently ignores all quality settings, cropping etc. I doesn't try to do any sharpening either, but it's a starting point that we can play with. I need to get back to real work, but thought one of you guys might be keen to play around with and tweak settings and see what you can come up with.

@adrian: this is a very good starting point! An IM alternative may be good for all that can use it on their hosts.

But for all users that cannot, we have to improve the usage of GD.

  • Like 2
Link to comment
Share on other sites

Agreed horst - we need to make GD the best it can be. I do like the idea of a drop-in IM replacement though. There are so many settings that developers could tweak with IM. One thing that should be tried straight off is using: adaptiveResizeImage instead of ResizeImage, which is what I used in the module to start with.

Anyway, as I said, no time right now, but perhaps if enough people are keen and think the benefits are worth the effort, perhaps we could collaborate on this?

  • Like 2
Link to comment
Share on other sites

Anyway, as I said, no time right now, but perhaps if enough people are keen and think the benefits are worth the effort, perhaps we could collaborate on this?

Currently I'm not knowing IM, but I'm in! :)

  • Like 2
Link to comment
Share on other sites

Can you post the resulting images with the lines commented out? 

I've learned to live with the limitations of GD library, but would be thrilled if there was a way to improve.

@renobird: Tom, to comment it out is nonsense. It just do the opposite: it save the original colors when resizing, whereas not using it it wash out (some) colors (makes them darker). A very helpful article with tests, examples and explanations is here: http://www.4p8.com/eric.brasseur/gamma.html

This article also provides solutions for IMagick and Adobe Photoshop that have the same gamma error in resizing 8bit images! The advantage from Imagick and photoshop over GD-lib is their support for 16bit colordepth. Transfering images into 16bit colordepth do exactly a gamma linearization at first and after that a numbered colortransfer!

One way to improve it is to use gamma correction! :grin:

  • Like 3
Link to comment
Share on other sites

Agreed horst - we need to make GD the best it can be. I do like the idea of a drop-in IM replacement though. There are so many settings that developers could tweak with IM. One thing that should be tried straight off is using: adaptiveResizeImage instead of ResizeImage, which is what I used in the module to start with.

Anyway, as I said, no time right now, but perhaps if enough people are keen and think the benefits are worth the effort, perhaps we could collaborate on this?

I'm not particularly interested or knowledgeable in image optimisation myself (as long as I can still tell what's in the image and it doesn't consume too much disk space and/or cause unnecessary slowdowns all is good) but this sounds awesome! GD vs. Imagick is clearly something that's been bugging some folks and we'll likely be seeing even more topics about that in the future.

I sincerely hope that you guys find the time to take this further :)

  • Like 2
Link to comment
Share on other sites

I have had the same problem some days ago... 

Is you example a JPEG image? I switched from JPG to PNG and the results of quality are significant better!

Unfortunately Photoshop does a much better job than GD does. While the original png (1024px) has a size of about 300 KB a resized version down to 721px needs 570 KB. I'll try to use IM next time or as mentioned above: Resize all images in Photoshop (which is not the solution I would prefer since PW has such cool functions :D

Link to comment
Share on other sites

... While the original png (1024px) has a size of about 300 KB a resized version down to 721px needs 570 KB

??? that makes no sense. The original must be greater than the resized version.

And even with jpeg format, the original source should be 100% quality (and therefor greater than resized versions) and only the outputted / resized versions should be degradated to lesser quality (70 - 90).

If you use a lossy compressed source, you multiple times add artefacts to the outputs.

And PNG can be compressed too.

--------

Workflow 1 could be:

  • local source format TIFF, 16bit colordepth (ECI-RGB_v2 or Adobe-RGB) (regardless of with or without lossless compression)
  • convert to sRGB colorspace, optionally scale down to max 1600px, reduce colordepth to 8bit and save it as JPEG with quality 12 (photoshop) or 100% (other software)
  • upload this JPEG as original source
  • try resizing and sharpening with unsharpMask($amount, $radius, $threshold) from PageImageManipulator

Workflow 2 could be:

  • local source format TIFF, 16bit colordepth (ECI-RGB_v2 or Adobe-RGB) (regardless of with or without lossless compression)
  • convert to sRGB colorspace, optionally scale down to max 1600px, reduce colordepth to 8bit and save it as PNG without compression
  • upload this PNG as original source
  • try resizing and sharpening with unsharpMask($amount, $radius, $threshold) from PageImageManipulator and test different quality settings for the output (results in smaller filesizes)

And once the imagick-module is ready change to it :) 

but above workflows may be worth a try.

  • Like 2
Link to comment
Share on other sites

Thanks for these two workflows. I'll give it a try as soon as possible.

My last trial was this workflow:

- Export from Lightroom as PSD

- Save for Web via Photoshop as PNG

- Upload PNG (as described above 300 KB))

- Resize image via PW (570 KB)

The quality of all images is quite nice when using PNG, but the size isn't.

As soon as I have some more results I'll let you know. 

Link to comment
Share on other sites

Just for interest, why do you go from Lightroom to PS rather than just export from LR? Or can't you do png from Lightroom and I never noticed...

Horst, that add noise trick is really useful. I couldn't appreciate it on my desktop but it really shows up on my kindle - very neat.

  • Like 1
Link to comment
Share on other sites

 - Save for Web via Photoshop as PNG 

Don't use it for the original source image. Simply save as PNG (not with the SaveForWeb-Plugin). Would assume you get 800-1600k filesize then.

Upload it to site assets and do a test for the best quality / filesize:

	// you first need to install the PageImageManipulator

	$width     = 680;
	$qualities = array(10,20,30,40,50,60,70,75,80,85,90,95,100);
	$options   = array('sharpening'=>'none', 'cropping'=>false, 'upscaling'=>false, 'quality'=>100);  // options for the image sizeing: max quality without sharpening
	$amount    = 100;  // unsharpMask default values
	$radius    = 0.5;  //      "
	$threshold = 3;    //      "

	$image = $page->images->first();
	$image->removeVariations();

	foreach($qualities as $quality) {
		ini_set('max_execution_time', 15);
		$img = $image->pimLoad("{$width}_q{$quality}", true)->setOptions($options)->width($width, 'none')->unsharpMask($amount, $radius, $threshold)->setQuality($quality)->pimSave();
		echo "<p>Quality: {$quality} :: Filesize: " . filesize($img->filename) . "<br /><img src='{$img->url}' width='{$img->width}' height='{$img->height}' alt='{$img->name}' title='' /></p>\n";
	}

If you have found the best quality value for your images you may try different values with USM-sharpening. (it is the same like with photoshop)

  • Like 1
Link to comment
Share on other sites

hey ya!

thanks for sharing the code!

After some testing here are some intermediate results:

1. Resizing with PageImageManipulator gives better results than the build-in resizing

2. Exporting (like mentioned in Workflow 2) causes bigger PNGs than the original

3. I'll test much more with the PageImageManipulator. Seems this could be very(!) useful :)

Thanks for sharing!

@Joss: LR does not include PNG export. This has to be done with a plugin called MagicExport. With PIM it looks like I can export the good ol' JPG from LR and put it online directly without PS :)

Cheers!

Link to comment
Share on other sites

 ...

1. Resizing with PageImageManipulator gives better results than the build-in resizing

...

Glad to hear it gives better results for you now. But want to clarify that resizing with PiM is 100% identical with resizing from the build in ImageSizer. You have used another sharpening method with PiM. You used USM-sharpening which produces better results but is very slow as PHP-implementation for GD. But supports identical values for all three params as photoshop does.

Link to comment
Share on other sites

Hhhm, not enough time to go much further these days, but interesting stuff this ImageMagick. :)
 
Imagick can be setup as CMS (Color Management System). I have created a little colorTargetfile and a Testcase with files of different colorspaces, colordepth, with and without embedded ICC-profiles, including Adobe-RGB, ECI-RGB, sRGB, different CMYK and different Grayscale. The RGBs and CMYKs it seems I have covered already, grayscales are on the todo.
 
pw_imagick_cms_preview_01.png
 

  • Like 7
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By spercy16
      These issues should be fairly easy for any intermediate to advanced ProcessWire developer to answer. I'm new to PHP and relatively new to ProcessWire and just need a bit of help. What I'm trying to do is bring in a couple of cards from my Projects page to display on my home page. I finally got the code right to bring in the cards but right now they're using my original images instead of my resized "variations". So firstly, I would like to know how to reference the variations of my images instead of using the original. Secondly, I need to grab only four of the cards from the Project page and not import in all ten. It should be just two small changes to my code to do these things (I would imagine). Here is the code I currently have for that section:
      <?php // https://processwire.com/api/arrays/ // check if the array of images has items if (count($pages->get("/projects/")->images)) : // get array of images from the field $images = $pages->get("/projects/")->images; $count = 0; // iterate over each one foreach ($images as $image) : $count++; $sectionText = $pages->get("/projects/")->get("paragraph_$count"); $img = $image; $buttonCode = $pages->get("/projects/")->get("url_$count"); ?> <span id="card<?php echo $count?>" class="card"> <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" /> <div class="cardBody"> <div class="cardText"> <h2><?php echo $img->description; ?></h2> <?php echo $sectionText; ?> </div> <div class="primaryBtn"> <a href="https://www.paypal.com/donate?hosted_button_id= <?php echo $buttonCode; ?> &source=url"> <button> <i class="fas fa-donate"></i> Donate </button> </a> </div> </div> </span> <?php endforeach; endif; ?> Thanks in advance for any help!
    • By skeltern
      WebP image support is great and works fine. But once created I've issues to get rid of all API generated WebP variations.
      The backend image field variations "Delete" works and I can remove all variations JPEG plus WebP. Image list is clean but all WebP API variations are still stored in file system (for instance files/12345/84.900x675.webp etc). I can only use ImageSizer with temp 'force' option to request fresh WebP variations or have to delete WebP files from folders. No other way so far. Tested with 2 sites and latest master PW 3.0.165.
      Is there somewhere a "magic button" or config/setup thing to solve my sticky WebP issue?
    • By psy
      I've searched, and maybe missed, the solution. I have a 'normal' images field and uploading images with a file size greater than 10Kb is fine. Any image size smaller results in the never-ending spinner and no upload.
      No min/max width/height set on image uploads in admin, ie just the defaults.
      Any ideas on how to fix?
      Using:
      PW: 3.0.175
      PHP: 7.3
      Marking it as "Resolved" rather than "Solved" as it auto-magically fixed itself. No idea whether PW, PHP, or just an internet hiccough... All good now 🤞
    • By totoff
      Dear all,
      tomorrow I'll have to introduce some editors on how to upload and edit images in image fields in Processwire. The site in question is quite image rich and I've spent some time to serve the appropriate images via scrcset already cropped for different screen sizes.
      However, the backend offers a lot of possibilities to manipulate images and most of them I'm not familiar with because as a developer I've never spent much thinking on what all the features might be good for … Yet I'm concerned that my editors work on images in the backend may interfere with my optimization strategies in the templates.
      Is there a general rule of thumb what content editors should do or not do with images in order not to break srcset strategies etc.? Maybe there is already a source of information you could point me to?
      Your recommendations are much appreciated!
    • By totoff
      Dear all,
      I'm upgrading an older side with the new custom fields for images feature as of 3.0.142. My image field is set to "Automatic" and holds a bunch of images together with their respective description on each page. New custom fields include "caption" among others and to make my live easier I I'm trying to populate "caption" with the value from the (default) description field. But unfortunately I can't seem to find out how to save the newly set values. This is my code:
      <?php foreach (page()->images as $image) { $image->set('caption', $image->description); bd($image->caption); echo files()->render("markup/views/view-card-image-fancybox.php", array('image'=>$image)); } ?> <?php $page->save(); bd($page->save()); ?> This sets the value as intended (see screenshot) but doesn't save it permanently to the database. What am I doing wrong?
      Thanks!
       

×
×
  • Create New...