How do You Resize a High Resolution Picture with PHP

前端 未结 6 1888
天命终不由人
天命终不由人 2020-12-24 09:34

I\'m processing images when the user uploads a pic but my problem is high rez pics. How do you detect when the user uploads one? I\'m using the GD library for PHP. Setting

6条回答
  •  难免孤独
    2020-12-24 10:22

    PPI, DPI...

    First, let us clarify the terminology. Both PPI (pixels per inch) and DPI (dot per inch) are ratios that specify conversion of pixels to physical units (inch in this case). In the digital world - computers, images, ... DPI is mistakenly used where PPI should be used instead. DPI in fact only exist in a printing world. But for us now, DPI = PPI. >> More info

    The resolution information (sometimes refered to as DPI, but it is PPI) is stored in the headers (image meta information). JPG and PNG do support this; but GIF doesn't support DPI - it is not present in the GIF header.

    Change PPI in PHP

    So, you are probably asking how to set PPI (DPI) in the image header? In PHP, you can do it using Imagick library (of course not for GIFs):

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

    If you download these images and try to print them e.g. in IrfanView, it will actually use the dpi information to convert pixels to target physical unit. Both images will be printed in different size.

    Image PPI won't work on web

    Bad news is that this won't change anything when displaying the image on a web page. The anchor unit for the display is always a pixel in CSS. So img.jpg and the img-500dpi.jpg will have exactly the same size in the browser. Even if you open the images directly. Even if you use physical unit like cm:

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

    both images will be displayed in the same size; physical units are converted to pixels regardless of the image resolution using fixed ratio. And surprisingly even if you try to print the raw images (not the page) in Firefox, they both will be printed at the same size. Cannot comment on other browsers. Strange enough - this works as expected in Irfanview.

    PPI and retina images

    Now with Iphones etc. retina (i.e. high resolution) images are becoming trendy. Here, a lot is spoken about DPI (PPI in fact), but this is all related only to the target device and the CSS media queries. There is nothing that would actually recognize the PPI of your image; you have to specify the actual dimensions of the high-res retina image in pixels. This is an example for 66x66 icon (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;
        }
    }
    

    So you can actually "downscale" the high-res images by setting lower dimensions for them in the CSS. But I would only recommend to do this for retina images and within correct media query.

    So, you have to resample in PHP

    So in fact, if you want to make uploaded image appear smaller "on the Web", the best way is to resample it. Resampling means not to change the header only, but to change the actual pixel matrix of the image. Here is the code I use in PHP, which uses the GD library:

    $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);
    

    Be aware that this requires quite a lot of memory, which might be limited by your hosting provider.

提交回复
热议问题