为什么PHP在加载从Facebook拍摄的图像时无法生成图像?
|
几年前,我创作了一个 PHP(ZEND)模块,我今天在一些项目中仍然使用它.这个模块是基于对PHP图像处理的相当基本的(即copypasta)理解而构建的,但在一种情况下工作得很漂亮. 模块从表中提取blob数据,将其解析为图像,使用imagcopyresampled()调整其大小,然后将生成的.jpg发送到浏览器,它被称为标准控制器操作. 它似乎适用于所有情况,除非用户从Facebook保存原始图像(即右键单击Facebook图像查看器并下载到桌面然后上传到客户端站点).我自己测试了很多次并且能够复制它.我还能够通过photoshop重新保存时上传相同的图像,而不会遇到问题. 我怀疑facebook图像显示在文件中添加了一些导致我的系统中断的额外元数据. 这有解决方案吗? PHP映像模块的代码如下: private function _buildImage($mode) {
//Prepare the output image
//Currently CROP and RESIZE are using different output onstruction calls
//So $finalImage is initialized prior to entering the mode blocks.
$finalImage = imagecreatetruecolor($this->_width,$this->_height);
$backgroundFillColor = imagecolorallocate($finalImage,RED,BLUE,GREEN);
imageFill($finalImage,$backgroundFillColor);
$this->_table = $this->_getTable($mode);
$image = $this->_request->image;
$this->_imageData = $this->_table->fetchEntryAsRow($image);
//Set top and left to 0 to capture the top/left corner of the orignal image.
$top = 0;
$left = 0;
$inputImage = imagecreatefromstring( $this->_imageData->image);
list($inputWidth,$inputHeight) = $this->_getImageSize($this->_imageData->image);
//Ratio is the target ratio of $this->_width divided by $this->_height,as set in actions.
//For index thumbnails this ratio is .7
//For index large images this ratio is 2
$ratio = $this->_width / $this->_height;
//define offset width and offset height as being equal to input image width and height
$offsetWidth = $inputWidth;
$offsetHeight = $inputHeight;
//Define Original Ratio as found in the image in the table.
$inputRatio = $inputWidth / $inputHeight;
//Rendering maths for RESIZE and CROP modes.
//RESIZE forces the whole input image to appear within the frame of the output image.
//CROP forces the output image to contain only the relevantly sized piece of the input image,measured from the middle.
if($this->_mode == CROP) {
if($inputRatio > $ratio) {
//Original image is too wide,use $height as is. Modify $width;
//define $scale: input is scaled to output along height.
$scale = $inputHeight / $this->_height;
//Calculate $left: an integer calculated based on 1/2 of the input width * half of the difference in the rations.
$left = round(($inputWidth/2)*(($inputRatio-$ratio)/2),0);
$inputWidth = round(($inputWidth - ($left*2)),0);
$offset = $offsetWidth - $inputWidth;
} else {
//Original image is too high,use $width as is. Modify $height;
$scale = $inputWidth / $this->_width;
$inputHeight = round(($this->_height * $scale),0);
$offset = $offsetHeight - $inputHeight;
$top = $offset / 2;
}
imagecopyresampled($finalImage,//Destination Image
$inputImage,//Original Image
0,//Destination top left Coord
$left,$top,//Source top left coord
$this->_width,$this->_height,//Final location Bottom Right Coord
$inputWidth,$inputHeight //Source bottom right coord.
);
} else {
if($inputRatio < $ratio) {
//Original image is too wide,use $height as is. Modify $width;
$scale = $inputHeight / $this->_height;
$calculatedWidth = round(($inputWidth / $scale),0);
$calculatedHeight = $this->_height;
$offset = $this->_width - $calculatedWidth;
$left = round(($offset / 2),0);
$top = 0;
} else {
//Original image is too high,use $width as is. Modify $height;
$scale = $inputWidth / $this->_width;
$calculatedHeight = round(($inputHeight / $scale),0);
$calculatedWidth = $this->_width;
$offset = $this->_height - $calculatedHeight;
$top = round(($offset / 2),2);
}
imagecopyresampled($finalImage,//Original Image
$left,//Destination top left Coord
0,//Source top left coord
$calculatedWidth,$calculatedHeight,$inputHeight //Source bottom right coord.
);
}
imagejpeg($finalImage,null,100);
imagedestroy($inputImage);
imagedestroy($finalImage);
}
我怀疑问题实际上可能与_getImageSize的实现有关. private function _getImageSize($data)
{
$soi = unpack('nmagic/nmarker',$data);
if ($soi['magic'] != 0xFFD8) return false;
$marker = $soi['marker'];
$data = substr($data,4);
$done = false;
while(1) {
if (strlen($data) === 0) return false;
switch($marker) {
case 0xFFC0:
$info = unpack('nlength/Cprecision/nY/nX',$data);
return array($info['X'],$info['Y']);
break;
default:
$info = unpack('nlength',$data);
$data = substr($data,$info['length']);
$info = unpack('nmarker',$data);
$marker = $info['marker'];
$data = substr($data,2);
break;
}
}
}
您可以在http://www.angelaryan.com/gallery/Image/22看到此问题的另一个示例,该示例显示蓝色方块,而不是存储在数据库中的图像. 上传后尝试自动“重新保存”图像imagejpeg(imagecreatefromjpeg($filename),$filename,9); 这应该从原始Facebook图像重新创建任何格式错误或无法识别的标题. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
