src/includes/classes/Core/Utils/Image.php
protected function compressPng(string $file, array $args = []): bool
    {
        if (!$this->c::canCallFunc('exec')) {
            return false;
        }
        $default_args = [
            'min_quality' => 0,
            'max_quality' => 0,
            'output_file' => '',
        ];
        $args += $default_args; // Defaults.

        if (!$file || !is_file($file)) {
            return false; // Not possible.
        }
        $args['min_quality'] = (int) ($args['min_quality'] ?: 60);
        $args['min_quality'] = max(0, min(100, $args['min_quality']));

        $args['max_quality'] = (int) ($args['max_quality'] ?: 90);
        $args['max_quality'] = max($args['min_quality'], min(100, $args['max_quality']));

        $args['output_file'] = (string) $args['output_file'];
        $args['output_file'] = $args['output_file'] ?: $file;

        $output_file_existed_prior = is_file($args['output_file']);

        $esc_file        = $this->c::escShellArg($file);
        $esc_output_file = $this->c::escShellArg($args['output_file']);
        $esc_quality     = $this->c::escShellArg($args['min_quality'].'-'.$args['max_quality']);
        exec('pngquant --skip-if-larger --quality='.$esc_quality.' --force --output='.$esc_output_file.' '.$esc_file, $_, $status);

        if ($status === 0) {
            return true; // Success.
            //
        } elseif (in_array($status, [98, 99], true)) {
            if ($args['output_file'] !== $file) {
                return copy($file, $args['output_file']);
            } else {
                return true;
            } // See `$ man pngquant` for further details.
            // `98` = --skip-if-larger, `99` = --quality min-max.
        } else {
            if (!$output_file_existed_prior && is_file($args['output_file'])) {
                unlink($args['output_file']);
            }
            return false;
        }
    }
protected function compressPng(string $file, array $args = []): bool
    {
        if (!$this->c::canCallFunc('exec')) {
            return false;
        }
        $default_args = [
            'min_quality' => 0,
            'max_quality' => 0,
            'output_file' => '',
        ];
        $args += $default_args; // Defaults.

        if (!$file || !is_file($file)) {
            return false; // Not possible.
        }
        $args['min_quality'] = (int) ($args['min_quality'] ?: 60);
        $args['min_quality'] = max(0, min(100, $args['min_quality']));

        $args['max_quality'] = (int) ($args['max_quality'] ?: 90);
        $args['max_quality'] = max($args['min_quality'], min(100, $args['max_quality']));

        $args['output_file'] = (string) $args['output_file'];
        $args['output_file'] = $args['output_file'] ?: $file;

        $output_file_existed_prior = is_file($args['output_file']);

        $esc_file        = $this->c::escShellArg($file);
        $esc_output_file = $this->c::escShellArg($args['output_file']);
        $esc_quality     = $this->c::escShellArg($args['min_quality'].'-'.$args['max_quality']);
        exec('pngquant --skip-if-larger --quality='.$esc_quality.' --force --output='.$esc_output_file.' '.$esc_file, $_, $status);

        if ($status === 0) {
            return true; // Success.
            //
        } elseif (in_array($status, [98, 99], true)) {
            if ($args['output_file'] !== $file) {
                return copy($file, $args['output_file']);
            } else {
                return true;
            } // See `$ man pngquant` for further details.
            // `98` = --skip-if-larger, `99` = --quality min-max.
        } else {
            if (!$output_file_existed_prior && is_file($args['output_file'])) {
                unlink($args['output_file']);
            }
            return false;
        }
    }
Compress PNG image.

@since 161011 Initial release.

@param string $file PNG file path.
@param array  $args Behavioral args.

@return bool True on success.

@see https://pngquant.org/php.html