【问题标题】:How can I check if a jpeg will fit in memory?如何检查 jpeg 是否适合内存?
【发布时间】:2017-10-17 20:13:45
【问题描述】:

使用imagecreatefromjpeg 打开 JPEG 图像很容易导致致命错误,因为所需的内存超过了memory_limit

小于 100Kb 的.jpg 文件很容易超过 2000x2000 像素 - 打开时将占用大约 20-25MB 的内存。 “相同”的 2000x2000 像素图像使用不同的压缩级别可能会占用 5MB 磁盘空间。

所以我显然不能使用文件大小来确定它是否可以安全打开。

在打开文件之前如何确定文件是否适合内存,从而避免致命错误?

【问题讨论】:

  • 注意:问答部分是为了回答这个问题:stackoverflow.com/questions/46797422/… 被(正确)标记为重复 - 它确实提出了这个我在 SO 上找不到答案的有趣问题。
  • 非常好的问答

标签: php image gd fatal-error


【解决方案1】:

根据几个来源,所需的内存最多为每个像素 5 个字节,具体取决于几个不同的因素,例如位深度。我自己的测试证实这大致正确。

除此之外,还需要考虑一些开销。

但通过检查图像尺寸(无需加载图像即可轻松完成),我们可以粗略估计所需内存并将其与(估计)可用内存进行比较,如下所示:

$filename = 'black.jpg';

//Get image dimensions
$info = getimagesize($filename);

//Each pixel needs 5 bytes, and there will obviously be some overhead - In a
//real implementation I'd probably reserve at least 10B/px just in case.
$mem_needed = $info[0] * $info[1] * 6;

//Find out (roughly!) how much is available
// - this can easily be refined, but that's not really the point here
$mem_total = intval(str_replace(array('G', 'M', 'K'), array('000000000', '000000', '000'), ini_get('memory_limit')));

//Find current usage - AFAIK this is _not_ directly related to
//the memory_limit... but it's the best we have!
$mem_available = $mem_total - memory_get_usage();

if ($mem_needed > $mem_available) {
    die('That image is too large!');
}

//Do your thing
$img = imagecreatefromjpeg('black.jpg');

这只是表面测试,所以我建议进一步测试很多不同的图像,并使用这些函数来检查计算在您的特定环境中是否相当正确:

//Set some low limit to make sure you will run out
ini_set('memory_limit', '10M');

//Use this to check the peak memory at different points during execution
$mem_1 = memory_get_peak_usage(true);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2013-05-30
    • 2023-03-28
    相关资源
    最近更新 更多