Better way to get map of all pixels of an image with GD

前端 未结 2 1908
忘了有多久
忘了有多久 2021-02-15 14:53

The following code uses the SimpleImage library

I have a function that gets a pixel from an image:

function getPixel($x, $y) {

    $colors = imagecolors         


        
2条回答
  •  隐瞒了意图╮
    2021-02-15 15:43

    This is the ugly brute-force method, using imagecolorat() on every pixel. In my tests with large (6.5Mpixel) images, it's about 3.6sec, or about 1.1sec faster than the more elegant GD hack proposed by @cleong. It also has the advantage of brutal simplicity, and independence from the undocumented internal GD2 format.

    $alphaLookup = array(
        0x00000000=>"\xff",0x01000000=>"\xfd",0x02000000=>"\xfb",0x03000000=>"\xf9",
        0x04000000=>"\xf7",0x05000000=>"\xf5",0x06000000=>"\xf3",0x07000000=>"\xf1",
        0x08000000=>"\xef",0x09000000=>"\xed",0x0a000000=>"\xeb",0x0b000000=>"\xe9",
        0x0c000000=>"\xe7",0x0d000000=>"\xe5",0x0e000000=>"\xe3",0x0f000000=>"\xe1",
        0x10000000=>"\xdf",0x11000000=>"\xdd",0x12000000=>"\xdb",0x13000000=>"\xd9",
        0x14000000=>"\xd7",0x15000000=>"\xd5",0x16000000=>"\xd3",0x17000000=>"\xd1",
        0x18000000=>"\xcf",0x19000000=>"\xcd",0x1a000000=>"\xcb",0x1b000000=>"\xc9",
        0x1c000000=>"\xc7",0x1d000000=>"\xc5",0x1e000000=>"\xc3",0x1f000000=>"\xc1",
        0x20000000=>"\xbf",0x21000000=>"\xbd",0x22000000=>"\xbb",0x23000000=>"\xb9",
        0x24000000=>"\xb7",0x25000000=>"\xb5",0x26000000=>"\xb3",0x27000000=>"\xb1",
        0x28000000=>"\xaf",0x29000000=>"\xad",0x2a000000=>"\xab",0x2b000000=>"\xa9",
        0x2c000000=>"\xa7",0x2d000000=>"\xa5",0x2e000000=>"\xa3",0x2f000000=>"\xa1",
        0x30000000=>"\x9f",0x31000000=>"\x9d",0x32000000=>"\x9b",0x33000000=>"\x99",
        0x34000000=>"\x97",0x35000000=>"\x95",0x36000000=>"\x93",0x37000000=>"\x91",
        0x38000000=>"\x8f",0x39000000=>"\x8d",0x3a000000=>"\x8b",0x3b000000=>"\x89",
        0x3c000000=>"\x87",0x3d000000=>"\x85",0x3e000000=>"\x83",0x3f000000=>"\x81",
        0x40000000=>"\x7f",0x41000000=>"\x7d",0x42000000=>"\x7b",0x43000000=>"\x79",
        0x44000000=>"\x77",0x45000000=>"\x75",0x46000000=>"\x73",0x47000000=>"\x71",
        0x48000000=>"\x6f",0x49000000=>"\x6d",0x4a000000=>"\x6b",0x4b000000=>"\x69",
        0x4c000000=>"\x67",0x4d000000=>"\x65",0x4e000000=>"\x63",0x4f000000=>"\x61",
        0x50000000=>"\x5f",0x51000000=>"\x5d",0x52000000=>"\x5b",0x53000000=>"\x59",
        0x54000000=>"\x57",0x55000000=>"\x55",0x56000000=>"\x53",0x57000000=>"\x51",
        0x58000000=>"\x4f",0x59000000=>"\x4d",0x5a000000=>"\x4b",0x5b000000=>"\x49",
        0x5c000000=>"\x47",0x5d000000=>"\x45",0x5e000000=>"\x43",0x5f000000=>"\x41",
        0x60000000=>"\x3f",0x61000000=>"\x3d",0x62000000=>"\x3b",0x63000000=>"\x39",
        0x64000000=>"\x37",0x65000000=>"\x35",0x66000000=>"\x33",0x67000000=>"\x31",
        0x68000000=>"\x2f",0x69000000=>"\x2d",0x6a000000=>"\x2b",0x6b000000=>"\x29",
        0x6c000000=>"\x27",0x6d000000=>"\x25",0x6e000000=>"\x23",0x6f000000=>"\x21",
        0x70000000=>"\x1f",0x71000000=>"\x1d",0x72000000=>"\x1b",0x73000000=>"\x19",
        0x74000000=>"\x17",0x75000000=>"\x15",0x76000000=>"\x13",0x77000000=>"\x11",
        0x78000000=>"\x0f",0x79000000=>"\x0d",0x7a000000=>"\x0b",0x7b000000=>"\x09",
        0x7c000000=>"\x07",0x7d000000=>"\x05",0x7e000000=>"\x03",0x7f000000=>"\x00"
    ); // Lookup table for chr(255-(($x >> 23) & 0x7f)).
    
    
    $chr = array(
        "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F",
        "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F",
        "\x20","\x21","\x22","\x23","\x24","\x25","\x26","\x27","\x28","\x29","\x2A","\x2B","\x2C","\x2D","\x2E","\x2F",
        "\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3A","\x3B","\x3C","\x3D","\x3E","\x3F",
        "\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48","\x49","\x4A","\x4B","\x4C","\x4D","\x4E","\x4F",
        "\x50","\x51","\x52","\x53","\x54","\x55","\x56","\x57","\x58","\x59","\x5A","\x5B","\x5C","\x5D","\x5E","\x5F",
        "\x60","\x61","\x62","\x63","\x64","\x65","\x66","\x67","\x68","\x69","\x6A","\x6B","\x6C","\x6D","\x6E","\x6F",
        "\x70","\x71","\x72","\x73","\x74","\x75","\x76","\x77","\x78","\x79","\x7A","\x7B","\x7C","\x7D","\x7E","\x7F",
        "\x80","\x81","\x82","\x83","\x84","\x85","\x86","\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E","\x8F",
        "\x90","\x91","\x92","\x93","\x94","\x95","\x96","\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E","\x9F",
        "\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6","\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE","\xAF",
        "\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6","\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE","\xBF",
        "\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF",
        "\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF",
        "\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF",
        "\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF",
    ); // Lookup for chr($x): much faster.
    
    
    
    function lookUpImageBytes($canvas) {
        global $alphaLookup, $chr;
        $imageWidth = imagesx($canvas);
        $imageHeight = imagesy($canvas);
        // Faster than append, and >500mb more memory efficient for a 6.5MPx image!
        $imageData = str_repeat("\x00\x00\x00\x00", $imageWidth * $imageHeight);
    
        // Loop over each single pixel.
        $j = 0;
        for ($y = 0; $y < $imageHeight; $y++) {
            for ($x = 0; $x < $imageWidth; $x++) {
                // Grab the pixel data.
                $argb = imagecolorat($canvas, $x, $y);
                $imageData[$j++] = $alphaLookup[$argb & 0x7f000000]; // A (convert from GD).
                // NB: three $chr arrays to replace the shifts WON'T improve speed.
                $imageData[$j++] = $chr[($argb >> 16) & 0xFF]; // R
                $imageData[$j++] = $chr[($argb >> 8) & 0xFF]; // G
                $imageData[$j++] = $chr[$argb & 0xFF]; // B
            }
        }
        return $imageData;
    }
    

提交回复
热议问题