Monthly Archives: September 2012

PHP: Dpi of a png image

I recently needed to determine the DPI of a set of PNG files (so that I could convert the size to points), with the exception of imagemagick there is no way to do this.

So here is a pure-php method of extracting the DPI from a PNG file, it searches for the pHYs chunk (which may or may not exist).

function read_png_dpi($source)
{
  $fh = fopen($source, 'rb');
  if (!$fh)
    return false;
  
  $dpi = false;
  
  $buf = array();
  
  $x = 0;
  $y = 0;
  $units = 0;
  
  while(!feof($fh)) {
    array_push($buf, ord(fread($fh, 1)));
    if (count($buf) > 13)
      array_shift($buf);
    if (count($buf) < 13)
      continue;
    if ($buf[0] == ord('p') &&
        $buf[1] == ord('H') &&
        $buf[2] == ord('Y') &&
        $buf[3] == ord('s'))
    {
      $x = ($buf[4] << 24) + ($buf[5] << 16) + ($buf[6] << 8) + $buf[7];
      $y = ($buf[8] << 24) + ($buf[9] << 16) + ($buf[10] << 8) + $buf[11];
      $units = $buf[12];
      break;
    }
  }
  
  fclose($fh);
  
  if ($x == $y)
    $dpi = $x;
    
  if ($dpi != false && $units == 1) //meters
    $dpi = round($dpi * 0.0254);
  
  return $dpi;
}