41

我正在尝试获取数百个远程图像的图像大小(图像尺寸、宽度和高度),但getimagesize速度太慢了。

我做了一些阅读,发现最快的方法是使用file_get_contents从图像中读取一定数量的字节并检查二进制数据中的大小。

以前有人尝试过吗?我将如何检查不同的格式?有人看过任何图书馆吗?

4

3 回答 3

95
function ranger($url){
    $headers = array(
    "Range: bytes=0-32768"
    );

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($curl);
    curl_close($curl);
    return $data;
}

$start = microtime(true);

$url = "http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg";

$raw = ranger($url);
$im = imagecreatefromstring($raw);

$width = imagesx($im);
$height = imagesy($im);

$stop = round(microtime(true) - $start, 5);

echo $width." x ".$height." ({$stop}s)";

测试...

640 x 480 (0.20859s)

加载 32kb 的数据对我有用。

于 2011-01-08T20:34:06.170 回答
27

我已经为这种情况创建了一个 PHP 库,它通过下载确定文件大小所需的远程文件的绝对最小值来工作。这对于每个图像都是不同的,特别是对于 JPEG,取决于文件中有多少嵌入的缩略图。

它在 GitHub 上可用:https ://github.com/tommoor/fastimage

示例用法:

$image = new FastImage($uri);
list($width, $height) = $image->getSize();
echo "dimensions: " . $width . "x" . $height;
于 2012-09-26T12:10:00.650 回答
8

我一直在寻找一种更好的方法来处理这种情况,所以我使用了一些在互联网上找到的不同功能。

总的来说,当它工作时,最快的往往是getjpegsizeJames Relyea 在 PHP 页面上发布的函数getimagesize,击败了ranger上面 Dejan 提供的函数。 http://php.net/manual/en/function.getimagesize.php#88793

Image #1 (787KB JPG on external older server)
getimagesize: 0.47042 to 0.47627 - 1700x2340 [SLOWEST]
getjpegsize: 0.11988 to 0.14854 - 1700x2340 [FASTEST]
ranger: 0.1917 to 0.22869 - 1700x2340

Image #2 (3MB PNG)
getimagesize: 0.01436 to 0.01451 - 1508x1780 [FASTEST]
getjpegsize: - failed
ranger: - failed

Image #3 (2.7MB JPG)
getimagesize: 0.00855 to 0.04806 - 3264x2448 [FASTEST]
getjpegsize: - failed
ranger: 0.06222 to 0.06297 - 3264x2448 * [SLOWEST]

Image #4 (1MB JPG)
getimagesize: 0.00245 to 0.00261 - 2031x1434
getjpegsize: 0.00135 to 0.00142 - 2031x1434 [FASTEST]
ranger: 0.0168 to 0.01702 - 2031x1434 [SLOWEST]

Image #5 (316KB JPG)
getimagesize: 0.00152 to 0.00162 - 1280x720
getjpegsize: 0.00092 to 0.00106 - 1280x720 [FASTEST]
ranger: 0.00651 to 0.00674 - 1280x720 [SLOWEST]
  • ranger在图像#3 上抓取 32768 字节时失败,所以我将其增加到 65536,它成功地抓取了大小。

但是,两者都存在问题,ranger并且getjpegsize在使其不够稳定而无法使用的方式上受到限制。在处理大约 3MB 的大型 JPG 图像时,两者都失败了,但ranger在更改它抓取的字节数后会起作用。此外,这些替代只处理 JPG 图像,这意味着需要使用条件来仅在 JPG 和getimagesize其他图像格式上使用它们。

另外,请注意,第一个图像位于运行旧版本 PHP 5.3.2 的旧服务器上,而其他 4 个图像来自现代服务器(具有 MultiPHP 的基于云的 cPanel 拨回 5.4.45 以实现兼容性)。

值得注意的是,基于云的服务器的表现要好得多getimagesizeranger事实上,对于云服务器上的所有 4 次测试,ranger它是最慢的。这 4 个人也在代码运行时从同一台服务器中提取图像,尽管帐户不同。

这让我想知道 PHP 核心是否在 5.4 中有所改进,或者 Apache 版本是否有所改进。此外,这可能取决于服务器和服务器负载的可用性。让我们不要忘记网络每年都变得越来越快,所以速度问题可能变得不那么令人担忧了。

所以,最终结果和我的回答是,为了完全支持所有网络图像格式,并且仍然获得超快的图像大小,最好将其吸收并使用getimagesize然后缓存图像大小(如果这些图像将检查了不止一次)在数据库表中。在这种情况下,只有第一次检查会产生更大的成本,但随后的请求将比读取图像标题的任何函数最小且更快。

与任何缓存一样,它只有在内容没有变化并且有办法检查是否发生变化时才能正常工作。因此,一种可能的解决方案是在检查缓存时仅检查图像 URL 的标头,如果不同,则转储缓存版本并使用getimagesize.

于 2017-03-09T23:12:22.687 回答