【问题标题】:How to make thumbnails using Imagick::resizeImage appear sharper - PHP?如何使用 Imagick::resizeImage 使缩略图看起来更清晰 - PHP?
【发布时间】:2018-04-14 06:16:22
【问题描述】:

我正在使用 Imagick::resizeImage 为 pdf 文件的每一页创建缩略​​图 PNG 图像。然而,我得到的图像真的很模糊。我怎样才能使它更尖锐一点?任何指针将不胜感激。

我尝试在 0.1 - 1 之间调整 Imagick::resizeImage 的“模糊”参数,但没有成功。

$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

【问题讨论】:

  • PHP 文档中的此注释使用“setResolution”选项:php.net/manual/en/imagick.construct.php#113801 - 你试过了吗?
  • @Philip 我已经尝试过 - 请参阅编辑。
  • PDF 文件是没有像素的矢量文件,以英寸或厘米为单位。您必须将它们栅格化为像素。但是要告诉它制作光栅图像有多大,你必须告诉它你想要的光栅化分辨率。所以必须把setResolution 设置成一个大的值比如300 before 来阅读PDF。但是你想要的 width=200 太小了,无法得到任何合理的东西
  • @fmw42 我是使用 imgick 的新手。请你能给我一些关于如何光栅化 pdf 的广泛指示,以及在阅读 pdf 文件之前我将如何设置分辨率?我想要的宽度是灵活的。也许你可以分享一些代码?
  • 您还使用STYLE_NORMAL 作为调整大小算法的参数——该参数应该是FILTER_ 常量之一(例如Imagick::FILTER_LANCZOS)。但解决方案是主要问题。

标签: php imagemagick imagick resize-image


【解决方案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 和读取有点慢:

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

这不是想象的,但vipsthumbnail 可以在一个操作中执行 ping 和读取:

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

如果速度很重要,可能值得考虑。 libvips has a php binding 所以你可以直接调用它,但如果你这样做,你会遇到可怕的许可问题,因为它使用 GPL 库 poppler 进行 PDF 渲染,叹息。出于同样的原因,ImageMagick 使用了 GhostScript 和 shell。

【讨论】:

  • 感谢您的输入,问题是您将如何使用 php - imagick 做到这一点?
  • user894763 方法确实比我的好。一个问题是您需要计算所需的密度以产生所需的像素大小。因此,您需要以 72 的名义密度运行命令一次并找到大小,然后缩放密度以达到所需的输出大小(以像素为单位)。
【解决方案2】:

不幸的是,我不太了解 Imagick。但在 Imagemagick 命令行中,我会执行有时称为超级采样的操作。即使用大密度读取 PDF,然后按逆比例因子缩小。

例如,标称密度为 72 dpi。我会以 4*72=288 dpi 读取输入 PDF。然后在光栅化之后,我会调整 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'); 

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 2016-09-03
    • 2014-01-16
    • 2020-09-18
    • 1970-01-01
    相关资源
    最近更新 更多