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
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.
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.
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.
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 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.