3

我正在使用此代码从 Mapquest Traffic API 下载图像文件。

<?php
$files = glob("/root/TrafficHistory/*.gif");
$lastFileName = $files[count($files)-1];

$newFile = time() . ".gif";

$imgData = file_get_contents("http://www.mapquestapi.com/traffic/v2/flow?key=**REMOVED**&mapLat=34.05396382838673&mapLng=-118.24529104634557&mapHeight=1000&mapWidth=1000&mapScale=433342");
file_put_contents("/root/TrafficHistory/" . $newFile, $imgData);

$md5Old = md5_file($lastFileName);

if ($md5Old == md5_file("./" . $newFile)) {
    unlink("./" . $newFile);
    echo "\033[31mTraffic data same at " . time() . " aborting.\033[0m\n";
} else {
    echo "\033[32mNew traffic data downloaded to /root/TrafficHistory/" . $newFile  . " at " . time() . "\033[0m\n";
}
?>

尽管我在保存图像时发生错误,但代码可以完美运行。如此处所示您可以看到通过下载的流量覆盖file_get_contents似乎没有完全下载 GIF 图像。这是有问题的 GIF 的链接(它在浏览器中正确显示,但不会在 PhotoShop 中打开,说明文件意外结束)。请注意,通过这种方式下载的所有图像都以file_get_contents这种方式显示。虽然直接通过 API 链接查看时,它们显示完美。如果需要,这里也是 Mapquest Traffic API 的链接。谢谢你的帮助。

4

2 回答 2

1

您提供的文件肯定被截断了。它至少短 8 个字节。末尾有一个 GIF 图像数据块,声明长度为 168 字节,但此时文件中只剩下 162 字节。即使在那之后,至少应该有一个 0 终止符,然后是一个 GIF“预告片”块(字节 0x3B)。

浏览器旨在渲染部分下载的图像,因此它们不会抱怨这一点,尽管您可以看到损坏:在触及图像最底部的道路上,有垂直线(Firefox)或水平线的图案(Chrome)不应该在那里。

如果您执行以下代码将 8 个字节附加到文件,它会清除该损坏点,并且还可以在其他程序中打开该文件:

$data = file_get_contents('map.gif');
$data .= "\x00\x00\x00\x00\x00\x00" . "\x00" . "\x3B";
file_put_contents('map-repaired.gif', $data);

这是完成块的六个(空)字节,终止数据块的长度为 0 字节,然后是尾部字节。但是,这种粗略的修复不能作为所有其他图像的通用解决方案。

您提供的代码没有任何问题。我没有 API 的密钥,所以我无法实际测试它,但我只能想象 MapQuest 的最后一定有一个错误。也许它的 GIF 压缩器坏了,或者服务器发送了一个不正确的Content-LengthHTTP 标头?我真的不知道。

由于 MapQuest 可以返回 PNG 格式的图像,而且这显然有效,所以去吧。PNG 压缩总是优于 GIF 压缩(除非图像非常小 - 大约 100 字节;然后更复杂的 PNG 格式的标头使其处于劣势),因此没有理由在这方面更喜欢 GIF案子。

于 2013-12-03T04:18:08.283 回答
0

我遇到file_get_contents()过从 HTTP 请求截断数据的其他实例。我通过使用 CURL 解决了这个问题:

$url = "http://www.mapquestapi.com/traffic/v2/flow?key=**REMOVED**&mapLat=34.05396382838673&mapLng=-118.24529104634557&mapHeight=1000&mapWidth=1000&mapScale=433342";

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 300);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 8.0; Trident/4.0)');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$imgData = curl_exec($curl);
$http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE); // You may not need this
curl_close($curl);

有关更多信息或设置您自己的 CURL 选项,请参阅PHP 手册

于 2016-12-15T14:33:17.313 回答