【发布时间】:2011-06-12 21:07:17
【问题描述】:
当用户上传图片时,我正在处理图片,但我的问题是高分辨率图片。您如何检测用户何时上传?我正在为 PHP 使用 GD 库。使用 imagejpeg() 方法将质量设置为 90 对它没有任何作用,而是缩放尺寸,然后将 ppi 设置为 72。我希望能够保留尺寸并同时将 ppi 降低到 72。任何建议将不胜感激。
【问题讨论】:
标签: php image gd high-resolution
当用户上传图片时,我正在处理图片,但我的问题是高分辨率图片。您如何检测用户何时上传?我正在为 PHP 使用 GD 库。使用 imagejpeg() 方法将质量设置为 90 对它没有任何作用,而是缩放尺寸,然后将 ppi 设置为 72。我希望能够保留尺寸并同时将 ppi 降低到 72。任何建议将不胜感激。
【问题讨论】:
标签: php image gd high-resolution
就您需要关注的而言,没有 PPI 之类的东西。此外,DPI 不存在于数字中。只有像素和尺寸(只是对任一方向的像素的测量)。
您真正想做的是对图像进行下采样,从而减小图像的整体尺寸。您可能希望按比例执行此操作,也就是说,您希望保持相同的宽高比,以便图像在重新采样后不会显得拉伸。另外值得注意的是,调整大小和重新采样的不同之处在于调整大小并不太关注内容,导致调整后的图像在视觉上非常糟糕。您可能需要重新采样。
PHP 文档中有一些关于handling uploaded files 和how to resize images 使用GDImage 库的优秀示例。我建议你检查一下。您可能想了解的其他相关方法:
【讨论】:
首先,让我们澄清一下术语。 PPI(每英寸像素数)和 DPI(每英寸点数)都是指定将像素转换为物理单位(在本例中为英寸)的比率。在数字世界中 - 计算机、图像、...在应使用 PPI 的地方错误地使用了 DPI。 DPI 实际上只存在于印刷界。但现在对我们来说,DPI = PPI。 >> More info
分辨率信息(有时称为 DPI,但它是 PPI)存储在 headers(图像元信息)中。 JPG 和 PNG 确实支持这一点;但是GIF doesn't support DPI - 它不在GIF header 中。
那么,您可能会问如何在图像标题中设置 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 信息将像素转换为目标物理单位。两张图片将以不同的尺寸打印。
坏消息是,当在网页上显示图像时,这不会改变任何东西。用于显示的anchor unit 在 CSS 中始终是一个像素。所以img.jpg 和img-500dpi.jpg 在浏览器中的大小完全相同。即使您直接打开图像。即使你使用像cm这样的物理单位:
img { width: 8cm; height: 6cm; }
两张图片将以相同的尺寸显示;无论使用fixed ratio 的图像分辨率如何,物理单位都会转换为像素。令人惊讶的是,即使您尝试在 Firefox 中打印原始图像(不是页面),它们也会以相同的大小打印。无法评论其他浏览器。很奇怪——这在 Irfanview 中可以正常工作。
现在有了 Iphone 等,视网膜(即高分辨率)图像变得流行起来。这里谈了很多关于 DPI(实际上是 PPI)的内容,但这都只与目标设备和CSS media queries 有关。 没有什么可以真正识别您图像的 PPI;您必须以像素为单位指定高分辨率视网膜图像的实际尺寸。这是 66x66 图标 (from here) 的示例:
@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 中使用的代码,它使用了 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);
请注意,这需要相当多的内存,这可能会受到您的托管服务提供商的限制。
【讨论】:
如果您经常处理高分辨率图像,我会选择 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();
【讨论】:
使用 phpthumb (http://phpthumb.gxdlabs.com) 是一个很好、优雅且简单的解决方案。
我有一个使用它上传到 GitHub 的工作代码示例。它可以同时使用 GD 和 Imagemagick,这取决于您。
【讨论】:
bool Imagick::setResolution ( float $x_resolution , float $y_resolution )
【讨论】:
如果您要减少 ppi,尺寸会发生变化以反映减少情况 - 每英寸像素越少意味着图片的英寸数越少。
【讨论】: