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

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

На листе видны 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. Лист не применяет выбранный эффект автоматически.
<?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.4 | gammaImage применяется к новой копии полного рисунка 400 × 320, а не к вырезанному и увеличенному тайлу. |
| writeImage | JPEG-кодек создаёт файл с выбранной quality; до этого будущий размер не обязан быть известен. |
| new Imagick + getImageLength | Заново читается конкретный файл; getter возвращает его текущую длину. |
| filesize | Независимая сверка с файловой системой; clearstatcache сбрасывает PHP-кэш сведений об этом файле. |
Контактный лист похож на пробную полосу фотографа: помогает увидеть направление изменения, но не заменяет обработку полного кадра. В Core сначала создаются уменьшенные thumbnails, затем монтаж 3 × 3 с рамками, тенью и подписями. Он сам по себе не содержит интерфейс выбора ячейки и не возвращает массив настроек. Число изображений в возвращённом Imagick равно 1, хотя нарисовано девять ячеек.
Байты файла, геометрия и память — разные величины. У исходника 400 × 320 число пикселей равно 128 000, но это не число байтов JPEG. Метаданные, алгоритм кодирования, quality и содержимое влияют на итоговый файл; getter не является оценщиком этой будущей величины. Подробнее: сжатие и качество, геометрия и файлы.
Запустить короткий preview и отдельно прочитать размер существующего файла

Каждый архив содержит собственный нормализованный 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 — отдельные величины. Число относится к точному рисунку и проверенной версии кодека.
<?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 и ошибки

Теперь другая независимая задача для исходного рисунка без 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 |
|---|---|---|
| 40 | 4 837 байт | Подходит. |
| 85 | 10 008 байт | Выбран: наибольшая подходящая quality среди этих трёх. |
| 95 | 20 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(): intgetImageLength не принимает параметров и возвращает 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(): intgetImageLength не принимает параметров и возвращает 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 — отдельные величины. Число относится к точному рисунку и проверенной версии кодека.
<?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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


