Я использую 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
Вместо того, чтобы рендерить, а затем изменять размер растра, лучше сначала отрисовать 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 и делает это по той же причине.
К сожалению, я не очень хорошо знаю 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');