11

当用户上传图片时,我正在处理图片,但我的问题是高分辨率图片。您如何检测用户何时上传?我正在为 PHP 使用 GD 库。使用 imagejpeg() 方法将质量设置为 90 对它没有任何作用,而是缩放尺寸,然后将 ppi 设置为 72。我希望能够同时保留尺寸并将 ppi 降至 72。任何建议将不胜感激。

4

6 回答 6

21

就您需要关注的而言,没有 PPI 这样的东西。此外,DPI 不存在于数字中。只有像素和尺寸(只是在任一方向上的像素测量)。

您真正想做的是对图像进行下采样,从而减小图像的整体尺寸。您可能希望按比例执行此操作,也就是说,您希望保持相同的宽高比,以便图像在重新采样后不会显得拉伸。另外值得注意的是,调整大小和重新采样的不同之处在于调整大小并不太关注内容,导致调整后的图像在视觉上非常糟糕。您可能需要重新采样。

PHP 文档有一些关于处理上传文件以及如何使用 GDImage 库调整图像大小的优秀示例。我建议你检查一下。您可能想了解的其他相关方法:

  • getimagesize()将让您在不打开图像的情况下检查图像的尺寸(用于检查是否需要在不加载图像的情况下调整其大小)。
  • imagesx()imagesy()抓取 GD Image 资源的尺寸。
于 2011-01-21T01:45:44.157 回答
15

PPI、DPI...

首先,让我们澄清一下术语。PPI(每英寸像素数)和DPI (每英寸点数)都是指定将像素转换为物理单位(在本例中为英寸)的比率。在数字世界中——计算机、图像…… DPI 被错误地使用在应该使用 PPI 的地方。DPI 实际上只存在于印刷界。但现在对我们来说,DPI = PPI>> 更多信息

分辨率信息(有时称为 DPI,但它是 PPI)存储在标头(图像元信息)中。JPG 和 PNG 确实支持这一点;但GIF 不支持 DPI - 它不存在于 GIF 标头中。

在 PHP 中更改 PPI

那么,您可能会问如何在图像标题中设置 PPI(DPI)?在 PHP 中,您可以使用 Imagick 库(当然不适用于 GIF):

$image = new Imagick('img.jpg'); // default 72 dpi image
$image->setImageResolution(500, 500);
$image->writeImage("img-500dpi.jpg"); // this image will have 500 dpi

如果您下载这些图像并尝试在 IrfanView 中打印它们,它实际上会使用 dpi 信息将像素转换为目标物理单位。两个图像将以不同的尺寸打印。

图片 PPI 在网络上不起作用

坏消息是,在网页上显示图像时,这不会改变任何东西。显示的锚单元始终是 CSS 中的一个像素。因此img.jpgimg-500dpi.jpg在浏览器中将具有完全相同的大小。即使您直接打开图像。即使您使用物理单位,例如cm

img { width: 8cm; height: 6cm; }

两个图像将以相同的尺寸显示;无论图像分辨率如何,物理单位都使用固定比率转换为像素。令人惊讶的是,即使您尝试在 Firefox 中打印原始图像(而不是页面),它们也会以相同的尺寸打印。无法评论其他浏览器。很奇怪——这在 Irfanview 中按预期工作。

PPI 和视网膜图像

现在随着 Iphone 等视网膜(即高分辨率)图像变得流行。这里谈了很多关于 DPI(实际上是 PPI)的内容,但这都只与目标设备和CSS 媒体查询有关。没有什么可以真正识别您图像的 PPI;您必须以像素为单位指定高分辨率视网膜图像的实际尺寸。这是 66x66 图标的示例(来自此处):

@media (-webkit-min-device-pixel-ratio: 2), 
       (min-resolution: 192dpi) { 
    .box {
        background:url('images/icon66x66.png') no-repeat top left;
        background-size: 33px 33px;
    }
}

因此,您实际上可以通过在 CSS 中为它们设置较低的尺寸来“缩小”高分辨率图像。但我只建议对视网膜图像和正确的媒体查询执行此操作。

所以,你必须在 PHP 中重新采样

所以事实上,如果你想让上传的图片在“网络上”看起来更小,最好的方法是重新采样。重采样意味着不只是改变标题,而是改变图像的实际像素矩阵。这是我在 PHP 中使用的代码,它使用了 GD 库:

$t = imagecreatefromjpeg($old_img_path);
$s = imagecreatetruecolor($new_width, $new_height);
$x = imagesx($t);
$y = imagesy($t);
imagecopyresampled($s, $t, 0, 0, 0, 0, $new_width, $new_height, $x, $y);
imagejpeg($s, $new_img_path);
chmod($new_img_path, 0644);

请注意,这需要相当多的内存,这可能会受到您的托管服务提供商的限制。

于 2014-01-24T23:56:14.160 回答
1

如果您经常处理高分辨率图像,我会沿着 ImageMagick 路径走,因为它更快 + 提供有关图像的更多信息 + 如果您愿意,可以让您以 300 DPI(或其他分辨率)写回图像.

这是我对 Jcrop 和 ImageMagick 所做的(但 DPI 为 72)

    $picture = new Imagick($src);
    $picture->cropImage( $_POST['w'],  $_POST['h'],  $_POST['x'],  $_POST['y']);

    $picture->resizeImage(690, 500, Imagick::FILTER_LANCZOS,1, true);
    $picture->writeImage($cropped);
    $picture->clear();
    $picture->destroy();
于 2011-01-21T04:28:58.143 回答
1

使用 phpthumb ( http://phpthumb.gxdlabs.com ) 是一个很好、优雅且简单的解决方案。

我有一个使用它上传到 GitHub 的工作代码示例。它可以同时使用 GD 和 Imagemagick,这取决于你。

https://github.com/lopezator/thumbNailGenerator

于 2014-01-21T14:11:13.980 回答
1

bool Imagick::setResolution ( float $x_resolution , float $y_resolution )

于 2014-07-22T17:53:43.467 回答
0

如果您要减少 ppi,尺寸会发生变化以反映减少情况 - 每英寸像素越少意味着图片的英寸数越少。

于 2011-01-21T01:45:13.497 回答