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

(Kommentare: 1)

Im Web kursieren Code-Teile und Klassen in PHP, mit denen man die Auflösung (Druckauflösung, DPI, dots per inch) aus einer JPEG-Datei lesen kann. Hat leider nicht oft nicht funktioniert. Habe es noch etwas optimiert.

Die Lösung basiert auf der, die in der PHP-Online-Dokumentation zu finden ist unter imagejpeg(), dazu Infos von www.fileformat.info  über den JFIF-Header.

    /** Reads JPG-file and returns array with 6 elements: type name, image resource, width, height, dpi for x, dpi for y.
* Dpi values might be 0 if file format does not provide dpi or other resolution information.
* Usage:
* list($type, $image, $w, $h, $dpix, $dpiy) = readJpeg($filename);
*/
function readJpeg($filename) {
$type = 'jpeg';
$r = array($type, null, 0, 0, 0, 0);
$image = @imagecreatefromjpeg($filename);
if ($image) {
$w = imagesx($image);
$h = imagesy($image);
$dpix = 0;
$dpiy = 0;

// from: http://php.net/manual/de/function.imagejpeg.php
// soapergem at gmail dot com
// 06-Nov-2008 09:48
$exif = null;
if (function_exists('exif_read_data')) exif_read_data($filename, 'IFD0');
$x = $y = 0;
if (isset($exif['XResolution']) && isset($exif['YResolution'])) {
#$x = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['XResolution']));
#$y = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['YResolution']));
$m = array();
if (ereg('^([0-9]+)/([0-9]+)$', $exif['XResolution'], $m)) {
if ($m[2] != 0) {
$x = $m[1] / $m[2];
} else $x = 0;
} else {
$x = floatval($exif['XResolution']);
}
if (ereg('^([0-9]+)/([0-9]+)$', $exif['YResolution'], $m)) {
if ($m[2] != 0) {
$y = $m[1] / $m[2];
} else $y = 0;
} else {
$y = floatval($exif['YResolution']);
}
}
if (!$x && !$y && $fp = fopen($filename, 'r')) {
// from. http://www.fileformat.info/format/jpeg/egff.htm
// last visited 29.3.2010
// typedef struct _JFIFHeader
// {
// BYTE SOI[2]; /* 00h Start of Image Marker */
// BYTE APP0[2]; /* 02h Application Use Marker */
// BYTE Length[2]; /* 04h Length of APP0 Field */
// BYTE Identifier[5]; /* 06h "JFIF" (zero terminated) Id String */
// BYTE Version[2]; /* 07h JFIF Format Revision */
// BYTE Units; /* 09h Units used for Resolution */
// BYTE Xdensity[2]; /* 0Ah Horizontal Resolution */
// BYTE Ydensity[2]; /* 0Ch Vertical Resolution */
// BYTE XThumbnail; /* 0Eh Horizontal Pixel Count */
// BYTE YThumbnail; /* 0Fh Vertical Pixel Count */
// } JFIFHEAD;
// Units, Xdensity, and Ydensity identify the unit of measurement used to describe the image resolution.
// Units may be 01h for dots per inch, 02h for dots per centimeter, or 00h for none (use measurement as
// pixel aspect ratio). Xdensity and Ydensity are the horizontal and vertical resolution of the image
// data, respectively. If the Units field value is 00h, the Xdensity and Ydensity fields will contain
// the pixel aspect ratio (Xdensity : Ydensity) rather than the image resolution. Because non-square
// pixels are discouraged for portability reasons, the Xdensity and Ydensity values normally equal 1
// when the Units value is 0.

$string = fread($fp, 20);
fclose($fp);
$units = hexdec(bin2hex(substr($string, 13, 1)));
$jx = hexdec(bin2hex(substr($string, 14, 2)));
$jy = hexdec(bin2hex(substr($string, 16, 2)));

if ($units == 1) {
// resolution in dots per inch
$x = $jx;
$y = $jy;
} else if ($units == 2) {
$x = $jx * 2.54;
$y = $jy * 2.54;
}
}
if ($x && $y) {
$dpix = $x;
$dpiy = $y;
}
$r = array($type, $image, $w, $h, $dpix, $dpiy);
}
return $r;
}

Das hat bei mir jetzt für die Varianten JPEG mit EXIF, JPEG ohne EXIF und JPEG mit beiden funktioniert.

Zurück

Kommentare

Kommentar von Moritz |

Cool, hat mir sehr geholfen: (hab daraus eine Extension-Mod für fPDF gebastelt...)

Einen Kommentar schreiben