【问题标题】:How do You Resize a High Resolution Picture with PHP如何使用 PHP 调整高分辨率图片的大小
【发布时间】:2011-06-12 21:07:17
【问题描述】:

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

【问题讨论】:

标签: php image gd high-resolution


【解决方案1】:

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

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

PHP 文档中有一些关于handling uploaded fileshow to resize images 使用GDImage 库的优秀示例。我建议你检查一下。您可能想了解的其他相关方法:

  • getimagesize() 可让您在不打开图像的情况下检查图像的尺寸(有助于检查是否需要在不加载图像的情况下调整其大小)。
  • imagesx()imagesy() 抓取 GD Image 资源的尺寸。

【讨论】:

  • 非常感谢您的洞察力。我会检查这些方法。我忘了提到我正在使用 jCrop,基本上它是将它传递给一个处理各种尺寸输出的函数。但高分辨率照片让我感到困惑。
  • 您可能对他们有关缩放大图像的文档页面感兴趣:deepliquid.com/content/Jcrop_Sizing_Issues.html
  • 非常有趣。我会记住这一点。感谢您的发现!
  • +1 用于解释调整大小和重新采样之间的区别。
【解决方案2】:

PPI、DPI...

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

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

在 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 在网络上不起作用

坏消息是,当在网页上显示图像时,这不会改变任何东西。用于显示的anchor unit 在 CSS 中始终是一个像素。所以img.jpgimg-500dpi.jpg 在浏览器中的大小完全相同。即使您直接打开图像。即使你使用像cm这样的物理单位:

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

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

PPI 和视网膜图像

现在有了 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 中重新采样

所以事实上,如果你想让上传的图片在“网络上”看起来更小,最好的方法是重新采样。重采样意味着不只是改变标题,而是改变图像的实际像素矩阵。这是我在 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);

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

【讨论】:

    【解决方案3】:

    如果您经常处理高分辨率图像,我会选择 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();
    

    【讨论】:

    • 很好,我一直在读到 imagick 非常强大,所以如果其他方法都失败了,我可能会使用这种方法。非常感谢!
    【解决方案4】:

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

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

    https://github.com/lopezator/thumbNailGenerator

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • 我的意思是说分辨率,因为我试图检测用户何时上传分辨率设置为 300 的图片,但当您设置为 72 时,图像实际上很小。跨度>
        • 这是真的吗?因为我读过 ppi 和 dpi 用于打印,在 PC 上无用
        • @Alex 显示图像时,ppi/dpi 指示图像质量,当在屏幕上以“100%”尺寸查看时。
        猜你喜欢
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-28
        • 1970-01-01
        • 1970-01-01
        • 2012-01-07
        相关资源
        最近更新 更多