php 中超快的 getimagesize

发布于 2024-10-11 08:26:31 字数 327 浏览 0 评论 0原文

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

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

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沙沙粒小 2024-10-18 08:26:31
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 数据对我来说很有效。

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)

Loading 32kb of data worked for me.

沦落红尘 2024-10-18 08:26:31

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

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

示例用法:

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

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 image and particularly for JPEG depends on how many embedded thumbnails there are in the file.

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

Example usage:

$image = new FastImage($uri);
list($width, $height) = $image->getSize();
echo "dimensions: " . $width . "x" . $height;
只涨不跌 2024-10-18 08:26:31

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

总的来说,当它起作用时,最快的往往是 James Relyea 在 getimagesize PHP 页面上发布的 getjpegsize 函数,击败了 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 并且成功抓取了大小。

但也存在一些问题,因为 rangergetjpegsize 都受到限制,导致其使用不够稳定。在处理大约 3MB 的大型 JPG 图像时,两者都失败了,但是 ranger 在更改它抓取的字节数后可以工作。此外,这些替代方案仅处理 JPG 图像,这意味着需要使用条件来仅在 JPG 上使用它们,而在其他图像格式上使用 getimagesize

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

值得注意的是,基于云的服务器在 getimagesize 方面表现得更好,击败了 ranger,事实上,对于云服务器 ranger 上的所有 4 项测试而言> 是最慢的。这 4 个人还在代码运行时从同一台服务器提取图像,尽管帐户不同。

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

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

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

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 getjpegsize function that James Relyea posted on the PHP page for getimagesize, beating the ranger function provided by Dejan above.
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 failed when grabbing 32768 bytes on Image #3, so I increase it to 65536 and it worked to grab the size successfully.

There are problems, though, as both ranger and getjpegsize are limited in ways that make it not stable enough to use. Both failed when dealing with a large JPG image around 3MB, but ranger will 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 getimagesize on the other image formats.

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).

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

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.

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 getimagesize and 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文