Friday, October 10, 2008

PHP: JPEG/JPG DPI function

While working with a lot of JPEG images lately I needed to be able to set the DPI with PHP and I was having trouble finding a way to do that with the native PHP or GD functions. The stuff I did find seemed to be overly complicated or just plain wrong.

So I wrote my own DPI function for PHP that rather than doing pointless resampling simply adjusts the file header.
My needs didn't require me to do it "right", but it will handle from 1 to 255 DPI.

/*
@$jpg -- Path to a jpg file
@$dpi -- DPI to use (1-255)
*/
function set_dpi($jpg, $dpi = 163)
{
$fr = fopen($jpg, 'rb');
$fw = fopen("$jpg.temp", 'wb');

stream_set_write_buffer($fw, 0);

fwrite($fw, fread($fr, 13) . chr(1) . chr(0) . chr($dpi) . chr(0) . chr($dpi));

fseek($fr, 18);
stream_copy_to_stream($fr, $fw);

fclose($fr);
fclose($fw);

unlink($jpg);
rename("$jpg.temp", $jpg);
}

2 comments:

Anonymous said...

Very helpful. But could you please tell me the process to convert image to higher dpi value, eg. 300dpi?

Anonymous said...

Anything over 255 is more than 8bits, so you have to tweak the chr(0) . chr($dpi) . chr(0) . chr($dpi) part of the code. ASCII 0 = 0 binary and ASCII 255 (255dpi)equals 11111111 binary. 400 decimal (400dpi) = 110010000, 9bits. So I changed both chr(0) from a 0 character to a 1 character (binary 00000001). That takes care of the first digit of my 9bit number. The rest of the 8 bits (10010000) equal 144 decimal. So I changed my $dpi variable to 144.