php php中的超快速getimagesize

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4635936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 13:46:59  来源:igfitidea点击:

Super fast getimagesize in php

phpimagehttpgetimagesize

提问by Sir Lojik

I am trying to get image size (image dimensions, width and height) of hundreds of remote images and getimagesizeis way too slow.

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

I have done some reading and found out the quickest way would be to use file_get_contentsto read a certain amount of bytes from the images and examining the size within the binary data.

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

Anyone attempted this before? How would I examine different formats? Anyone has seen any library for this?

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

回答by Dejan Marjanovic

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)";

test...

测试...

640 x 480 (0.20859s)

640 x 480 (0.20859s)

Loading 32kb of data worked for me.

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

回答by Tom

I have created a PHP library for exactly this scenario, it works by downloading the absolute minimum of the remote file needed to determine the filesize. This is different for every imageand particularly for JPEG depends on how many embedded thumbnails there are in the file.

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

It is available on GitHub here: https://github.com/tommoor/fastimage

它可以在 GitHub 上找到:https: //github.com/tommoor/fastimage

Example usage:

用法示例:

$image = new FastImage($uri);
list($width, $height) = $image->getSize();
echo "dimensions: " . $width . "x" . $height;

回答by Exit

I was looking for a better way to handle this situation, so I used a few different functions found around the internet.

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

Overall, when it worked, the fastest tended to be the getjpegsizefunction that James Relyea posted on the PHP page for getimagesize, beating the rangerfunction provided by Dejan above. http://php.net/manual/en/function.getimagesize.php#88793

总的来说,当它工作时,最快的往往是getjpegsizeJames Relyea 在 PHP 页面上发布getimagesizeranger函数,击败了上面 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]
  • rangerfailed when grabbing 32768 bytes on Image #3, so I increase it to 65536 and it worked to grab the size successfully.
  • ranger在 Image #3 上抓取 32768 字节时失败,所以我将它增加到 65536 并且它成功抓取了大小。

There are problems, though, as both rangerand getjpegsizeare limited in ways that make it not stable enough to use. Both failed when dealing with a large JPG image around 3MB, but rangerwill work after changing the amount of bytes it grabs. Also, these alternates only deal with JPG images, which means that a conditional would need to be used to only use them on JPGs and getimagesizeon the other image formats.

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

Also, note that the first image was on an older server running an old version of PHP 5.3.2, where as the 4 other images came from a modern server (cloud based cPanel with MultiPHP dialed back to 5.4.45 for compatibility).

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

It's worth noting that the cloud based server did far better with getimagesizewhich beat out ranger, in fact for all 4 tests on the cloud server, rangerwas the slowest. Those 4 also were pulling the images from the same server as the code was running, though different accounts.

值得一提的是,基于云的服务器做了更好的使用getimagesize它打败了ranger,其实在云服务器上的所有4个试验,ranger是最慢的。尽管帐户不同,但那 4 个也从运行代码的同一台服务器中提取图像。

This makes me wonder if the PHP core improved in 5.4 or if the Apache version factors in. Also, it might be down to availability from the server and server load. Let's not forget how networks are getting faster and faster each year, so maybe the speed issue is becoming less of a concern.

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

So, the end result and my answer is that for complete support for all web image formats, and to still achieve super fast image size, it might be best to suck it up and use getimagesizeand then cache the image sizes (if these images will be checked more than once) in a database table. In that scenario, only the first check will incur a larger cost, but subsequent requests would be minimal and faster than any function that reads the image headers.

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

As with any caching, it only works well if the content doesn't change and there is a way to check if has been a change. So, a possible solution is to check only the headers of a image URL when checking the cache, and if different, dump the cached version and grab it again with getimagesize.

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