Skip to content

imagebmp is extremely slow on Windows #23457

Closed

Description

@divinity76

Description

imagebmp is extremely slow on Windows.

(PS, there is also a performance issue with imagegrabscreen(), it is much slower than equivalent Python-mss code: #23459 )

The following code:

<?php

$t = microtime(true);
$h = imagegrabscreen();
$grab = microtime(true) - $t;

echo 'Grab: ' . sprintf('%.9f', $grab) . " s\n";

$t = microtime(true);
$r = imagebmp($h, 'bmp0.bmp', false);
$dt = microtime(true) - $t;
echo 'BMP no compression: ' . sprintf('%.9f', $dt) . ' s (result: ' . var_export($r, true) . ')' . "\n";

$t = microtime(true);
$r = imagebmp($h, 'bmp1.bmp', true);
$dt = microtime(true) - $t;
echo 'BMP compressed: ' . sprintf('%.9f', $dt) . ' s (result: ' . var_export($r, true) . ')' . "\n";

$t = microtime(true);
$r = imagepng($h, 'png0.png', 0);
$dt = microtime(true) - $t;
echo 'PNG no compression: ' . sprintf('%.9f', $dt) . ' s (result: ' . var_export($r, true) . ')' . "\n";

$t = microtime(true);
$r = imagepng($h, 'pngd.png', -1);
$dt = microtime(true) - $t;
echo 'PNG default compression: ' . sprintf('%.9f', $dt) . ' s (result: ' . var_export($r, true) . ')' . "\n";

imagedestroy($h);

Resulted in this output:

PS C:\Users\hansh> php test.php
Grab: 7.558355093 s
BMP no compression: 48.639475107 s (result: true)
BMP compressed: 52.303011179 s (result: true)
PNG no compression: 0.094882011 s (result: true)
PNG default compression: 0.109680176 s (result: true)
PHP Deprecated:  Function imagedestroy() is deprecated since 8.5, as it has no effect since PHP 8.0 in C:\Users\hansh\test.php on line 29

Deprecated: Function imagedestroy() is deprecated since 8.5, as it has no effect since PHP 8.0 in C:\Users\hansh\test.php on line 29

But I expected this output instead:

BMP no compression: 0.019475107 s (result: true)
BMP compressed: 0.013011179 s (result: true)
  • png executed in 0.01 seconds, BMP needs 40 seconds.

PHP Version

Observed both windows 11 with
PHP 8.5.1 (cli) (built: Dec 17 2025 10:55:54) (ZTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.5.1, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.1, Copyright (c), by Zend Technologies

and Windows Server 2025 with
PHP 8.2.12 (cli) (built: Oct 24 2023 21:15:15) (ZTS Visual C++ 2019 x64)
Copyright (c) The PHP Group
Zend Engine v4.2.12, Copyright (c) Zend Technologies

Operating System

Observed on both Windows Server 2025, and Windows 11, both x86-64

Activity

  1. divinity76 commented on Aug 25, 2026

    @divinity76
    ContributorAuthor

    For comparsion, Python-mss +PIL does everything combined in <1s:

    PS C:\Users\hansh> python3 test.py
    Grab: 0.265929600 s
    BMP no compression: 0.069192300 s (result: True)
    BMP compressed (PIL ignores this): 0.022632100 s (result: True)
    PNG no compression: 0.105889400 s (result: True)
    PNG default compression: 0.093167300 s (result: True)
    
    import time
    import mss
    from PIL import Image
    
    # 1. Grab Screen
    t = time.perf_counter()
    with mss.MSS() as sct:  
        # monitors[1] is the primary monitor (monitors[0] is all monitors combined)
        monitor = sct.monitors[1] 
        sct_img = sct.grab(monitor)
        
        # Convert raw MSS pixels (BGRA) to a PIL Image (RGB)
        img = Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")
        
    grab_time = time.perf_counter() - t
    print(f"Grab: {grab_time:.9f} s")
    
    # 2. BMP no compression
    t = time.perf_counter()
    try:
        img.save('bmp0.bmp', format='BMP')
        r = True
    except Exception:
        r = False
    dt = time.perf_counter() - t
    print(f"BMP no compression: {dt:.9f} s (result: {r})")
    
    # 3. BMP compressed (PIL does not support writing compressed BMPs)
    t = time.perf_counter()
    try:
        img.save('bmp1.bmp', format='BMP')
        r = True
    except Exception:
        r = False
    dt = time.perf_counter() - t
    print(f"BMP compressed (PIL ignores this): {dt:.9f} s (result: {r})")
    
    # 4. PNG no compression (compress_level=0)
    t = time.perf_counter()
    try:
        img.save('png0.png', format='PNG', compress_level=0)
        r = True
    except Exception:
        r = False
    dt = time.perf_counter() - t
    print(f"PNG no compression: {dt:.9f} s (result: {r})")
    
    # 5. PNG default compression
    t = time.perf_counter()
    try:
        img.save('pngd.png', format='PNG') 
        r = True
    except Exception:
        r = False
    dt = time.perf_counter() - t
    print(f"PNG default compression: {dt:.9f} s (result: {r})")
  2. added 3 commits that reference this issue on Aug 26, 2026
    d777841
    5c0e8c7
    a2a2029
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions