Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more detailed encoder control #1259

Open
olivervogel opened this issue Jan 9, 2024 · 7 comments · Fixed by #1260
Open

Add more detailed encoder control #1259

olivervogel opened this issue Jan 9, 2024 · 7 comments · Fixed by #1260
Assignees

Comments

@olivervogel
Copy link
Member

olivervogel commented Jan 9, 2024

Describe the feature you'd like
Add more detailed control on the encoding process. A settings object might be useful.

Settings to control

  • Compression Level (Quality)
  • Compression Type
  • Interlace Option
  • Bit Depth (Maybe because the supported bit depth is often linked to the image format)
  • ...

Example (draft)

$image->encode(new PngEncoder(
    quality: 65,
    compression: Compression::ZIP,
    interlace: true,
    depth: 8
));
@konnng-dev
Copy link

konnng-dev commented Jan 30, 2024

@olivervogel is there a plant to reintroduce interlacing images?

I'm working together w/ the creator of https://github.com/thephpleague/glide/ to bring support to intervention v3 and we did some tweaks to support interlacing on JPEGS there, but it won't work case Driver is Gd.

@olivervogel
Copy link
Member Author

Yes, there are plans to bring back interlaced support. However, the exact path is not clear yet.

The main thing to think about is how to handle the differences between GD and Imagick and where to set the interlace flag in the public API.

Also, "interlace" can mean different things for different formats. For example, GD with imageinterlace will produce progressive Jpeg data if a Jpeg is output at the end. The interlace bit is also closely related to the output format for the GIF format.

For this reason, I am currently considering integrating this feature into the encoding process. Which somehow makes sense, because after an image has been decoded it exists undefined and "normalized" as a GDImage or Imagick object in memory. At this point, an "Interlace" command makes less sense than when a (new) image format is defined again, namely for encoding.

@olivervogel
Copy link
Member Author

In version 3.6.0, the option of interlaced encoding of the GIF and PNG image formats was reintroduced. Furthermore, the Jpeg encoder now also offers the option of progressive encoding.

See documentation:
https://image.intervention.io/v3/basics/image-output#encoding-gif-format
https://image.intervention.io/v3/basics/image-output#encoding-png-format
https://image.intervention.io/v3/basics/image-output#encoding-jpeg-format

cc @konnng-dev

@konnng-dev
Copy link

konnng-dev commented Apr 22, 2024

@olivervogel Thank you for finding time for this update. I really appreciate the effort maintaining this awesome lib.

I was able to move on w/ my project regarding progressive JPEGs, but I ran in into another issue.

My code tries to detect which format I want to encode based on the format and set quality. But since now the encoders have its own parameters, it no longer works.

// ...
$encoded = $image->encodeByExtension(extension: $format, quality: $quality);
// ...

On the above example, $format is specified by dynamic argument. It can be "jpg", "png", "webp", "gif", etc. Same w/ $quality value.

The script throws the following Exception:

{ "message":"Unknown named parameter $quality"}

According to https://image.intervention.io/v3/basics/image-output#encode-images-by-file-extension, in theory it would be possible to specify the quality.

I think the situation is the encoders now has different set of arguments, which throws this exception.

Would be possible to support quality, regardless the encoder I choose?

@konnng-dev
Copy link

I ended up doing the following approach

//...
       $shouldInterlace = filter_var($this->getParam('interlace'), FILTER_VALIDATE_BOOLEAN);
       $encoderOptions = ['extension' => $format];
        switch ($format) {
            case FileExtension::AVIF->value:
            case FileExtension::HEIC->value:
            case FileExtension::AVIF->value:
            case FileExtension::TIFF->value:
            case FileExtension::AVIF->value:
            case FileExtension::JPG->value:
            case FileExtension::WEBP->value:
                $encoderOptions['quality'] = $quality;
            case FileExtension::JPG->value:
                $encoderOptions['progressive'] = $shouldInterlace;
                break;
            case FileExtension::GIF->value:
            case FileExtension::PNG->value:
                $encoderOptions['interlaced'] = $shouldInterlace;
                break;
            default:
        }

        $encoded = $image->encodeByExtension(...$encoderOptions);
//...

@olivervogel
Copy link
Member Author

Yes, this is unfortunately an issue in 3.6. But I'm already preparing a workaround that will be released very soon.

See also #1332

@konnng-dev
Copy link

Thanks for jumping right in, I'll be following #1332 then.

Feel free to mark this one as closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants