#php #imagemagick
#php #imagemagick ( магия изображений)
Вопрос:
Я использую Imagick и расширение PHP Imagick в проекте для преобразования всевозможных изображений. Изображения предоставлены пользователями и будут преобразованы в миниатюры jpg заданного размера.
Это выполняется внутри docker-контейнера на основе php:7.4.12-cli
. В настоящее время я использую Imagemagick 6.9.7-4
установленный из исходного кода со следующей командой:
RUN apt-get update amp;amp; apt-get install -y libmagickwand-dev --no-install-recommends
RUN cd /usr/local/src amp;amp;
curl -L https://github.com/ImageMagick/ImageMagick6/archive/6.9.7-4.tar.gz --output Imagick-6.9.7-4.tar.gz amp;amp;
tar xvzf Imagick-6.9.7-4.tar.gz amp;amp;
cd ImageMagick6-6.9.7-4 amp;amp;
export CPPFLAGS=-I/usr/local/include amp;amp;
export LDFLAGS=-L/usr/local/lib amp;amp;
./configure --with-module amp;amp;
make amp;amp;
make install amp;amp;
ldconfig /usr/local/lib amp;amp;
cd .. amp;amp;
rm -rf /usr/local/src/Imagick-6.9.7-4.tar.gz ImageMagick6-6.9.7-4
Чтобы преобразовать изображения, я использую следующую функцию, которая на данный момент работает без каких-либо известных проблем
<?php
public static function resize(string $src, string $dst, int $width, $height = false, int $quality = 90) : bool {
if ($quality <= 0 || $quality > 100) {
throw new Exception(
"quality is out of range. must be between 1 and 100. '".$quality."' given"
);
}
// check if the source file exists
if (!file_exists($src)) {
throw new Exception(
"source file '".$src."' does not exist"
);
}
// check if imagemagick is installed
if (!extension_loaded("imagick") || !class_exists("Imagick")) {
throw new Exception(
"Imagick Extension is not loaded"
);
}
// create image
$img = ImageHelpers::newImagick($src);
// set backgroundcolor for transparent images and merge multiple layers to one
$img->setBackgroundColor(new ImagickPixel("#FFFFFF"));
$img = $img->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
// auto orientation
switch ($img->getImageOrientation()) {
case Imagick::ORIENTATION_BOTTOMRIGHT:
$img->rotateimage("#000", 180); // rotate 180 degrees
break;
case Imagick::ORIENTATION_RIGHTTOP:
$img->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case Imagick::ORIENTATION_LEFTBOTTOM:
$img->rotateimage("#000", -90); // rotate 90 degrees CCW
break;
}
// set new orientation in exif-data
$img->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
// resizes to whichever is larger, width or height
if ($height !== false) {
$img->thumbnailImage($width, $height, true);
} else {
$img->cropThumbnailImage($width, $width);
}
// set iterator to 0 on PSD and XCF Files
$ending = strtolower(substr($src, -3, 3));
if (in_array($ending, [ "psd", "xcf" ])) {
$img->setIteratorIndex(0);
}
// convert image to jpg
$img->setImageFormat("jpg");
// colorspace transformation
// only if imagick version is not 6.9.10-23 (1690)
// due to bug in imagick
// imagick generates segfault
$imagickVersion = Imagick::getVersion();
if ($imagickVersion['versionNumber'] ?? "" !== 1690) {
try {
// check if icc profiles exist
$profiles = $img->getImageProfiles("*", false);
$hasIccProfile = array_search("icc", $profiles) !== false;
// fetch colorspace of the image
$colorSpace = $img->getImageColorspace();
// if images does not have an assigned profile and is cmyk add a default profile
if ($hasIccProfile === false amp;amp; $colorSpace == Imagick::COLORSPACE_CMYK) {
$img->profileImage("icc", file_get_contents(TB_PATH_ROOT."_common/icc/USWebUncoated.icc"));
}
// if images does not have an assigned profile and is srgb add a default profile
if ($hasIccProfile === false amp;amp; $colorSpace == Imagick::COLORSPACE_SRGB) {
$img->profileImage("icc", file_get_contents(TB_PATH_ROOT."_common/icc/sRGB_v4_ICC_preference.icc"));
}
// set the new color profile
$img->profileImage("icc", file_get_contents(TB_PATH_ROOT."_common/icc/AdobeRGB1998.icc"));
} catch (Exception $e) {
// do nothing
// thumbnail creation will still work
}
}
// set image compression
$img->setImageCompression(Imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality($quality);
// remove destination-file if already exists
if (file_exists($dst) amp;amp; unlink($dst) === false) {
throw new Exception(
"destination file already exists but cannot be deleted"
);
}
// write image
$img->writeImage($dst);
// clear image from memory
$img->clear();
// all done, image was created
return true;
}
У меня есть соответствующие icc-файлы в данной папке, поэтому их можно использовать для настройки цветового профиля.
Теперь, как только я обновлюсь до Imagick 7 (7.0.10-43), у меня есть некоторые изображения, которые не были преобразованы правильно. У меня есть изображения в формате tiff, где цвета инвертированы. Даже если я удалю весь код преобразования, это все равно произойдет. Есть ли какие-либо известные изменения в Imagmagick, которые приводят к этим проблемам? Или есть какие-нибудь подсказки о том, где искать проблему?
Я разбил это, насколько это было возможно, и это также происходит со следующим кодом:
<?php
$src = __DIR__ . "/_common/_data/persistent/images/219.tif";
$dst = __DIR__ . "/output.jpg";
$img = new Imagick($src);
$img->writeImage($dst);
Это работает в Imagick 6.9.7-4
, но не в Imagick 7.0.10-43
. В 7 все изображение инвертируется.
Расширение php imagick устанавливается с pecl
RUN pecl install imagick amp;amp; docker-php-ext-enable imagick
С наилучшими пожеланиями, Дэвид
Комментарии:
1. Вы также должны опубликовать фрагмент простого кода, показывающий проблему, чтобы люди могли попробовать это. Кому-то очень трудно прочитать и попробовать ваш код таким, какой он есть. Вы обновили свои версии imagemagick и Imagick, поскольку они должны совпадать?
2. Привет, Бонзо. Спасибо за ваш ответ. Я изложил это так подробно, как только мог. Я использую этот код для тестов
$img = new Imagick($src); $img->writeImage($dst);
, в которых он работает,Imagick 6.9.7-4
но не вImagick 7.0.10-43
нем. В 7 все изображение инвертируется. Я устанавливаю расширение php сpecl
помощью . Есть ли лучший способ сделать это? Чтобы соответствовать установленной версии imagemagick?bash RUN pecl install imagick amp;amp; docker-php-ext-enable imagick