最近开发一套绣标生产管理系统,遇到一个问题就是如果用户上传的图片是除了基线(“标准”)外的格式,印刷机会认不出来。所以需要在上传时进行检测。
网上没有找到现成的方案,前后尝试了三种方式,最后成功解决准确识别photoshop格式类型的方法。
为了避免遇到同样问题的朋友少走弯路,特将解决方法和代码分享出来。
方法一:
/**
* 检测JPEG图片的基线优化标准
*最初的版本,只能识别是否连续模式,并且准确性有点问题
* @param $filename string 图片路径
* @return string 图片基线优化标准 FFC0=标准,FFC2=连续,0000=不支持
*/
function get_interlace_old($filename)
{
if(!file_exists($filename)) throw new Exception("no found file!");
$file = @fopen($filename,"rb");
if(!$file) throw new Exception("file refuse!");
$bin = fread($file, 2*8*50000); //只读15字节 各个不同文件类型,头信息不一样。
fclose($file);
//ffc0的几种格式
//ffc0 0011 0800 3800 3803 0122 0002 1101
//ffc0 0011 0800 3800 3803 0122 0002 1101
//ffc0 0011 0802 4f02 4f03 0122 0002 1101
//ffc2的几种格式
//ffc2 0011 0802 4f02 4f03 0111 0002 1101
//ffc2 0011 0802 4f02 4f03 0122 0002 1101
$f = implode(' ',str_split(bin2hex($bin),4));
// var_dump($f);
if(strpos($f,'ffc2 0011 080'))return 'SOF2';
if(strpos($f,'ffc0 0011 080'))return 'SOF0';
return '0000';
}
方法二:
/**
* 检测JPEG图片的基线优化标准
* 第二个版本,只能识别是否连续模式,准确性没问题(使用ImageMagick工具集的identify命令实现)
* @param $filename string 图片路径
* @return string 图片基线优化标准 FFC0=标准,FFC2=连续,0000=不支持
*/
function get_interlace2($filename)
{
if(PHP_OS=='Darwin'){
$result = `/usr/local/bin/identify -verbose $filename |grep Interlace`;//调用系统命令covert处理图片 支持dpi调整
}elseif(substr(PHP_OS,0,3)==='WIN'){
exit();
}else{
$result = `identify -verbose $filename |grep Interlace`;
}
if(strpos($result,'Interlace: None')!==false){
return 'SOF0';
}else if(strpos($result,'Interlace: JPEG')!==false){
return 'SOF2';
}else{
return '0000';
}
}
方法三:
/**
* 检测JPEG图片的基线优化标准
* 这个版本是,识别是否连续模式,如是标准模式还能识别是否优化
* @param $filename string 图片路径
* @return string 图片基线优化标准 Baseline.Standard=基线标准,Baseline.Optimized=基线已优化,Progressive.Progressive=连续,unknow=不支持
*/
function get_interlace($filename)
{
if(!file_exists($filename)) throw new Exception("no found file!");
$file = @fopen($filename,"rb");
if(!$file) throw new Exception("file refuse!");
$bin = fread($file, 2*8*50000); //只读15字节 各个不同文件类型,头信息不一样。
fclose($file);
$f = implode(' ',str_split(bin2hex($bin),4));
if(strpos($f,'3842 494d 0406 0000 0000 0007 0008 0000 0001 0100'))return 'Baseline.Standard';
if(strpos($f,'3842 494d 0406 0000 0000 0007 0008 0001 0001 0100'))return 'Baseline.Optimized';
if(strpos($f,'3842 494d 0406 0000 0000 0007 0008 0101 0001 0100'))return 'Progressive.Progressive';
return 'unknow';
}
方法三之2:
/**
* 检测JPEG图片的基线优化标准
*
* @param $filename string 图片路径
* @return string 图片基线优化标准 Baseline.Standard=标准,Baseline.Optimized=优化,Progressive.Progressive=连续,unknow=不支持
*/
function get_interlace4($filename)
{
if(!file_exists($filename)) throw new Exception("no found file!");
$size = getimagesize($filename, $info);
$f='';
if(isset($info['APP13']))
{
$bin = substr($info['APP13'],-6,2);
$f = implode(' ',str_split(bin2hex($bin),4));
}
switch($f){
case '0000':
$psformat = 'Baseline.Standard';
break;
case '0001':
$psformat = 'Baseline.Optimized';
break;
case '0101':
$psformat = 'Progressive.Progressive';
break;
default:
$psformat = 'unknow';
}
return $psformat;
}
最后给出一个测试用的脚本:
/**
* 检测JPEG图片的基线优化标准
*
* @param $filename string 图片路径
* @return string 图片基线优化标准 Baseline.Standard=基线标准,Baseline.Optimized=基线已优化,Progressive.Progressive=连续,unknow=不支持
*/
function get_interlace1($filename)
{
if(!file_exists($filename)) throw new Exception("no found file!");
$file = @fopen($filename,"rb");
if(!$file) throw new Exception("file refuse!");
$bin = fread($file, 2*8*50000); //只读15字节 各个不同文件类型,头信息不一样。
fclose($file);
$f = implode(' ',str_split(bin2hex($bin),4));
if(strpos($f,'3842 494d 0406 0000 0000 0007 0008 0000 0001 0100'))return 'Baseline.Standard';
if(strpos($f,'3842 494d 0406 0000 0000 0007 0008 0001 0001 0100'))return 'Baseline.Optimized';
if(strpos($f,'3842 494d 0406 0000 0000 0007 0008 0101 0001 0100'))return 'Progressive.Progressive';
return 'unknow';
}
?>
请选择文件:
if($_FILES){
$arr = $_FILES["file"];
// $pa = get_interlace('runtime/180808171002-00001-a0.jpg');
// $pb = get_interlace('runtime/180808171002-00001-a1.jpg');
// $pc = get_interlace('runtime/180808171002-00001-c.jpg');
$pc = '';
// $pa = get_interlace($arr['tmp_name']);
// $pa = get_interlace2($arr['tmp_name']);
$pa = get_interlace($arr['tmp_name']);
echo '
文件名:'.$arr['name'];
echo '
文件类型:'.$arr['type'];
echo '
文件大小:'.$arr['size'];
echo '
平台:'.PHP_OS;
echo '
检测结果:';
if($pa=='Baseline.Standard'){
echo '基线标准模式【允许】';
}elseif($pa=='Baseline.Optimized'){
echo '基线已优化模式【禁止】';
}elseif($pa=='Progressive.Progressive'){
echo '连续【禁止】';
}else{
echo '不能识别【禁止】';
// var_dump($pa);
}
}
?>