我获得了一个可以从JPEG here读取DPI值的函数。
function get_dpi($filename){
$a = fopen($filename,'r');
$string = fread($a,20);
fclose($a);
$data = bin2hex(substr($string,14,4));
$x = substr($data,0,4);
$y = substr($data,4,4);
return array(hexdec($x),hexdec($y));
}
但是,当我检查Photoshop在300DPI下创建的图像时,它错误地返回了42DPI的值。
我想念什么?
由Photoshop生成的有问题的图像:https://drive.google.com/open?id=117LHlgpefXZsuiVSl_nMG6MUQfKcT1MI
更新:我尝试使用online DPI converter重新生成300DPI的JPEG,PHP函数报告了正确的值300DPI。
重新生成的图像:https://drive.google.com/open?id=1-C4GZ8_K4wit3sISz21ngd4OVlLXuL72
我比较了2个JPEG的元数据,生成的JPEG具有JIFF信息,但是初始JPEG没有。那是问题的原因吗?
鉴于我没有Imagick库,因此无法使用其getImageResolution()
函数来读取值。
答案 0 :(得分:0)
感谢@ golddragon007的帮助,我的最终解决方案是合并各种功能的数据,如下所示:
function get_dpi($filename){
$new_filename = time() . '_' . rand(1000, 999999) . '.jpg';
$result = move_uploaded_file($filename, 'upload/' . $new_filename);
$dpi_from_exif = get_exif('upload/' . $new_filename);
if($dpi_from_exif !== false) {
unlink('upload/' . $new_filename);
return $dpi_from_exif;
} else {
$a = fopen('upload/' . $new_filename,'r');
$string = fread($a, 20);
fclose($a);
$data = bin2hex(substr($string, 14, 4));
$x = substr($data, 0, 4);
$y = substr($data, 4, 4);
unlink('upload/' . $new_filename);
return hexdec($x);
}
}
function get_exif($filename) {
$exif = exif_read_data($filename);
if($exif === false) {
return false;
} else {
if(array_key_exists('XResolution', $exif)) {
return do_maths($exif['XResolution']);
} else {
return false;
}
}
}
function do_maths($expression) {
eval('$o = ' . preg_replace('/[^0-9\+\-\*\/\(\)\.]/', '', $expression) . ';');
return $o;
}
用法如下:
$dpi_in_int = get_dpi($the_image_file);
如果我使用问题中引用的图像,该函数将返回:
300
功能说明:
在我的情况下,我从<input type="file" />
中读取了上载的文件,get_dpi($filename)
首先将临时上载文件移动到了upload/
文件夹中(可选步骤),然后读取了使用get_exif($filename)
函数从EXIF获取DPI。
如果可以从EXIF数据中读取DPI,则将返回DPI值;否则,DPI值是从JPEG元数据(JPEG文件的前几个字节)中获取的,在某些情况下(例如,我提供的第一张图像),这被证明是不准确的。
do_maths()
函数将从EXIF的IPF0数据的XResolution
中解析出值(显然是数学方程式3000000/10000
)并计算最终值。请注意,eval()
存在一些潜在的安全问题,因此首先使用preg_replace()
正则表达式清除输入,以确保不存在注入代码。此do_maths()
函数来自https://stackoverflow.com/a/5805773/188331
最后,get_dpi()
函数将删除上载的文件以节省服务器中的磁盘空间(可选)。