PNG: Druckgröße (DPI) auslesen mit PHP

(Kommentare: 0)

Mit PHP kann man direkt eine PNG-Bild-Datei einlesen, aber man bekommt nur die Pixel und die Größe, aber keine Information über die Druckauflösung (DPI, dots per inch). Man muss noch einmal selbst die PNG-Datei öffnen und die Information auslesen.

Die folgendne PHP-Klasse liest die PNG-Datei, bis sie die entsprechende Information gefunden hat.

<?php

/**
* Class to read PNG image with dpi / resolution information.
*
* Siehe auch http://www.fileformat.info/format/png/corion.htm
*
* @copyright Ingmar Decker 2010, www.webdecker.de
* @author Ingmar Decker
*/
class PngImageReader {

public function PngImageReader() {
}

/** Returns type: 'png'. */
public function getType() {
return 'png';
}

/** Returns true iff this reader can read given file (at least file extension should be
* checked.
* @return bool True if reader can read file, false otherwise
*/
public function canRead($filename) {
$pi = pathinfo($filename);
$ext = strtolower($pi['extension']);
return ($ext == 'png');
}

/** Reads file and returns array with 6 elements: type name, image resource, with, height, dpi for x, dpi for y.
* Dpi values might be 0 if file format does not provide dpi or other resolution information.
*/
public function read($filename) {
$type = $this->getType();
$r = array($type, null, 0, 0, 0, 0);
$image = imagecreatefrompng($filename);
if ($image) {
$w = imagesx($image);
$h = imagesy($image);
list($xdpi, $ydpi) = $this->getDpi($filename);
$r = array($type, $image, $w, $h, $xdpi, $ydpi);
}
return $r;
}

/** Get dpi / print resolution of given png file. Returns array with dpiX, dpiY as values. */
private function getDpi($filename) {
$dpi = array(0, 0);
$file = fopen($filename, 'rb');
$header = fread($file, 8);
if (substr($header, 1,3) != 'PNG') throw new Exception("$filename is not PNG file.");
while (!feof($file)) {
list($len, $type, $data, $crc) = $this->readChunk($file);
if ($type == 'pHYs') {
$dx = unpack('N', substr($data, 0, 4));
$dy = unpack('N', substr($data, 4, 4));
$unit = $data[8];
if (ord($unit) == 1) {
// 1 == meter, 0 == unknown
// $dx, $dy are dots or pixels per meter, 1 inch = 0.0254 meter
$dpi = array($dx[1] * 0.0254, $dy[1] * 0.0254);
break;
}
}
}
fclose($file);
return $dpi;
}

/** Reads a png chunk and returns array with length in bytes, type string, data bytes, crc code.
*/
private function readChunk($file) {
$data = '';
$type = '';
$crc = '';
$len = fread($file, 4);
if ($len) {
$len = unpack('N', $len); // 'N' = big endian unsigned long, 'V' little endian
$len = $len[1];
$type = fread($file, 4);
if ($len) $data = ($len ? fread($file, $len) : '');
$crc = fread($file, 4);
}
return array($len, $type, $data, $crc);
}

}

?>

Zurück

Kommentare

Einen Kommentar schreiben