gpt4 book ai didi

php - 为什么 PHP 在加载从 facebook 获取的图像时无法生成图像?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:41:37 25 4
gpt4 key购买 nike

几年前,我编写了一个 PHP (ZEND) 模块,至今仍在我的一些项目中使用。该模块是在对 PHP 图像处理有相当基本的了解(即 copypasta)的情况下构建的,但除了在一种情况下外,工作起来很漂亮。

该模块从表中提取 blob 数据,将其解析为图像,使用 imagcopyresampled() 调整其大小,然后将生成的 .jpg 发送到浏览器,它被称为标准 Controller 操作。

它似乎在所有情况下都有效,除非原始图像是由用户从 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, 0, 0, $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, 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, //Destination Image
$inputImage, //Original Image
$left, $top, //Destination top left Coord
0, 0, //Source top left coord
$calculatedWidth, $calculatedHeight, //Final location Bottom Right Coord
$inputWidth, $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 查看此问题的另一个示例它显示一个蓝色方 block ,而不是存储在数据库中的图像。

最佳答案

上传后尝试自动“重新保存”图像

imagejpeg(imagecreatefromjpeg($filename),$filename,9);

这应该会根据原始 Facebook 图片重新创建任何格式错误或无法识别的 header 。

关于php - 为什么 PHP 在加载从 facebook 获取的图像时无法生成图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17903552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com