Jump to content
jacmaes

Webp support

Recommended Posts

On 4/27/2019 at 8:37 PM, horst said:

Please can someone test the .htaccess solution for WebP support in other environments?

It's working here on Windows and IIS 8.5

  • Thanks 1

Share this post


Link to post
Share on other sites

😎 Heya, success! This seems to be a reliable and resource-saving method to bring webp support to (existing) PW sites: .htaccess only 2.0 😎

(subtitle: learning more about htaccess directives)

When only calling webpUrl | webpSrc for all image sources, without any conditional markup, the whole site / page tries to get all images as webp files.

$options = ["webpAdd" => true];
$img = $page->images->first()->size(120, 120, $options);

echo "<img src='{$img->webpUrl}' alt='{$img->description}' />";

The new htaccess directives will check if the browser supports webp. If not, it redirects the webp requests to the jpeg or png variations. Also if the browser supports webp, but a webp file is not available (for what ever reason), the htaccess redirects to an existing jpeg or png file. So, it redirects, it does not only rewrite the URL. Look at this screenshot, the redirected request has the correct file extension:

webp-htaccess-only-two-dot-zero.thumb.png.f13e1eb5cdb7db0f1aefd0b7da902455.png

The new .htaccess directives:

Spoiler

AddType image/webp .webp

<IfModule mod_rewrite.c>

    RewriteEngine On
    AddDefaultCharset UTF-8

    ### Redirect regular PW WEBP images to JPEG where the WEBP is missing or
    ### if the Browser doesn't support WEBP:

        ## Does Browser NOT accept WEBP images?
        RewriteCond %{HTTP_ACCEPT} !image/webp    [OR]

        ## Or is it NOT an existing WebP file?
        RewriteCond %{REQUEST_FILENAME} !-f

        ## Does a JPEG file exist for it?
        RewriteCond %{DOCUMENT_ROOT}/$1$2$3/$4.jpg -f

    ## Is a regular PW JPEG image stored under site/assets/files for the requested webp file?
    RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.webp(.*)$  /$1$2$3/$4.jpg [R=301,L]
    
</IfModule>

 

To support png too, we need to copy the block and change .jpg to .png, or there is a way to implement both types into one block. We will see. 🙂

 

  • Like 6
  • Thanks 1

Share this post


Link to post
Share on other sites

I can't make this work on IIS as I don't know if mixed conditions are supported, as far as I know, you can either MatchAny or MatchAll. It will work If I omit the last rule and use MatchAny (IIS fans?).

But, how would we know what to serve to the browser if webp is either unsupported or doesn't exist, .jpg or .png or even something else?

Share this post


Link to post
Share on other sites

The regular pw htaccess file is full of [OR] conditions. So I would expect that this must be possible. 

My example currently checks for jpg only. It must be completed to also check for png. And it serves the file that it (first) detects. You can read it in the htaccess comments. 

Share this post


Link to post
Share on other sites
12 hours ago, matjazp said:

I can't make this work on IIS as I don't know if mixed conditions are supported, as far as I know,

@matjazp If sending webp first is not possible to you, you may use the initial htaccess solution, what already worked for you, but with the redirect in the rewrite rule (R=301):

AddType image/webp .webp

<IfModule mod_rewrite.c>

    RewriteEngine On
    AddDefaultCharset UTF-8

    ### Redirect regular PW JPEGs and PNGs to their WEBP image copies,
    ### if available and if the Browser supports WEBP:

        ## Does Browser accept WEBP images?
        RewriteCond %{HTTP_ACCEPT} image/webp

        ## Is it an existing file?
        RewriteCond %{REQUEST_FILENAME} -f

        ## Does a WEBP copy exist for it?
        RewriteCond %{DOCUMENT_ROOT}/$1$2$3/$4.webp -f

        ## With an added GET var or GET value of skiprewrite we do send the original JPEG or PNG
        RewriteCond expr "! %{QUERY_STRING} -strmatch '*skiprewrite*'"
        ## With an added GET var or GET value from the PW Page Editor, we do send the original JPEG or PNG
        RewriteCond expr "! %{QUERY_STRING} -strmatch 'nc=*'"

    ## Is it a regular PW JPEG or PNG image, stored under site/assets/files?
    RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.(jpe?g|png)(.*)$  /$1$2$3/$4.webp [R=301,L]

</IfModule>

 

  • Like 1

Share this post


Link to post
Share on other sites
9 hours ago, horst said:

The regular pw htaccess file is full of [OR] conditions. So I would expect that this must be possible. 

Yes, there are [OR] conditions in htaccess.txt, but they are all [OR], not a mixture of [OR] and [AND].

9 hours ago, horst said:

My example currently checks for jpg only. It must be completed to also check for png. And it serves the file that it (first) detects.

I understand that, but how would .htacces know if image.webp is "made" from image.png or image.jpg? How would you decide which one is first?

Also, when I upload image.webp I get "Pageimage: castle.0x260.webp - not a supported image type"

  • Like 1

Share this post


Link to post
Share on other sites

Maybe the most reliable way is:

$webpsupport = (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false);
if($webpsupport) {
  //serve webp
} else {
  //serve jpg or png or whatever
}

Of course, .htaccess is a viable solution...

  • Thanks 1

Share this post


Link to post
Share on other sites
3 hours ago, matjazp said:

I understand that, but how would .htacces know if image.webp is "made" from image.png or image.jpg? How would you decide which one is first?

I never have jpg and png files of the same variation name. So there will be only one type available. If you really create png and jpeg of the same variation, you have to work with suffixes. 

 

3 hours ago, matjazp said:

 

Also, when I upload image.webp I get "Pageimage: castle.0x260.webp - not a supported image type"

Webp is a (final) OUTPUTFORMAT only! You cannot use it as a pageimage. 

If you want to upload and use webp directly, you can use a file field. 

 

2 hours ago, matjazp said:

$webpsupport = (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false); if($webpsupport) {   //serve webp } else {   //serve jpg or png or whatever }

This one, maybe in site/config.php, is really usefull for conditional markup, as it can reduce it drastically. 👍

Share this post


Link to post
Share on other sites
4 hours ago, horst said:

Webp is a (final) OUTPUTFORMAT only! You cannot use it as a pageimage. 

If you want to upload and use webp directly, you can use a file field. 

Why not? Why is webp treated only as variation and not as other "normal" image?

I added this to /site/config.php:

$config->hasWebpSupport = (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false);
$config->imageSizerOptions = array_merge($config->imageSizerOptions, array(
    'webpAdd' => true
));

And in my template:

$img = $page->images->first();
$url = ($config->hasWebpSupport && $img->hasWebp) ? "urlWebp" : "url";
echo "<a href='{$img->$url}'>{$img->$url}</a>";
// this is actually php implementation of .htaccess rules

Then I uploaded image.jpg and found out that webp is generated only for admin thumbs and not for my uploaded image. I don't want to call size() as my uploaded image is already the way I wanted, I just need webp. Is this unsupported situation? Why do we need webp as admin thumb? I added:

$config->adminThumbOptions = array_merge($config->adminThumbOptions, array(
    'webpAdd' => false
));

and that fixed admin thumb webp creation, but of course there is no webp image. I then manually copied image.webp to the folder where image.jpg was uploaded and this time the image was correctly displayed in Chrome (that has webp support) and in IE (that lacks webp support). Maybe you could add another property to the image that would return the correct URL as in my template file?

Should webp extension be listed in /wire/config.php on $config->fileContentTypes?

Share this post


Link to post
Share on other sites

 

5 hours ago, matjazp said:

Why is webp treated only as variation and not as other "normal" image?

Because it is not a "normal" image format by its intended purpose!

 

5 hours ago, matjazp said:

Then I uploaded image.jpg and found out that webp is generated only for admin thumbs and not for my uploaded image. I don't want to call size() as my uploaded image is already the way I wanted, I just need webp. Is this unsupported situation? 

 

As far as I understood, you upload already compressed images that you don't want to proceed further? Note:

1) Already (not lossless) compressed images should not be used for any transformation, because the images are lacking lots of information due to the compression. (like the webp format!)

2) If you do not want to use the resize functionality, you have to provide the final webp by yourself too. PW only provides webp support for PW created variations for final output. This is due to the file formats nature or its intended purpose.

 

5 hours ago, matjazp said:

Why do we need webp as admin thumb?

Maybe you don't want or need a webp variation for admin thumbs. Maybe other users don't care. Maybe some users really like it when opening a editor page with 300 images displayed as admin thumbs.
I cannot answer this other then: It may depend on a lot of different things?

 

I really would like to discuss the general webp support first, and the less common use cases like this later on, in a following fine tuning phase.

 

-----------

AFAIK the most common case is to use the pageimage system with uploaded uncompressed images that serves as master images.

Those master images are never get served to the outside "as is".

They every time get transformed into a variation file that is optimized and finalized for a specific purpose! 

At least this is the only correct way for an error-free workflow with maximum possible quality combined with smallest possible file size!

Whether people understand this or not, my almost 30 years of expertise in the photographic industry has never shown me anything else.
And all my work within the PW images system is (and only can be) based on this.

-----------

 

I know that there also is a minor usage of the pageimage fields for simply displaying the original files to the frontend, but my best bet is that this is much lower then 10%. In my opinion this is not the intended use case for pageimages.
The use of a file field would suffice, if it also could display an admin thumbnail in the backend. 
But because this functionality is missing in a file field, pageimage fields are used as "compromise solution" for this purpose.

 

  • Like 5

Share this post


Link to post
Share on other sites
11 minutes ago, horst said:

Because it is not a "normal" image format by its intended purpose!

Hm, the intended purpose for the image (regardless of the format) is to be displayed on the screen, no? How is webp different in that context?

13 minutes ago, horst said:

I really would like to discuss the general webp support first, and the less common use cases like this later on, in a following fine tuning phase.

Noted.

Share this post


Link to post
Share on other sites
2 hours ago, matjazp said:

Hm, the intended purpose for the image (regardless of the format) is to be displayed on the screen, no? How is webp different in that context?

No, as written two posts above, we have different purpose images. There could be, for example, uncompressed master images that serves as source and should not be displayed on screen! Following I show some more image file purposes, but want to start with a brief introduction to image processing procedures.

 

Within a web environments very limited support, our master source images have to be uncompressed JPGs with 8 bit color depth per channel. Far from optimal. In other environments TIFF or PSD in 16 or 32 bit color depth is used for that purpose.

The destructive compression method of JPGs is responsible for most of the user errors that occur during the processing steps. Once you saved a JPG compressed within a workflow, as source or intermediate, you damaged it unrecoverable! And one also cannot detect this programmatic within a common web environment! This is one reason why we keep the master source, the original image untouched, "as is" in PW! (besides other aspects)

So, for our use cases, the JPG format can have different purposes: uncompressed master source images, uncompressed intermediate variations, final optimized and compressed variations for screen output.

Also, if one has a use case for it, one can optimize and finalize JPGs only for the purpose of printing in PW. Or for embedding them into PDFs, or for serving them as single files or as zipped archives for different purposes per downloads. So, it's not: "all get displayed on screen". Some never should be displayed on screen. (I maintain sites for photographers who keeps 60k+ images as original (pw master source) images in the site. They only publicly show watermarked images within limited dimensions. The original images are protected against web access. And they are used for all the different above listed output purposes.)

 

Luckily with the WebP format it behaves different. Due to its intended purpose, (that is, highly compressed and optimized for screen output), it is unusable for all other purposes!
Sure, if you want to or don't care about anything, you can use everything wrong, but it is not that subtle like with JPGs. In German we have a saying: "gefährliches Halbwissen" ("dangerous half-knowledge"). No idea whether one can translate the sense connected with it by DeepL? But it means something like: If you already know a good part, you quickly run the risk of drawing (wrong) conclusions about the unknown parts.

Personally, I am always happy when I get explanations, help or advice from people who have more specialist knowledge. After all, I can't know everything myself, right? 😎
One of my most important life experiences & wisdoms to fight against my "gefährliches Halbwissen": "If there are many people who study and learn for years to get a vocational qualification before they can "really" get into the subject, then I know that a huge part of it is invisible to me, even if I think I already understand a lot of it.". 

 

 

  • Like 8

Share this post


Link to post
Share on other sites

Just wanted to add, that using one highly compressed WebP image as source image also would be bad for using responsive images, which is highly recommended to use, because of all those different devices with different screen resolutions. For responsive images you need generated variations of a uncompressed source image. 😉

  • Like 2

Share this post


Link to post
Share on other sites
3 hours ago, AndZyk said:

Just wanted to add, that using one highly compressed WebP image as source image also would be bad for using responsive images, which is highly recommended to use, because of all those different devices with different screen resolutions. For responsive images you need generated variations of a uncompressed source image. 😉

Not that it really matters, but until now I was unaware that WebP even supported "lossy" compression for PNG images. Turns out that for PNGs one can indeed use either WebP-lossless or WebP-lossy, while for JPGs you're obviously always using WebP-lossy 🙂

Thanks to @horst for explaining the use cases!

I did also wonder why we wouldn't want WebP source images. Technically I still think that it could make sense (ProcessWire can be used for a number of use cases, but "displaying images online" is still the most popular one by a wide margin), but it isn't really such a big deal. Not to mention that I'm not sure how well supported WebP manipulation operations are (in GD/Imagemagick).

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, teppo said:

while for JPGs you're obviously always using WebP-lossy

I think it is independent from the source. The compression is set for the output format, that is webp, regardless what was the source format. It can be JPEG, PNG, GIF, TIFF, BMP or any other image file format that can be opened by the proceeding rendering engine. (For IMagick most often one out of 230+)

In this context, we can use lossless for sources from JPEGs too. But because in my tests it seems to be exact or nearly the same like quality 100, I had not seen a valid reason to bloat our imageSizerOptions with another setting, what then would need to be checked for its existence and compared against webpQuality. Also: HINT:  if one passes wrong values for webpQuality, out of range (1-100), the webp rendering method automatically falls back to lossless. So if you use 100 or anything above 100 for webpQuality, you get lossless. 🙂

  • Like 3

Share this post


Link to post
Share on other sites
Posted (edited)

Regarding compression and quality | webpQuality | lossy | lossless and how different the two rendering engines work, I want to show a little example, comparing two image motives with equal dimensions.

I have created two master source images in the dimensions 3000 x 2000 px. The first one is a 24bit color jpeg, filled with noise in Photoshop. The second one is a checkerboard with 100x100 squares, only black and white, but also saved as 24bit color jpeg.

I don't want to scare or confuse anybody. Look at the following tables with the file sizes for the different qualities, rendering engines and output formats. (Just let it sink, ...)

2019-05-06_203056_comparison_ps-noise_vs_checkerboard__gd_vs_im.thumb.png.c36fdd00549a6ca9b7e45ce5b59622a9.png

Really interesting are the results of the IM files in 100% quality, compared to their jpegs and compared between both motives. 🙂

 

EDIT:

And here two more real world motives, but also with interesting IM 100 quality results:2019-05-06_215023_realworld-motives-1.thumb.png.e0502867e2dbce712cbc2228f70dec8b.png

Edited by horst
added 2 "real world motives" :)
  • Like 9

Share this post


Link to post
Share on other sites

Just want to thank @horst for all his work on the WebP integration and the effort for explaining many things (of which I am aware, because I also have a background in image retouching and stuff, but most people do not).

  • Like 3

Share this post


Link to post
Share on other sites

Hi @horst

Following your guides complete and having set quality to 100 every step of the way. Imagick is set to no sharpening and 100 output. I'm getting really bad banding in dark areas when an image is being resized. I can't imagine anything more I can do my side for this? Everything is at 100 quality so it shouldn't degrade. 

This is the original image: 
https://www.dropbox.com/s/0qh0fvg8ldfqxn5/060618-peter_paul00667-luke-hayes-edit.jpg?dl=0

Here is the image resized to 3840 x 2160 (for retina 4k displays):
https://www.dropbox.com/s/gjtcl9vxtzmekp9/060618-peter_paul00667-luke-hayes-edit.3840x2160.jpg?dl=0

And here are where things get bad, resized to 1920 x 1080:
https://www.dropbox.com/s/ihgwmp20gn2yvze/060618-peter_paul00667-luke-hayes-edit.1920x1080.jpg?dl=0

You can really start to see banding in the darker areas. Do you have any suggestions for this? I've done the correct photoshop formatting as said in your previous post. 

 

EDIT: Example 2

Original image: 
https://www.dropbox.com/s/rokphzpd1s225as/No_Bounds_Image_Large.jpg?dl=0

ProcessWire resize at 100 quality:
https://www.dropbox.com/s/8phrl60fzjfmvnq/no_bounds_image_large.1920x1080.jpg?dl=0

  • Like 1

Share this post


Link to post
Share on other sites

@Tom., I tried resizing your original image and could see the banding issue when using GD for image resizing with the default gamma correction.

The banding issue doesn't occur when using the ImageMagick resize engine, or when using the GD resize engine if gamma correction is disabled.

Disable gamma correction for individual image resize:

$page->image->size(1920, 1080, ['defaultGamma' => -1])->url

Or disable gamma correction globally in /site/config.php

$config->imageSizerOptions('defaultGamma', -1);

 

  • Like 4

Share this post


Link to post
Share on other sites
10 hours ago, Robin S said:

@Tom., I tried resizing your original image and could see the banding issue when using GD for image resizing with the default gamma correction.

The banding issue doesn't occur when using the ImageMagick resize engine, or when using the GD resize engine if gamma correction is disabled.

Disable gamma correction for individual image resize:


$page->image->size(1920, 1080, ['defaultGamma' => -1])->url

Or disable gamma correction globally in /site/config.php


$config->imageSizerOptions('defaultGamma', -1);

 

Thanks Robin, it seems to be the Gamma correction causing the issue here. Thank you 🙂

  • Like 2

Share this post


Link to post
Share on other sites

Yep, but this is only with the GD lib. Unfortunatly the gamma correction brings some advantages for most the images, but is worth for images with very dark parts. 

Maybe I should check out if we can detect such candidates on upload and flag them for automatic disabling gamma correction (whit GD). But currently I have no clue if this can be done with reasonable accuracy. 

  • Like 1

Share this post


Link to post
Share on other sites
19 hours ago, horst said:

Maybe I should check out if we can detect such candidates on upload and flag them for automatic disabling gamma correction (whit GD). But currently I have no clue if this can be done with reasonable accuracy. 

@Robin S I have created a first shot for this. Maybe you have time to take at look at it and play around a bit. I'm very interested in your opinion and how we should finish this.

 

Spoiler

<?php

$filenames = array(
    './060618-peter_paul00667-luke-hayes-edit.jpg',
    './checkerboard.jpg',
    './photoshop_noise.jpg',
    './oldtimer.jpg'
);
foreach($filenames as $filename) {
    echo "\n{$filename}:\n";
    $nums = hnGetHistoNumbers($filename);
    hnGetHistoDarkCalculation($nums);
}




function hnGetHistoDarkCalculation($idxCount) {
    $totals = 0;
    foreach(array_values($idxCount) as $val) $totals += $val;
    $dark = $idxCount[0] + $idxCount[1];
    $midDark = $idxCount[2] + $idxCount[3];
    $midLight = $idxCount[4] + $idxCount[5];
    $light =  $idxCount[6] + $idxCount[7];


    mvd([
        intval($dark / $totals * 100),
        intval($midDark / $totals * 100),
        intval($midLight / $totals * 100),
        intval($light / $totals * 100),
        '----------',
        intval(($dark + $midDark) / $totals * 100),
        intval(($light + $midLight) / $totals * 100),
    ]);


}


function hnGetHistoNumbers($filename) {
    // create a grayscale image from original
    $im = imagecreatefromstring(file_get_contents($filename));
    imagefilter($im, IMG_FILTER_GRAYSCALE);
    $w = imagesx($im);
    $h = imagesy($im);
    // make sure to have landscape dimensions
    if($h > $w) {
        imagerotate($im, 90, imagecolorallocate($im, 0, 0, 0));
        $w = imagesx($im);
        $h = imagesy($im);
    }
    // create a proof image with max 200 px
    $proofWidth = $w;
    $proofHeight = $h;
    if($proofWidth > 200) {
        $proofWidth = 200;
        $proofHeight = intval($proofWidth / 100 * intval($h / $w * 100));
    }
    $proof = imagecreatetruecolor($proofWidth, $proofHeight);
    pwgdengine_prepareImageLayer($proof, $im, $filename);
    imagecopyresampled($proof, $im, 0, 0, 0, 0, $proofWidth, $proofHeight, $w, $h);
    imagedestroy($im);
    // get the HistoNumbers from proof image
    $idxCount = [];
    foreach(array_keys(hnGetHistoIndexes()) as $k) $idxCount[$k] = 0;
    for($x = 0; $x < $proofWidth; $x++) {
        for($y = 0; $y < $proofHeight; $y++) {
            $idx = hnGetHistoColorAt($proof, $x, $y);
            if(isset($idxCount[$idx])) $idxCount[$idx] += 1;
        }
    }
    imagedestroy($proof);
    return $idxCount;
}


function hnGetHistoColorAt(&$imGrayscale, $x, $y) {
    $rgba = hnGetColorAt($imGrayscale, $x, $y);
    $num = $rgba[0];
    foreach(hnGetHistoIndexes() as $idx => $midValue) {
        if($num >= $midValue - 16 && $num <= $midValue + 15) {
            return $idx;
        }
    }
    return -1;
}

function hnGetColorAt(&$im, $x, $y) {
    $r = $g = $b = $a = -1;
    if(is_resource($im)) {
        $rgba = imagecolorat($im, $x, $y);
        $r = ($rgba >> 16) & 0xFF;
        $g = ($rgba >> 8) & 0xFF;
        $b =  $rgba & 0xFF;
        $a = ($rgba & 0x7F000000) >> 24;
        // $a = alpha, contain the TRANSPARENCY (NOT OPACITY) level.
        // So 127, the max, would be completely transparent, and 0 would be completely opaque.
    }
    return array($r, $g, $b, $a);
}

function hnGetHistoIndexes() {
    return array(0 => 16, 1 => 48, 2 => 80, 3 => 112,  4 => 144, 5 => 176, 6 => 208, 7 => 240);
}















/**
 * Prepares a new created GD image resource according to the IMAGETYPE
 *
 * Intended for use by the resize() method
 *
 * @param GD -resource $im, destination resource needs to be prepared
 * @param GD -resource $image, with GIF we need to read from source resource
 *
 */
function pwgdengine_prepareImageLayer(&$proof, &$im                           , $filename) {
                                                                                $imageType = exif_imagetype($filename);
    if($imageType == IMAGETYPE_PNG) {
        // @adamkiss PNG transparency
        imagealphablending($proof, false);
        imagesavealpha($proof, true);

    } else if($imageType == IMAGETYPE_GIF) {
        // @mrx GIF transparency
        $transparentIndex = imagecolortransparent($im);
        $transparentColor = $transparentIndex != -1 ? @imagecolorsforindex($im, $transparentIndex) : 0;
        if(!empty($transparentColor)) {
            $transparentNew = imagecolorallocate($proof, $transparentColor['red'], $transparentColor['green'], $transparentColor['blue']);
            $transparentNewIndex = imagecolortransparent($proof, $transparentNew);
            imagefill($proof, 0, 0, $transparentNewIndex);
        }

    } else {
        $bgcolor = imagecolorallocate($proof, 0, 0, 0);
        imagefilledrectangle($proof, 0, 0, imagesx($proof), imagesy($proof), $bgcolor);
        imagealphablending($proof, false);
    }
}


function mvd($v, $out = 2) {
    $fn = 'C:/bin_local/php_includes/hn_basic.class.php';
    if(file_exists($fn)) require_once($fn);
    if(class_exists('hn_basic')) {
        $hn = new hn_basic();
        return $hn->my_var_dump($v, $out);
    }
    var_dump($v);
}

 

 

Spoiler

image-histo-zip-content.png.8fc41df4478478ea1561044c93861228.png image-histo-output.png.67d0e381eafc3a2f246d5de9cc812989.png

 

image-histo-test.zip

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
11 hours ago, horst said:

I have created a first shot for this

Awesome that you are tackling this, but it goes way over my head I'm afraid so I don't think I'll be much help.

I never see any of these gamma correction issues because all my sites use the ImageMagick resizer engine. Which raises the question: does ImageMagick not need gamma correction, or is it just not possible to do gamma correction with IM? Put another way: is the gamma correction a strength or weakness of the GD engine? If the IM engine avoids the gamma correction issue and is generally a better choice for resizing do you think the PW installer should check for IM support and automatically install the IM engine when IM is available?

Share this post


Link to post
Share on other sites
Posted (edited)
6 hours ago, Robin S said:

Which raises the question: does ImageMagick not need gamma correction, or is it just not possible to do gamma correction with IM?

ImageMagick does use this too, but do produce correct results when it is setup to work in 16 bit colordepth mode. And thats the main difference: IMagick can do this and GD only supports 8 bit colordepth mode. When working in 8 bit colordepth mode like the GD, the workaround with gammacorrection applies good results for the middark to white parts, but the very dark parts get masacred. A very good explanation with examples can be found here: http://www.ericbrasseur.org/gamma.html

( One of my personal favorite quotes on Eric Brasseur site is down in Solutions/Conclusions, regarding Adobe Photoshop:

Quote

Some software allow you get a proper gamma-handling if you ask for it. In some cases, the software is quite expensive and intended for common photographs. Then the fact that the images are handled incorrectly by default is a shame. In other cases, the software was always intended to be used by trained professionals. Then, well... you have to know the tools of your trade...

)

 

6 hours ago, Robin S said:

Put another way: is the gamma correction a strength or weakness of the GD engine?

It is a possible workaround to get overall better results with resizing/downsizing then it would be without it. But not for very dark parts!

 

6 hours ago, Robin S said:

do you think the PW installer should check for IM support and automatically install the IM engine when IM is available?

Let Ryan answer this: https://github.com/processwire/processwire-issues/issues/465#issuecomment-363045136  🙂

 

Edited by horst
added links to IMagick engine
  • Like 3

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Kiwi Chris
      In the RTE, when inserting a link, there are several input fields that can be used to select a page, including a text input field that will auto-complete with pages on the site.
      When inserting an image, there is only an option to navigate the page tree. (equivalent to the second input option 'Select Page...' on the Insert Link screen from the RTE.
      When inserting an image from another page buried somewhere in the page tree, if you know the name of the page, it would often be quicker to use an auto-complete text field than 'Select Page...' option.
      It would be nice if the image insertion dialog offered the same functionality as the link insertion dialog so that when selecting a page it's possible to choose either to navigate the page tree, or have a text auto-complete field.
    • By Brian Scramlin
      I just wanted to share that I added an AJAX-powered gallery to an artist website that I developed and host: https://jackpinecreations.com/gallery/

      There were two things that frustrated me about creating this. Perhaps you can show me a better way.
      1. After creating my processing script, which I placed under /templates/scripts/get-items.php, I realized that I would get a 403, due to ProcessWire's routing and security. This forced me to have to create a template and page for this little script. This was frustrating simply because it seemed unnecessarily confusing. But worse, see #2.
      2. I usually use config.php to prepend and append each of my templates with a head.inc and foot.inc, which keeps my templates easy to use and I don't have to go and use the GUI to do so on each template separately. However, since I realized I needed to create a new template and page so as to access it, whenever I sent POST params to it, I would get the header and footer along with it!!! I could find no workarounds and had to remove the pre/append calls in config.php and use the GUI on each template individually.  
      Code Below if you're interested:
      HTML and JavaScript (forgive my sad JavaScript skills, I know this can be tightened up)
      <!-- Begin Grid --> <div class="container mt-4"> <div id="gallery" class="row"> <?php foreach ($page->children("limit=9") as $child): ?> <div class="col-6 col-md-4 gallery-item"> <a href="<?= $child->url ?>" title="View <?= $child->title ?>"> <img class="gallery-item" src="<?= $child->item_featured_image->size(640, 640)->url ?>" alt="<?= $child->title ?> Image"> </a> </div> <?php endforeach; ?> </div> </div> <!-- End Grid --> <div class="center-block text-center"> <button id="get-more-items" type="button" name="get-more-items" class="btn-vintage">Load More</button> </div> <script type="text/javascript"> var buttonGetItems = document.getElementById("get-more-items"); var indexStart = 0; buttonGetItems.addEventListener("click", function() { indexStart += 9; $.ajax({ url: '<?= $pages->get(1186)->url ?>', type: "POST", dataType:'json', // add json datatype to get json data: ({page_id: <?= $page->id ?>, index_start: indexStart}), success: function(data){ console.log(data); if (data[1]) { //for each element, append it. $.each(data, function(key, value) { $("#gallery").append(value); }); } else { $("#get-more-items").after('<p class="center-block text-center">There are no more items to load.</p>'); $("#get-more-items").remove(); } } }); }); </script> Processing Script
      <?php $items_array = []; $i = 0; foreach ($pages->get($input->post->page_id)->children->slice($input->post->index_start, 9) as $child) { $i++; $items_array[$i] = "<div class='col-6 col-md-4 gallery-item'> <a href='$child->url' title='View $child->title'> <img src='{$child->item_featured_image->size(640,640)->url}' alt='$child->title Image'> </a> </div>"; } echo json_encode($items_array); I love ProcessWire for hundreds of reasons, but I've been using AJAX more and more, and I'm not liking having to create templates to access scripts. 
      Any advice?
    • By Inxentas
      I have an image gallery based on an Image field with about 300 images in it. That caused a little issues with uploading, since it's on a shared host I had to do that piecemeal in order to not overload the server. I kept refreshing the frontend of that page to make sure the server doesn't run out of memory compressing the images, as such an amount obviously requires thumbnails. After 160 images the frontend no longer updates. I can add images to the backend, but they are not shown on the frontend. The images field is not limited in any way. Is there a cap to the amount of images uploaded to a single field? Or any other aspect that might explain such behaviour?
      The images show up fine in the backend, but when I foreach() through that field I only get 160 results. Any idea what might be going on?
    • By ODDCODE
      Hi, 
      I am sure this question may been asked but I couldn’t find it in the forum. I am new to using Processwire CMS/CMF. I read great reviews on CMS blog about Processwire. So I decided to give It a try. I am trying to figure out what is the best way to structure a simple gallery. I will also need to be able to catalog the photos. 
      Thank you, 
    • By RicknRoller
      Hi there!
      I am quite new to processwire and am just finishing my first PW project. I think the whole framework is awesome and could profit a lot from all the tutorials available. One thing that I somehow can't seem to get my head around is working with images and their resizing. I have following scenario:
      A 'gallery-index' page with its 'gallery' children. Those children have an 'images' field where the user uploads his (often too big) images.
      I am working with twig. On the gallery page frontend I have a slider, a displayed collection of all the images and a hidden one where I get the source to the original image in a popup. So in total the images will be outputted 3 times in different sizes.
      First:
      <div id="slick"> {% for img in page.images %} <img src="{{ img.height(400).url }}" alt=""> {% endfor %} </div> Second:
      <div class="gallery"> {% for img in page.images %} <img src="{{ img.width(300).url }}" alt=""> {% endfor %} </div> Third:
      <div class="hidden"> {% for img in page.images %} <a href="{{ img.maxWidth(1024).url }}" data-original="{{ img.url }}"></a> {% endfor %} </div> Now, the loops basically work, and some images are displayed the right way. But not all of there are displayed at all, despite them being there in the DOM. The urls all look right but some will be displayed and some url just go to a small black box image. How comes that PW manages to have different results in displaying the images in different formats?
      URL of gallery: http://2019.hclaupersdorf.ch/fotos/hc-laupersdorf-vs-ruschlikon-chiefs/ (there are more in the DOM than displayed)
      URL of 'not working' image: http://2019.hclaupersdorf.ch/site/assets/files/2361/20180616-rueschlikon-21_42049612175_o.300x0.jpg
      Furthermore, whenever this error occurs (which usually is at every page request on the gallery page), the DOM doesn't fully load. My JS for init the slider or the popup won't be loaded and the page is basically displayed half-loaded.
      Any ideas or suggestions on how to work around it, best practice when handling images & galleries?
      Thanks!
×
×
  • Create New...