Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 386 · После объектов, файлов и базовых операций с изображениями

Imagick: девять превью параметров и настоящий размер JPEG в байтах

Выбрать gamma по настоящему листу, отдельно обработать исходник и измерить сохранённый файл, не путая байты с геометрией или будущим экспортом.

Увидеть варианты gamma и получить отдельный готовый JPEG

Для карточки товара нужно подобрать осветление рисунка, затем получить JPEG понятного размера. Сначала посмотрим настоящий контактный лист gamma: библиотека сама рассчитала восемь вариантов и оставила центральную миниатюру эталоном. После выбора 1.4 мы явно применим его к полному исходнику, сохраним JPEG85 и измерим уже готовый файл.

Подлинный нативный лист gamma и отдельно сохранённый выбранный вариант; центральная ячейка показывает исходную миниатюру
Подлинный нативный лист gamma и отдельно сохранённый выбранный вариант; центральная ячейка показывает исходную миниатюру

На листе видны gamma 0.2,0.6,1,1.4, исходная миниатюра,1.8,2.2,2.6,3. Это варианты просмотра, а не готовый выбор за пользователя. Полный лист 766 × 936 доступен как отдельный нативный PNG без уменьшения. Необработанные подписи центральной ячейки %f/%G/%b оставлены как их вывела эта версия; русская внешняя легенда объясняет их смысл и не перерисовывает результат.

$sheet = $source->previewImages(Imagick::PREVIEW_GAMMA);
$chosen = clone $source;
$chosen->gammaImage(1.4);

$source — объект с исходным изображением; -> вызывает метод этого объекта. Imagick::PREVIEW_GAMMA — именованная целочисленная константа, выбранный тип просмотра. $sheet получает реальный новый объект с контактным листом. clone создаёт другую рабочую копию исходника, а gammaImage(1.4) отдельно меняет её: previewImages не сделал этот выбор автоматически. Запись 1.4 — число с десятичной точкой, не строка. Полный пример затем сохраняет выбранную картинку и читает число байтов отдельным getter. Переменные, объекты и clone разобраны отдельно.

Выбрать gamma на настоящем листе и отдельно получить готовый JPEG

Получен подлинный лист из девяти вариантов gamma; затем выбор 1.4 отдельно применён к исходнику 400 × 320. selected-gamma85.jpg действительно записан и открыт заново; его конкретные байты и сверка с filesize находятся в metrics.json. Лист не применяет выбранный эффект автоматически.

Выбрать gamma на настоящем листе и отдельно получить готовый JPEGПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$sheet=$source->previewImages(Imagick::PREVIEW_GAMMA);
$chosen=clone $source;
$chosen->gammaImage(1.4); // An explicit choice, not an automatic tile selection.
$chosen->setImageFormat('jpeg');$chosen->setImageCompressionQuality(85);
$beforeWrite=$chosen->getImageLength();
$chosen->writeImage(__DIR__.'/selected-gamma85.jpg');
$reopened=new Imagick(__DIR__.'/selected-gamma85.jpg');
$bytes=$reopened->getImageLength();
clearstatcache(true,__DIR__.'/selected-gamma85.jpg');
$disk=filesize(__DIR__.'/selected-gamma85.jpg');
pfFirstProof($source,$sheet,$chosen,$reopened,$beforeWrite,$bytes,$disk,$before);
echo "preview-file-size-first.png\nsource-preview8.png\nselected-gamma8.png\nselected-jpeg8.png\nselected-gamma85.jpg\nmetrics.json\npreview=Imagick source-unchanged=1 export-saved=1 length-matches-file=1\n";

Получен подлинный лист из девяти вариантов gamma; затем выбор 1.4 отдельно применён к исходнику 400 × 320. selected-gamma85.jpg действительно записан и открыт заново; его конкретные байты и сверка с filesize находятся в metrics.json. Лист не применяет выбранный эффект автоматически. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-first.png
source-preview8.png
selected-gamma8.png
selected-jpeg8.png
selected-gamma85.jpg
metrics.json
preview=Imagick source-unchanged=1 export-saved=1 length-matches-file=1

Разделить миниатюры, выбранное действие, экспорт и единицы размера

Контактный лист помогает выбрать параметр; только отдельный экспорт полного исходника создаёт файл, длину которого можно измерить
Контактный лист помогает выбрать параметр; только отдельный экспорт полного исходника создаёт файл, длину которого можно измерить
ШагЧто происходит
previewImages(PREVIEW_GAMMA)Новый лист: восемь обработанных миниатюр и центральная исходная. Источник остаётся прежним.
Явно выбранное 1.4gammaImage применяется к новой копии полного рисунка 400 × 320, а не к вырезанному и увеличенному тайлу.
writeImageJPEG-кодек создаёт файл с выбранной quality; до этого будущий размер не обязан быть известен.
new Imagick + getImageLengthЗаново читается конкретный файл; getter возвращает его текущую длину.
filesizeНезависимая сверка с файловой системой; clearstatcache сбрасывает PHP-кэш сведений об этом файле.

Контактный лист похож на пробную полосу фотографа: помогает увидеть направление изменения, но не заменяет обработку полного кадра. В Core сначала создаются уменьшенные thumbnails, затем монтаж 3 × 3 с рамками, тенью и подписями. Он сам по себе не содержит интерфейс выбора ячейки и не возвращает массив настроек. Число изображений в возвращённом Imagick равно 1, хотя нарисовано девять ячеек.

Байты файла, геометрия и память — разные величины. У исходника 400 × 320 число пикселей равно 128 000, но это не число байтов JPEG. Метаданные, алгоритм кодирования, quality и содержимое влияют на итоговый файл; getter не является оценщиком этой будущей величины. Подробнее: сжатие и качество, геометрия и файлы.

Запустить короткий preview и отдельно прочитать размер существующего файла

Один прямой preview-вызов создаёт настоящий лист; getter отдельно читает байты подготовленного JPEG
Один прямой preview-вызов создаёт настоящий лист; getter отдельно читает байты подготовленного JPEG

Каждый архив содержит собственный нормализованный RGB8 PNG. pfRestore восстанавливает его из base64 и проверяет SHA, pfSource открывает файл. pfView сохраняет отдельную PNG8-копию объекта без масштабирования и подмены подписей; pfPreviewProof записывает реальный тип, размеры и неизменность источника. Эти вспомогательные функции не вызывают previewImages вместо вас: изучаемая строка остаётся видна в следующей короткой программе.

Одним вызовом получить новый объект с контактным листом

В этой сборке возвращён новый Imagick 766 × 936 с одним изображением-контактным листом. Это не bool и не массив из девяти объектов. Оригинальный источник не изменён.

Одним вызовом получить новый объект с контактным листомПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$sheet=$source->previewImages(Imagick::PREVIEW_GAMMA);
pfPreviewProof($source,$sheet,$before);
echo "preview-file-size-preview.png\npreview-source8.png\nmetrics.json\npreview=Imagick native-size=766x936 images=1 source-unchanged=1\n";

В этой сборке возвращён новый Imagick 766 × 936 с одним изображением-контактным листом. Это не bool и не массив из девяти объектов. Оригинальный источник не изменён. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-preview.png
preview-source8.png
metrics.json
preview=Imagick native-size=766x936 images=1 source-unchanged=1
$image = new Imagick('test.jpg');
echo $image->getImageLength() . ' bytes';

Это полный короткий официальный пример getter, предполагающий существующий test.jpg. Круглые скобки getter пустые, поскольку параметров нет. Точка между выражениями соединяет число и строку bytes для вывода; echo печатает текст, а не картинку. Чтобы запустить аналог без внешнего файла, подготовим свой JPEG85, откроем его заново и сделаем тот же вызов. Здесь 10 008 — реальные байты конкретного проверенного файла, а не универсальный размер quality 85.

Прочитать число байтов настоящего заново открытого JPEG

Подготовлен собственный JPEG85 и заново открыт: getImageLength вернул 10 008 байт, столько же насчитала файловая система. Размеры 400 × 320 — отдельные величины. Число относится к точному рисунку и проверенной версии кодека.

Прочитать число байтов настоящего заново открытого JPEGПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$image=clone $source;
$image->setImageFormat('jpeg');$image->setImageCompressionQuality(85);
$image->writeImage(__DIR__.'/length-source.jpg');
$reopened=new Imagick(__DIR__.'/length-source.jpg');
$bytes=$reopened->getImageLength();
clearstatcache(true,__DIR__.'/length-source.jpg');
$disk=filesize(__DIR__.'/length-source.jpg');
pfLengthProof($source,$reopened,$bytes,$disk,$before);
echo "preview-file-size-length.png\nlength-source.jpg\nmetrics.json\n10008 bytes length-matches-file=1 width=400 height=320\n";

Подготовлен собственный JPEG85 и заново открыт: getImageLength вернул 10 008 байт, столько же насчитала файловая система. Размеры 400 × 320 — отдельные величины. Число относится к точному рисунку и проверенной версии кодека. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-length.png
length-source.jpg
metrics.json
10008 bytes length-matches-file=1 width=400 height=320

Создание JPEG перед getter — подготовка контролируемого входа. Если нужный файл уже существует, достаточно двух строк официального примера с его именем. Для вывода изображения в браузер файл используют как src картинки; текст bytes и бинарное изображение не смешивают в одном HTTP-ответе.

Выбрать реальный файл под лимит и учесть текущий blob и ошибки

Три настоящих JPEG одного исходника: выбор среди проверенных quality по фактическим байтам, без обещания размера от одного параметра
Три настоящих JPEG одного исходника: выбор среди проверенных quality по фактическим байтам, без обещания размера от одного параметра

Теперь другая независимая задача для исходного рисунка без gamma: выбрать среди quality 40,85,95 наибольшее проверенное значение, чей файл не превышает 12 000 байт. Это собственная политика примера, не встроенная оптимизация previewImages и не поиск по всем возможным качествам. Каждая версия действительно записывается и читается; getter сверяется с filesize до отдельного получения нового blob.

Проверить три реальных файла и выбрать подходящий под лимит

Из трёх экспортов исходного рисунка с quality 40/85/95 получены 4 837/10 008/20 859 байт. При собственном лимите 12 000 выбран 85 — наибольшая проверенная quality, которая подошла. Дополнительно видны изменение текущей blob-длины после getImageBlob, нулевая длина нового незакодированного растра и три перехваченные ошибки.

Проверить три реальных файла и выбрать подходящий под лимитПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$jpegSheet=$source->previewImages(Imagick::PREVIEW_JPEG);
$budget=12000;$chosenQuality=null;$selectedBytes=null;$variants=[];$images=[];
foreach([40,85,95] as $quality){
    $image=clone $source;$image->setImageFormat('jpeg');$image->setImageCompressionQuality($quality);
    $beforeWrite=$image->getImageLength();$filename='quality-'.$quality.'.jpg';
    $image->writeImage(__DIR__.'/'.$filename);
    $file=new Imagick(__DIR__.'/'.$filename);
    $bytes=$file->getImageLength();
    clearstatcache(true,__DIR__.'/'.$filename);$disk=filesize(__DIR__.'/'.$filename);
    $blob=$file->getImageBlob();$afterBlob=$file->getImageLength();
    $variants[]=['filename'=>$filename,'quality'=>$quality,'before_write'=>$beforeWrite,
        'reopened_bytes'=>$bytes,'file_bytes'=>$disk,'blob_bytes'=>strlen($blob),'after_blob'=>$afterBlob];
    $images[]=$file;pfView($file,'workflow-quality'.$quality.'-8.png');
    if($bytes<=$budget){$chosenQuality=$quality;$selectedBytes=$bytes;}
}
$fresh=new Imagick();$fresh->newImage(100,80,'red','png');$newLength=$fresh->getImageLength();
$errors=[];
foreach(['preview_empty'=>fn()=>(new Imagick())->previewImages(Imagick::PREVIEW_GAMMA),
    'length_empty'=>fn()=>(new Imagick())->getImageLength(),'missing_file'=>fn()=>new Imagick(__DIR__.'/missing.jpg')] as $name=>$call){
    try{$call();$errors[$name]=['class'=>'not caught','message'=>''];}
    catch(Throwable $error){$errors[$name]=['class'=>get_class($error),'message'=>$error->getMessage()];}
}
pfView($jpegSheet,'workflow-jpeg-sheet.png');$rects=pfCompare($images,'preview-file-size-workflow.png');
$allMatch=true;$blobsMatch=true;foreach($variants as $variant){$allMatch=$allMatch&&$variant['reopened_bytes']===$variant['file_bytes'];$blobsMatch=$blobsMatch&&$variant['after_blob']===$variant['blob_bytes'];}
pfDiagnostic('preview-file-size-workflow',['executed_apis'=>['previewImages','getImageLength'],'sheet'=>pfSheetInfo($jpegSheet),
    'variants'=>$variants,'byte_budget'=>$budget,'chosen_quality'=>$chosenQuality,'selected_bytes'=>$selectedBytes,
    'new_image_length'=>$newLength,'errors'=>$errors,'source_unchanged'=>pfHash($source)===$before,'panel_geometry'=>$rects,
    'checks'=>['real_native_JPEG_sheet'=>$jpegSheet instanceof Imagick&&$jpegSheet!==$source&&$jpegSheet->getImageWidth()===766&&$jpegSheet->getImageHeight()===936,
        'three_real_file_lengths'=>$allMatch,'fixture_scoped_export_bytes'=>array_column($variants,'reopened_bytes')===[4837,10008,20859],
        'chosen_highest_tested_fitting_quality'=>$chosenQuality===85&&$selectedBytes===10008&&$selectedBytes<=$budget,
        'blob_length_is_current_blob'=>$blobsMatch,'fresh_raster_not_encoded_bytes'=>$newLength===0,
        'three_failures_caught'=>array_column($errors,'class')===['ImagickException','ImagickException','ImagickException'],
        'source_preserved'=>pfHash($source)===$before]]);
echo "preview-file-size-workflow.png\nworkflow-quality40-8.png\nworkflow-quality85-8.png\nworkflow-quality95-8.png\nworkflow-jpeg-sheet.png\nquality-40.jpg\nquality-85.jpg\nquality-95.jpg\nmetrics.json\nqualities=40,85,95 bytes=4837,10008,20859 budget=12000 selected=85 errors=3 source-unchanged=1\n";

Из трёх экспортов исходного рисунка с quality 40/85/95 получены 4 837/10 008/20 859 байт. При собственном лимите 12 000 выбран 85 — наибольшая проверенная quality, которая подошла. Дополнительно видны изменение текущей blob-длины после getImageBlob, нулевая длина нового незакодированного растра и три перехваченные ошибки. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-workflow.png
workflow-quality40-8.png
workflow-quality85-8.png
workflow-quality95-8.png
workflow-jpeg-sheet.png
quality-40.jpg
quality-85.jpg
quality-95.jpg
metrics.json
qualities=40,85,95 bytes=4837,10008,20859 budget=12000 selected=85 errors=3 source-unchanged=1
Quality исходного рисункаФайл после сохраненияРезультат при лимите 12 000
404 837 байтПодходит.
8510 008 байтВыбран: наибольшая подходящая quality среди этих трёх.
9520 859 байтНе подходит.

Эти цифры относятся к исходному fixture и PHP 8.5.11 / Imagick 3.8.1 / IM 7.1.1-46 с его JPEG-кодеком. В первом примере применяется gamma 1.4, поэтому там другой экспорт и собственные фактические байты в metrics.json. Другой рисунок, sampling, метаданные или кодек могут дать другую длину. Если ни один вариант не подошёл, обработчик должен выбрать понятное действие: отказать, уменьшить геометрию или проверить другие явно ограниченные варианты; не объявлять несуществующий файл допустимым.

Нативный PREVIEW_JPEG также сохранён как workflow-jpeg-sheet.png. В нашем реальном запуске его восемь обработанных миниатюр выглядели одинаково и сообщали одинаковые 6.28125kb; такой лист не использован как работающий оценщик quality. Более того, любые его подписи в байтах относятся к маленьким промежуточным JPEG, не к полному экспорту 400 × 320. Поэтому решение опирается на реальные quality-40.jpg, quality-85.jpg и quality-95.jpg, а не на обещание контактной карты.

getImageBlob создаёт бинарное представление и может изменить последующую наблюдаемую длину текущего blob. В контроле после него getter совпал со strlen(blob), но значения отличались от прежнего файла: для quality 40 было 4 835 вместо 4 837, для 85 —10 015 вместо 10 008, для 95 —20 861 вместо 20 859. Файл на диске этим сравнением не переименовывается в новый blob. Поэтому сохраняйте измерение нужного артефакта и не вызывайте повторное кодирование ради каждого чтения длины.

На новом непустом растре 100 × 80 до кодирования getter вернул 0: это не нулевая ширина и не доказательство отсутствия пикселей. Пустой объект у любого изучаемого метода дал ImagickException с Can not process empty Imagick object; отсутствующий файл вызвал отдельный ImagickException при открытии. Все три случая пойманы и сохранены с точным сообщением. Подробнее о перехвате ошибок и условиях и циклах.

Сохранить полный официальный контракт, константы и воспроизводимость окружения

Полный официальный базис

Imagick::previewImages(int $preview): bool

Официальное описание: девять миниатюр с операцией разной силы помогают выбрать подходящий параметр. Обязательный int $preview задаёт тип через PREVIEW_* константы. Официальные synopsis/return указывают bool и true при успехе; XML целиком сохранён ниже. Однако точный C-wrapper Imagick 3.8.1 создаёт новый Imagick, что подтверждено реальным запуском: это объект, отличный от исходного. Reflection этой же сборки сообщает bool. Поэтому работающий пример сохраняет и исследует реальный объект, а не обращается с ним как с логическим флагом.

Метод возвращает один контактный лист, а не массив из девяти объектов и не команду применить выбранный эффект. В проверенной среде лист 766 × 936 содержит 3 × 3 ячейки; центральная — исходная миниатюра без эффекта. Ширина и высота листа зависят от реализации, исходника, рамок и шрифтов; 766 × 936 — наблюдение конкретного запуска. Список PREVIEW_* относится к отдельному разделу констант; для понятного начала выбраны GAMMA и затем диагностический JPEG.

Официальный раздел ошибок указывает ImagickException. Нужны непустой текущий источник, поддержка операций выбранного preview и возможность отрисовать подписи установленным шрифтом. Наличие метода не гарантирует готовность каждого кодека и шрифта. В нашем окружении default fonts работали; мы не утверждаем, что вызов Wand setFont автоматически настраивает внутренний fresh ImageInfo этой реализации.

Оба метода доступны в проверенной Imagick 3.8.1 с IM7 и не помечены здесь deprecated. Полная официальная доступность и исходная формулировка сохранены; расхождение return для preview не скрыто и не исправлено притворной заменой официального текста.

Полный официальный XML с описанием, параметрами, возвратом и исходным примером, если он есть
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.previewimages">
 <refnamediv>
  <refname>Imagick::previewImages</refname>
  <refpurpose>Quickly pin-point appropriate parameters for image processing</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::previewImages</methodname>
   <methodparam><type>int</type><parameter>preview</parameter></methodparam>
  </methodsynopsis>
  <para>
   Tiles 9 thumbnails of the specified image with an image processing
   operation applied at varying strengths.  This is helpful to quickly
   pin-point an appropriate parameter for an image processing operation.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>preview</parameter></term>
     <listitem>
      <para>
       Preview type. See <link linkend="imagick.constants.preview">Preview type constants</link>
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Полный официальный базис

Imagick::getImageLength(): int

getImageLength не принимает параметров и возвращает int — текущую длину изображения в байтах. Это не ширина, не высота и не размер пиксельной памяти. Точный Wand вызывает GetBlobSize текущего file/blob; он не кодирует будущий JPEG только от чтения getter. Если размер определить нельзя, Core может вернуть 0. В рабочем сценарии сначала действительно сохраняют файл, затем открывают именно его и сравнивают getter с файловой системой.

Официальный пример полностью сохранён: new Imagick(test.jpg), затем echo getImageLength и bytes. Он предполагает существующий файл test.jpg. Наш минимальный вариант заменяет внешнюю зависимость собственным подготовленным length-source.jpg и сохраняет ту же последовательность чтение→getter→вывод. После getImageBlob объект может сообщать уже длину нового blob, отличающуюся от прежнего файла; это отдельно измерено в workflow.

У обеих функций wrapper требует непустой текущий Imagick: фактический вызов на пустом объекте выбросил ImagickException с Can not process empty Imagick object. Отсутствующий файл приводит к отдельной ошибке конструктора ещё до getter. Нулевое число на новом непустом растре не равно этому исключению: в контроле 100 × 80 getter вернул 0 до кодирования.

Оба метода доступны в проверенной Imagick 3.8.1 с IM7 и не помечены здесь deprecated. Полная официальная доступность и исходная формулировка сохранены; расхождение return для preview не скрыто и не исправлено притворной заменой официального текста.

Полный официальный XML с описанием, параметрами, возвратом и исходным примером, если он есть
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagelength">
 <refnamediv>
  <refname>Imagick::getImageLength</refname>
  <refpurpose>Returns the image length in bytes</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>int</type><methodname>Imagick::getImageLength</methodname>
   <void/>
  </methodsynopsis>
  <para>
   Returns the image length in bytes
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  &no.function.parameters;
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns an int containing the current image size.
  </para>
 </refsect1>

 <refsect1 role="examples">
  &reftitle.examples;
  <para>
   <example>
    <title>Using <function>Imagick::getImageLength</function>:</title>
    <para>
     Getting image length in bytes
    </para>
    <programlisting role="php">
<![CDATA[
<?php
$image = new Imagick('test.jpg');
echo $image->getImageLength() . ' bytes';
?>
]]>
    </programlisting>
   </example>
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Все официальные PREVIEW_* константы

Полный исходный раздел констант
<variablelist xml:id="imagick.constants.preview">
  <title><constant>PREVIEW_<replaceable>*</replaceable></constant> constants</title>
  <para></para>
   <varlistentry xml:id="imagick.constants.preview-undefined">
    <term>
     <constant>imagick::PREVIEW_UNDEFINED</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-rotate">
    <term>
     <constant>imagick::PREVIEW_ROTATE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-shear">
    <term>
     <constant>imagick::PREVIEW_SHEAR</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-roll">
    <term>
     <constant>imagick::PREVIEW_ROLL</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-hue">
    <term>
     <constant>imagick::PREVIEW_HUE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-saturation">
    <term>
     <constant>imagick::PREVIEW_SATURATION</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-brightness">
    <term>
     <constant>imagick::PREVIEW_BRIGHTNESS</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-gamma">
    <term>
     <constant>imagick::PREVIEW_GAMMA</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-spiff">
    <term>
     <constant>imagick::PREVIEW_SPIFF</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-dull">
    <term>
     <constant>imagick::PREVIEW_DULL</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-grayscale">
    <term>
     <constant>imagick::PREVIEW_GRAYSCALE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-quantize">
    <term>
     <constant>imagick::PREVIEW_QUANTIZE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-despeckle">
    <term>
     <constant>imagick::PREVIEW_DESPECKLE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-reducenoise">
    <term>
     <constant>imagick::PREVIEW_REDUCENOISE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-addnoise">
    <term>
     <constant>imagick::PREVIEW_ADDNOISE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-sharpen">
    <term>
     <constant>imagick::PREVIEW_SHARPEN</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-blur">
    <term>
     <constant>imagick::PREVIEW_BLUR</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-threshold">
    <term>
     <constant>imagick::PREVIEW_THRESHOLD</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-edgedetect">
    <term>
     <constant>imagick::PREVIEW_EDGEDETECT</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-spread">
    <term>
     <constant>imagick::PREVIEW_SPREAD</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-solarize">
    <term>
     <constant>imagick::PREVIEW_SOLARIZE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-shade">
    <term>
     <constant>imagick::PREVIEW_SHADE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-raise">
    <term>
     <constant>imagick::PREVIEW_RAISE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-segment">
    <term>
     <constant>imagick::PREVIEW_SEGMENT</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-swirl">
    <term>
     <constant>imagick::PREVIEW_SWIRL</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-implode">
    <term>
     <constant>imagick::PREVIEW_IMPLODE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-wave">
    <term>
     <constant>imagick::PREVIEW_WAVE</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-oilpaint">
    <term>
     <constant>imagick::PREVIEW_OILPAINT</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-charcoaldrawing">
    <term>
     <constant>imagick::PREVIEW_CHARCOALDRAWING</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
   <varlistentry xml:id="imagick.constants.preview-jpeg">
    <term>
     <constant>imagick::PREVIEW_JPEG</constant>
     (<type>int</type>)
    </term>
    <listitem>
     <simpara>
     </simpara>
    </listitem>
   </varlistentry>
 </variablelist>

Для воспроизведения контактных листов нужны соответствующие кодеки и установленные шрифты. В проверенной Windows-среде библиотека нашла 804 font names и реально отрисовала default-подписи; это характеристика окружения, не постоянная вашего компьютера. При переносе ошибки font/delegate надо исправлять в используемой сборке и её конфигурации. Не выдавайте произвольный setFont за доказанное управление fresh ImageInfo внутри этой версии PreviewImage. Числа 766 × 936 и подписи центрального тайла также не являются межверсионным стандартом.

Полный исполняемый fixture

<?php
declare(strict_types=1);
function pfRestore():void {
    $raw=base64_decode((string)file_get_contents(__DIR__.'/source-rgb8.png.b64'),true);
    if($raw===false||hash('sha256',$raw)!=='b6af02ed97020582a27e993a1565de41e23ea97ff7be11ac132d68204d56d483'||file_put_contents(__DIR__.'/source-rgb8.png',$raw)===false){throw new RuntimeException('Known own PNG input missing or changed');}
}
function pfSource():Imagick {return new Imagick(__DIR__.'/source-rgb8.png');}
function pfHash(Imagick $image):string {
    return hash('sha256',json_encode($image->exportImagePixels(0,0,$image->getImageWidth(),$image->getImageHeight(),'RGB',Imagick::PIXEL_SHORT),JSON_THROW_ON_ERROR));
}
function pfView(Imagick $image,string $name):void {
    $copy=clone $image;$copy->stripImage();$copy->setImageFormat('png');$copy->setImageDepth(8);
    $copy->setOption('png:bit-depth','8');$copy->setOption('png:color-type','2');$copy->setOption('png:exclude-chunk','all');
    if(!$copy->writeImage(__DIR__.'/'.$name)){throw new RuntimeException('PNG display write failed');}
}
function pfCompare(array $images,string $name):array {
    $board=new Imagick();$board->newImage(400*count($images),320,'white');$rects=[];
    foreach($images as $i=>$image){
        if($image->getImageWidth()!==400||$image->getImageHeight()!==320){throw new RuntimeException('Expected full400x320 product view');}
        $copy=clone $image;$copy->stripImage();$board->compositeImage($copy,Imagick::COMPOSITE_OVER,400*$i,0);
        $rects[]=['x'=>400*$i,'y'=>0,'width'=>400,'height'=>320];
    }
    pfView($board,$name);return $rects;
}
function pfDiagnostic(string $id,array $data):void {
    $doc=['schema'=>'aen-preview-file-size-program-diagnostics-v1','example_id'=>$id,
        'runtime'=>['php'=>PHP_VERSION,'imagick'=>phpversion('imagick'),'imagemagick'=>Imagick::getVersion()]]+$data;
    if(file_put_contents(__DIR__.'/metrics.json',json_encode($doc,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)."\n")===false){throw new RuntimeException('Cannot write measurements');}
}
function pfSheetInfo(Imagick $sheet):array {return ['actual_type'=>get_debug_type($sheet),'width'=>$sheet->getImageWidth(),'height'=>$sheet->getImageHeight(),'images'=>$sheet->getNumberImages()];}
function pfFirstProof(Imagick $source,Imagick $sheet,Imagick $chosen,Imagick $reopened,int $beforeWrite,int $bytes,int $disk,string $before):void {
    pfView($source,'source-preview8.png');pfView($sheet,'preview-file-size-first.png');
    pfView($chosen,'selected-gamma8.png');pfView($reopened,'selected-jpeg8.png');
    $meta=pfSheetInfo($sheet);
    pfDiagnostic('preview-file-size-first',['executed_apis'=>['previewImages','getImageLength'],'sheet'=>$meta,
        'reflection_return'=>(string)(new ReflectionMethod(Imagick::class,'previewImages'))->getReturnType(),
        'preview_is_source'=>$sheet===$source,'source_unchanged'=>pfHash($source)===$before,
        'selected_gamma'=>1.4,'selected_changes_source_pixels'=>pfHash($chosen)!==$before,
        'export'=>['filename'=>'selected-gamma85.jpg','quality'=>85,'before_write'=>$beforeWrite,'reopened_bytes'=>$bytes,'file_bytes'=>$disk],
        'checks'=>['actual_new_Imagick'=>$sheet instanceof Imagick&&$sheet!==$source,'native_sheet_geometry'=>$meta['width']===766&&$meta['height']===936&&$meta['images']===1,
            'manual_gamma_applied'=>pfHash($chosen)!==$before,'real_export_measured'=>$bytes>0&&$bytes===$disk,'source_preserved'=>pfHash($source)===$before]]);
}
function pfPreviewProof(Imagick $source,Imagick $sheet,string $before):void {
    pfView($source,'preview-source8.png');pfView($sheet,'preview-file-size-preview.png');$meta=pfSheetInfo($sheet);
    pfDiagnostic('preview-file-size-preview-minimal',['executed_api'=>'previewImages','sheet'=>$meta,
        'reflection_return'=>(string)(new ReflectionMethod(Imagick::class,'previewImages'))->getReturnType(),
        'preview_is_source'=>$sheet===$source,'source_unchanged'=>pfHash($source)===$before,
        'checks'=>['actual_new_Imagick'=>$sheet instanceof Imagick&&$sheet!==$source,'one_native_sheet'=>$meta['images']===1,
            'native_sheet_geometry'=>$meta['width']===766&&$meta['height']===936,'source_preserved'=>pfHash($source)===$before]]);
}
function pfLengthProof(Imagick $source,Imagick $reopened,int $bytes,int $disk,string $before):void {
    pfView($reopened,'preview-file-size-length.png');
    pfDiagnostic('preview-file-size-length-minimal',['executed_api'=>'getImageLength',
        'file'=>['filename'=>'length-source.jpg','quality'=>85,'reopened_bytes'=>$bytes,'file_bytes'=>$disk],
        'width'=>$reopened->getImageWidth(),'height'=>$reopened->getImageHeight(),'source_unchanged'=>pfHash($source)===$before,
        'checks'=>['int_bytes'=>is_int($bytes)&&$bytes>0,'length_matches_saved_file'=>$bytes===$disk,
            'fixture_scoped_bytes'=>$bytes===10008,'geometry_preserved'=>$reopened->getImageWidth()===400&&$reopened->getImageHeight()===320,'source_preserved'=>pfHash($source)===$before]]);
}

Helper восстанавливает только собственный PNG, открывает его, сохраняет PNG8-просмотры и измерения. Изучаемые previewImages и getImageLength вызываются напрямую в main. pfCompare собирает три натуральные 400 × 320 панели без изменения масштаба; листы 766 × 936 сохраняются целиком. pfHash сравнивает все компоненты RGB через PIXEL_SHORT, чтобы не спутать неизменность источника с одинаковыми файловыми метаданными.

Упражнение: изменить лимит workflow на 6 000 и предсказать выбор среди тех же трёх сохранённых файлов. Решение для этого fixture: quality 40 с 4 837 байт. При лимите меньше 4 837 ни один из этих вариантов не подходит; это отдельная ветка обработки, а не повод считать quality 40 всегда достаточно маленькой. Следующий шаг — вынести выбранную политику в функцию и разобрать реальные параметры JPEG-экспорта.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

Imagick::previewImagesПодобрать обработку по настоящим превью и измерить байты отдельно сохранённого файла

PECL imagick 2, PECL imagick 3 · imagick

Imagick::previewImages(int $preview): bool

Полный официальный базис

Imagick::previewImages(int $preview): bool

Официальное описание: девять миниатюр с операцией разной силы помогают выбрать подходящий параметр. Обязательный int $preview задаёт тип через PREVIEW_* константы. Официальные synopsis/return указывают bool и true при успехе; XML целиком сохранён ниже. Однако точный C-wrapper Imagick 3.8.1 создаёт новый Imagick, что подтверждено реальным запуском: это объект, отличный от исходного. Reflection этой же сборки сообщает bool. Поэтому работающий пример сохраняет и исследует реальный объект, а не обращается с ним как с логическим флагом.

Метод возвращает один контактный лист, а не массив из девяти объектов и не команду применить выбранный эффект. В проверенной среде лист 766 × 936 содержит 3 × 3 ячейки; центральная — исходная миниатюра без эффекта. Ширина и высота листа зависят от реализации, исходника, рамок и шрифтов; 766 × 936 — наблюдение конкретного запуска. Список PREVIEW_* относится к отдельному разделу констант; для понятного начала выбраны GAMMA и затем диагностический JPEG.

Официальный раздел ошибок указывает ImagickException. Нужны непустой текущий источник, поддержка операций выбранного preview и возможность отрисовать подписи установленным шрифтом. Наличие метода не гарантирует готовность каждого кодека и шрифта. В нашем окружении default fonts работали; мы не утверждаем, что вызов Wand setFont автоматически настраивает внутренний fresh ImageInfo этой реализации.

Оба метода доступны в проверенной Imagick 3.8.1 с IM7 и не помечены здесь deprecated. Полная официальная доступность и исходная формулировка сохранены; расхождение return для preview не скрыто и не исправлено притворной заменой официального текста.

Полный официальный XML с описанием, параметрами, возвратом и исходным примером, если он есть
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.previewimages">
 <refnamediv>
  <refname>Imagick::previewImages</refname>
  <refpurpose>Quickly pin-point appropriate parameters for image processing</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::previewImages</methodname>
   <methodparam><type>int</type><parameter>preview</parameter></methodparam>
  </methodsynopsis>
  <para>
   Tiles 9 thumbnails of the specified image with an image processing
   operation applied at varying strengths.  This is helpful to quickly
   pin-point an appropriate parameter for an image processing operation.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>preview</parameter></term>
     <listitem>
      <para>
       Preview type. See <link linkend="imagick.constants.preview">Preview type constants</link>
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Одним вызовом получить новый объект с контактным листом

В этой сборке возвращён новый Imagick 766 × 936 с одним изображением-контактным листом. Это не bool и не массив из девяти объектов. Оригинальный источник не изменён.

Одним вызовом получить новый объект с контактным листомПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$sheet=$source->previewImages(Imagick::PREVIEW_GAMMA);
pfPreviewProof($source,$sheet,$before);
echo "preview-file-size-preview.png\npreview-source8.png\nmetrics.json\npreview=Imagick native-size=766x936 images=1 source-unchanged=1\n";

В этой сборке возвращён новый Imagick 766 × 936 с одним изображением-контактным листом. Это не bool и не массив из девяти объектов. Оригинальный источник не изменён. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-preview.png
preview-source8.png
metrics.json
preview=Imagick native-size=766x936 images=1 source-unchanged=1

Проверить три реальных файла и выбрать подходящий под лимит

Из трёх экспортов исходного рисунка с quality 40/85/95 получены 4 837/10 008/20 859 байт. При собственном лимите 12 000 выбран 85 — наибольшая проверенная quality, которая подошла. Дополнительно видны изменение текущей blob-длины после getImageBlob, нулевая длина нового незакодированного растра и три перехваченные ошибки.

Проверить три реальных файла и выбрать подходящий под лимитПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$jpegSheet=$source->previewImages(Imagick::PREVIEW_JPEG);
$budget=12000;$chosenQuality=null;$selectedBytes=null;$variants=[];$images=[];
foreach([40,85,95] as $quality){
    $image=clone $source;$image->setImageFormat('jpeg');$image->setImageCompressionQuality($quality);
    $beforeWrite=$image->getImageLength();$filename='quality-'.$quality.'.jpg';
    $image->writeImage(__DIR__.'/'.$filename);
    $file=new Imagick(__DIR__.'/'.$filename);
    $bytes=$file->getImageLength();
    clearstatcache(true,__DIR__.'/'.$filename);$disk=filesize(__DIR__.'/'.$filename);
    $blob=$file->getImageBlob();$afterBlob=$file->getImageLength();
    $variants[]=['filename'=>$filename,'quality'=>$quality,'before_write'=>$beforeWrite,
        'reopened_bytes'=>$bytes,'file_bytes'=>$disk,'blob_bytes'=>strlen($blob),'after_blob'=>$afterBlob];
    $images[]=$file;pfView($file,'workflow-quality'.$quality.'-8.png');
    if($bytes<=$budget){$chosenQuality=$quality;$selectedBytes=$bytes;}
}
$fresh=new Imagick();$fresh->newImage(100,80,'red','png');$newLength=$fresh->getImageLength();
$errors=[];
foreach(['preview_empty'=>fn()=>(new Imagick())->previewImages(Imagick::PREVIEW_GAMMA),
    'length_empty'=>fn()=>(new Imagick())->getImageLength(),'missing_file'=>fn()=>new Imagick(__DIR__.'/missing.jpg')] as $name=>$call){
    try{$call();$errors[$name]=['class'=>'not caught','message'=>''];}
    catch(Throwable $error){$errors[$name]=['class'=>get_class($error),'message'=>$error->getMessage()];}
}
pfView($jpegSheet,'workflow-jpeg-sheet.png');$rects=pfCompare($images,'preview-file-size-workflow.png');
$allMatch=true;$blobsMatch=true;foreach($variants as $variant){$allMatch=$allMatch&&$variant['reopened_bytes']===$variant['file_bytes'];$blobsMatch=$blobsMatch&&$variant['after_blob']===$variant['blob_bytes'];}
pfDiagnostic('preview-file-size-workflow',['executed_apis'=>['previewImages','getImageLength'],'sheet'=>pfSheetInfo($jpegSheet),
    'variants'=>$variants,'byte_budget'=>$budget,'chosen_quality'=>$chosenQuality,'selected_bytes'=>$selectedBytes,
    'new_image_length'=>$newLength,'errors'=>$errors,'source_unchanged'=>pfHash($source)===$before,'panel_geometry'=>$rects,
    'checks'=>['real_native_JPEG_sheet'=>$jpegSheet instanceof Imagick&&$jpegSheet!==$source&&$jpegSheet->getImageWidth()===766&&$jpegSheet->getImageHeight()===936,
        'three_real_file_lengths'=>$allMatch,'fixture_scoped_export_bytes'=>array_column($variants,'reopened_bytes')===[4837,10008,20859],
        'chosen_highest_tested_fitting_quality'=>$chosenQuality===85&&$selectedBytes===10008&&$selectedBytes<=$budget,
        'blob_length_is_current_blob'=>$blobsMatch,'fresh_raster_not_encoded_bytes'=>$newLength===0,
        'three_failures_caught'=>array_column($errors,'class')===['ImagickException','ImagickException','ImagickException'],
        'source_preserved'=>pfHash($source)===$before]]);
echo "preview-file-size-workflow.png\nworkflow-quality40-8.png\nworkflow-quality85-8.png\nworkflow-quality95-8.png\nworkflow-jpeg-sheet.png\nquality-40.jpg\nquality-85.jpg\nquality-95.jpg\nmetrics.json\nqualities=40,85,95 bytes=4837,10008,20859 budget=12000 selected=85 errors=3 source-unchanged=1\n";

Из трёх экспортов исходного рисунка с quality 40/85/95 получены 4 837/10 008/20 859 байт. При собственном лимите 12 000 выбран 85 — наибольшая проверенная quality, которая подошла. Дополнительно видны изменение текущей blob-длины после getImageBlob, нулевая длина нового незакодированного растра и три перехваченные ошибки. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-workflow.png
workflow-quality40-8.png
workflow-quality85-8.png
workflow-quality95-8.png
workflow-jpeg-sheet.png
quality-40.jpg
quality-85.jpg
quality-95.jpg
metrics.json
qualities=40,85,95 bytes=4837,10008,20859 budget=12000 selected=85 errors=3 source-unchanged=1
Imagick::getImageLengthПодобрать обработку по настоящим превью и измерить байты отдельно сохранённого файла

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImageLength(): int

Полный официальный базис

Imagick::getImageLength(): int

getImageLength не принимает параметров и возвращает int — текущую длину изображения в байтах. Это не ширина, не высота и не размер пиксельной памяти. Точный Wand вызывает GetBlobSize текущего file/blob; он не кодирует будущий JPEG только от чтения getter. Если размер определить нельзя, Core может вернуть 0. В рабочем сценарии сначала действительно сохраняют файл, затем открывают именно его и сравнивают getter с файловой системой.

Официальный пример полностью сохранён: new Imagick(test.jpg), затем echo getImageLength и bytes. Он предполагает существующий файл test.jpg. Наш минимальный вариант заменяет внешнюю зависимость собственным подготовленным length-source.jpg и сохраняет ту же последовательность чтение→getter→вывод. После getImageBlob объект может сообщать уже длину нового blob, отличающуюся от прежнего файла; это отдельно измерено в workflow.

У обеих функций wrapper требует непустой текущий Imagick: фактический вызов на пустом объекте выбросил ImagickException с Can not process empty Imagick object. Отсутствующий файл приводит к отдельной ошибке конструктора ещё до getter. Нулевое число на новом непустом растре не равно этому исключению: в контроле 100 × 80 getter вернул 0 до кодирования.

Оба метода доступны в проверенной Imagick 3.8.1 с IM7 и не помечены здесь deprecated. Полная официальная доступность и исходная формулировка сохранены; расхождение return для preview не скрыто и не исправлено притворной заменой официального текста.

Полный официальный XML с описанием, параметрами, возвратом и исходным примером, если он есть
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagelength">
 <refnamediv>
  <refname>Imagick::getImageLength</refname>
  <refpurpose>Returns the image length in bytes</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>int</type><methodname>Imagick::getImageLength</methodname>
   <void/>
  </methodsynopsis>
  <para>
   Returns the image length in bytes
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  &no.function.parameters;
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns an int containing the current image size.
  </para>
 </refsect1>

 <refsect1 role="examples">
  &reftitle.examples;
  <para>
   <example>
    <title>Using <function>Imagick::getImageLength</function>:</title>
    <para>
     Getting image length in bytes
    </para>
    <programlisting role="php">
<![CDATA[
<?php
$image = new Imagick('test.jpg');
echo $image->getImageLength() . ' bytes';
?>
]]>
    </programlisting>
   </example>
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Прочитать число байтов настоящего заново открытого JPEG

Подготовлен собственный JPEG85 и заново открыт: getImageLength вернул 10 008 байт, столько же насчитала файловая система. Размеры 400 × 320 — отдельные величины. Число относится к точному рисунку и проверенной версии кодека.

Прочитать число байтов настоящего заново открытого JPEGПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$image=clone $source;
$image->setImageFormat('jpeg');$image->setImageCompressionQuality(85);
$image->writeImage(__DIR__.'/length-source.jpg');
$reopened=new Imagick(__DIR__.'/length-source.jpg');
$bytes=$reopened->getImageLength();
clearstatcache(true,__DIR__.'/length-source.jpg');
$disk=filesize(__DIR__.'/length-source.jpg');
pfLengthProof($source,$reopened,$bytes,$disk,$before);
echo "preview-file-size-length.png\nlength-source.jpg\nmetrics.json\n10008 bytes length-matches-file=1 width=400 height=320\n";

Подготовлен собственный JPEG85 и заново открыт: getImageLength вернул 10 008 байт, столько же насчитала файловая система. Размеры 400 × 320 — отдельные величины. Число относится к точному рисунку и проверенной версии кодека. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-length.png
length-source.jpg
metrics.json
10008 bytes length-matches-file=1 width=400 height=320

Проверить три реальных файла и выбрать подходящий под лимит

Из трёх экспортов исходного рисунка с quality 40/85/95 получены 4 837/10 008/20 859 байт. При собственном лимите 12 000 выбран 85 — наибольшая проверенная quality, которая подошла. Дополнительно видны изменение текущей blob-длины после getImageBlob, нулевая длина нового незакодированного растра и три перехваченные ошибки.

Проверить три реальных файла и выбрать подходящий под лимитПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/preview-file-size-fixture.php';
pfRestore();
$source=pfSource(); $before=pfHash($source);
$jpegSheet=$source->previewImages(Imagick::PREVIEW_JPEG);
$budget=12000;$chosenQuality=null;$selectedBytes=null;$variants=[];$images=[];
foreach([40,85,95] as $quality){
    $image=clone $source;$image->setImageFormat('jpeg');$image->setImageCompressionQuality($quality);
    $beforeWrite=$image->getImageLength();$filename='quality-'.$quality.'.jpg';
    $image->writeImage(__DIR__.'/'.$filename);
    $file=new Imagick(__DIR__.'/'.$filename);
    $bytes=$file->getImageLength();
    clearstatcache(true,__DIR__.'/'.$filename);$disk=filesize(__DIR__.'/'.$filename);
    $blob=$file->getImageBlob();$afterBlob=$file->getImageLength();
    $variants[]=['filename'=>$filename,'quality'=>$quality,'before_write'=>$beforeWrite,
        'reopened_bytes'=>$bytes,'file_bytes'=>$disk,'blob_bytes'=>strlen($blob),'after_blob'=>$afterBlob];
    $images[]=$file;pfView($file,'workflow-quality'.$quality.'-8.png');
    if($bytes<=$budget){$chosenQuality=$quality;$selectedBytes=$bytes;}
}
$fresh=new Imagick();$fresh->newImage(100,80,'red','png');$newLength=$fresh->getImageLength();
$errors=[];
foreach(['preview_empty'=>fn()=>(new Imagick())->previewImages(Imagick::PREVIEW_GAMMA),
    'length_empty'=>fn()=>(new Imagick())->getImageLength(),'missing_file'=>fn()=>new Imagick(__DIR__.'/missing.jpg')] as $name=>$call){
    try{$call();$errors[$name]=['class'=>'not caught','message'=>''];}
    catch(Throwable $error){$errors[$name]=['class'=>get_class($error),'message'=>$error->getMessage()];}
}
pfView($jpegSheet,'workflow-jpeg-sheet.png');$rects=pfCompare($images,'preview-file-size-workflow.png');
$allMatch=true;$blobsMatch=true;foreach($variants as $variant){$allMatch=$allMatch&&$variant['reopened_bytes']===$variant['file_bytes'];$blobsMatch=$blobsMatch&&$variant['after_blob']===$variant['blob_bytes'];}
pfDiagnostic('preview-file-size-workflow',['executed_apis'=>['previewImages','getImageLength'],'sheet'=>pfSheetInfo($jpegSheet),
    'variants'=>$variants,'byte_budget'=>$budget,'chosen_quality'=>$chosenQuality,'selected_bytes'=>$selectedBytes,
    'new_image_length'=>$newLength,'errors'=>$errors,'source_unchanged'=>pfHash($source)===$before,'panel_geometry'=>$rects,
    'checks'=>['real_native_JPEG_sheet'=>$jpegSheet instanceof Imagick&&$jpegSheet!==$source&&$jpegSheet->getImageWidth()===766&&$jpegSheet->getImageHeight()===936,
        'three_real_file_lengths'=>$allMatch,'fixture_scoped_export_bytes'=>array_column($variants,'reopened_bytes')===[4837,10008,20859],
        'chosen_highest_tested_fitting_quality'=>$chosenQuality===85&&$selectedBytes===10008&&$selectedBytes<=$budget,
        'blob_length_is_current_blob'=>$blobsMatch,'fresh_raster_not_encoded_bytes'=>$newLength===0,
        'three_failures_caught'=>array_column($errors,'class')===['ImagickException','ImagickException','ImagickException'],
        'source_preserved'=>pfHash($source)===$before]]);
echo "preview-file-size-workflow.png\nworkflow-quality40-8.png\nworkflow-quality85-8.png\nworkflow-quality95-8.png\nworkflow-jpeg-sheet.png\nquality-40.jpg\nquality-85.jpg\nquality-95.jpg\nmetrics.json\nqualities=40,85,95 bytes=4837,10008,20859 budget=12000 selected=85 errors=3 source-unchanged=1\n";

Из трёх экспортов исходного рисунка с quality 40/85/95 получены 4 837/10 008/20 859 байт. При собственном лимите 12 000 выбран 85 — наибольшая проверенная quality, которая подошла. Дополнительно видны изменение текущей blob-длины после getImageBlob, нулевая длина нового незакодированного растра и три перехваченные ошибки. Каждый архив самостоятельный: example.php, source-rgb8.png.b64 и preview-file-size-fixture.php. Распакуйте рядом и запустите php example.php. Реальная проверка: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, PNG/JPEG и работающие установленные шрифты. pfRestore восстанавливает собственный PNG по SHA, pfSource читает его; изучаемые вызовы видны в основном коде. pfView сохраняет отдельный PNG8 с теми же размерами, не рисует и не масштабирует нативные тайлы; измерения хранятся в metrics.json. Форматные даты и тексты исключений не подменяют проверку реального файла и его байтов.

Ожидаемый вывод в проверенной сборке
preview-file-size-workflow.png
workflow-quality40-8.png
workflow-quality85-8.png
workflow-quality95-8.png
workflow-jpeg-sheet.png
quality-40.jpg
quality-85.jpg
quality-95.jpg
metrics.json
qualities=40,85,95 bytes=4837,10008,20859 budget=12000 selected=85 errors=3 source-unchanged=1
Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.