Как сделать пиктограммы с помощью Imagick :: resizeImage более четкими — PHP?

Я использую Imagick :: resizeImage, чтобы создать уменьшенное изображение PNG каждой страницы PDF-файла. Однако изображение, которое я получаю, действительно размыто. Как я могу сделать это немного острее? Любые указатели будут по достоинству оценены.

Я попытался отрегулировать параметр размытия Imagick :: resizeImage между 0,1 — 1, но безуспешно.

$pdfPage = '1Mpublic.pdf[0]';
$im = new imagick($pdfPage);
$im->setImageFormat('png');

// Resize thumbnail image
$imgHeight =  $im -> getImageHeight();
$imgWidth = $im -> getImageWidth();
$desiredWidth = 200;
$desiredHeight = resizedImageHeight($imgWidth, $imgHeight, $desiredWidth);

$im -> setResolution(1500, 1500);
$im -> resizeImage($desiredWidth, $desiredHeight, imagick::STYLE_NORMAL, 0.1);

/* Resize image */
function resizedImageHeight($imgWidth, $imgHeight, $desiredImgWidth){

$quoient = $imgWidth/$imgHeight;
$height = $desiredImgWidth/$quoient;

return $height;
}

введите описание изображения здесь

оригинал pdf ссылка:

https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4905263/pdf/ksgt-06-04-1091539.pdf

1

Решение

Вместо того, чтобы рендерить, а затем изменять размер растра, лучше сначала отрисовать PDF с нужным количеством пикселей. Это будет быстрее, и вы можете быть уверены, что уровень резкости соответствует содержанию.

Например:

$ time convert -density 50 ksgt-06-04-1091539.pdf[0] x2.png
real    0m0.325s
user    0m0.299s
sys 0m0.024s

Делает:

прямая калибровка

-density 50 делает страницу примерно с таким же количеством пикселей в поперечнике, что и ваш образец, 425.

В imagick вы можете сделать это так (как уже сказал отличный ответ @ fmw42):

#!/usr/bin/env php
<?php

$target_width = 400;

# get natural size, calculate density we need for target width
$im = new imagick();
$im->pingImage($argv[1]);
$geo = $im->getImageGeometry();
$natural_width = $geo['width'];
$density = 72.0 * $target_width / $natural_width;

# load at correct resolution for target_width
$im = new imagick();
$im->setResolution($density, $density);
$im->readImage($argv[1]);

# and write back
$im->writeImage($argv[2]);

К сожалению, выполнение команды ping и read немного медленное:

$ time ./pdfthumb.php ksgt-06-04-1091539.pdf x.png
real    0m2.773s
user    0m2.737s
sys 0m0.036s

Это не воображение, но vipsthumbnail Можно выполнить пинг и прочитать за одну операцию:

$ time vipsthumbnail ksgt-06-04-1091539.pdf -s 400x -o x2.png
real    0m0.064s
user    0m0.064s
sys 0m0.011s

Возможно, стоит подумать, важна ли скорость. libvips имеет привязку php так что вы можете вызвать его напрямую, но если вы сделаете это, вы столкнетесь с ужасными проблемами лицензирования, потому что он использует библиотеку GPL для рендеринга PDF, вздох. ImageMagick использует GhostScript и делает это по той же причине.

3

Другие решения

К сожалению, я не очень хорошо знаю Imagick. Но в командной строке Imagemagick я бы делал то, что иногда называют суперсэмплингом. То есть используйте большую плотность, чтобы прочитать PDF, а затем измените размер на обратный масштабный коэффициент.

Например, номинальная плотность составляет 72 dpi. Я бы прочитал входной PDF в 4 * 72 = 288 точек на дюйм. Затем после растеризации я бы изменил размер на 1/4 = 25% или для большего результата на что-то большее, чем 25%, скажем, 50%. Вот ваша первая страница, выполненная в обе стороны:

convert -density 288 ksgt-06-04-1091539.pdf[0] -resize 25% result1.png

введите описание изображения здесь

convert -density 288 ksgt-06-04-1091539.pdf[0] -resize 50% result2.png

введите описание изображения здесь

В Imagick ключ что-то вроде:

$imagick = new Imagick();
$imagick->setImageResolution(288, 288);
$imagick->readImage('myfile.pdf');
2

По вопросам рекламы [email protected]