Я спрашивал, чтобы понять - насколько подробно нужно объяснять.
Документация по PIL, кстати, откровенно хреновая - поэтому и рекомендую читать исходники. Они подробные и не врут.
Полностью описывать все не буду - очень длинно выйдет. Если будут вопросы - задавайте.
PIL.Image хранит картинку в raw формате (развернутом). Всякие TIFF и JPEG перекодируются в raw и обратно при чтении-записи изображения.
Поэтому остановимся именно на raw.
Сначала приведу полную таблицу поддерживаемых режимов, а потом расскажу как ее читать.
/* raw mode syntax is "<mode>;<bits><flags>" where "bits" defaults
depending on mode (1 for "1", 8 for "P" and "L", etc), and
"flags" should be given in alphabetical order. if both bits
and flags have their default values, the ; should be left out */
/* flags: "I" inverted data; "R" reversed bit order; "B" big
endian byte order (default is little endian); "L" line
interleave, "S" signed, "F" floating point */
/* bilevel */
{"1", "1", 1, unpack1},
{"1", "1;I", 1, unpack1I},
{"1", "1;R", 1, unpack1R},
{"1", "1;IR", 1, unpack1IR},
/* greyscale */
{"L", "L;2", 2, unpackL2},
{"L", "L;4", 4, unpackL4},
{"L", "L", 8, copy1},
{"L", "L;I", 8, unpackLI},
{"L", "L;R", 8, unpackLR},
{"L", "L;16", 16, unpackL16},
{"L", "L;16B", 16, unpackL16B},
/* greyscale w. alpha */
{"LA", "LA", 16, unpackLA},
{"LA", "LA;L", 16, unpackLAL},
/* palette */
{"P", "P;1", 1, unpackP1},
{"P", "P;2", 2, unpackP2},
{"P", "P;2L", 2, unpackP2L},
{"P", "P;4", 4, unpackP4},
{"P", "P;4L", 4, unpackP4L},
{"P", "P", 8, copy1},
{"P", "P;R", 8, unpackLR},
/* palette w. alpha */
{"PA", "PA", 16, unpackLA},
{"PA", "PA;L", 16, unpackLAL},
/* true colour */
{"RGB", "RGB", 24, ImagingUnpackRGB},
{"RGB", "RGB;L", 24, unpackRGBL},
{"RGB", "RGB;R", 24, unpackRGBR},
{"RGB", "RGB;16B", 48, unpackRGB16B},
{"RGB", "BGR", 24, ImagingUnpackBGR},
{"RGB", "BGR;15", 16, ImagingUnpackBGR15},
{"RGB", "BGR;16", 16, ImagingUnpackBGR16},
{"RGB", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */
{"RGB", "RGBX", 32, copy4},
{"RGB", "RGBX;L", 32, unpackRGBAL},
{"RGB", "BGRX", 32, ImagingUnpackBGRX},
{"RGB", "XRGB", 24, ImagingUnpackXRGB},
{"RGB", "XBGR", 32, ImagingUnpackXBGR},
{"RGB", "YCC;P", 24, ImagingUnpackYCC},
{"RGB", "R", 8, band0},
{"RGB", "G", 8, band1},
{"RGB", "B", 8, band2},
/* true colour w. alpha */
{"RGBA", "LA", 16, unpackRGBALA},
{"RGBA", "LA;16B", 32, unpackRGBALA16B},
{"RGBA", "RGBA", 32, copy4},
{"RGBA", "RGBa", 32, unpackRGBa},
{"RGBA", "RGBA;I", 32, unpackRGBAI},
{"RGBA", "RGBA;L", 32, unpackRGBAL},
{"RGBA", "RGBA;16B", 64, unpackRGBA16B},
{"RGBA", "BGRA", 32, unpackBGRA},
{"RGBA", "ARGB", 32, unpackARGB},
{"RGBA", "ABGR", 32, unpackABGR},
{"RGBA", "YCCA;P", 32, ImagingUnpackYCCA},
{"RGBA", "R", 8, band0},
{"RGBA", "G", 8, band1},
{"RGBA", "B", 8, band2},
{"RGBA", "A", 8, band3},
/* true colour w. padding */
{"RGBX", "RGB", 24, ImagingUnpackRGB},
{"RGBX", "RGB;L", 24, unpackRGBL},
{"RGBX", "RGB;16B", 48, unpackRGB16B},
{"RGBX", "BGR", 24, ImagingUnpackBGR},
{"RGBX", "BGR;15", 16, ImagingUnpackBGR15},
{"RGB", "BGR;16", 16, ImagingUnpackBGR16},
{"RGBX", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */
{"RGBX", "RGBX", 32, copy4},
{"RGBX", "RGBX;L", 32, unpackRGBAL},
{"RGBX", "BGRX", 32, ImagingUnpackBGRX},
{"RGBX", "XRGB", 24, ImagingUnpackXRGB},
{"RGBX", "XBGR", 32, ImagingUnpackXBGR},
{"RGBX", "YCC;P", 24, ImagingUnpackYCC},
{"RGBX", "R", 8, band0},
{"RGBX", "G", 8, band1},
{"RGBX", "B", 8, band2},
{"RGBX", "X", 8, band3},
/* colour separation */
{"CMYK", "CMYK", 32, copy4},
{"CMYK", "CMYK;I", 32, unpackCMYKI},
{"CMYK", "CMYK;L", 32, unpackRGBAL},
{"CMYK", "C", 8, band0},
{"CMYK", "M", 8, band1},
{"CMYK", "Y", 8, band2},
{"CMYK", "K", 8, band3},
{"CMYK", "C;I", 8, band0I},
{"CMYK", "M;I", 8, band1I},
{"CMYK", "Y;I", 8, band2I},
{"CMYK", "K;I", 8, band3I},
/* video (YCbCr) */
{"YCbCr", "YCbCr", 24, ImagingUnpackRGB},
{"YCbCr", "YCbCr;L", 24, unpackRGBL},
{"YCbCr", "YCbCrX", 32, copy4},
{"YCbCr", "YCbCrK", 32, copy4},
/* integer variations */
{"I", "I", 32, copy4},
{"I", "I;8", 8, unpackI8},
{"I", "I;8S", 8, unpackI8S},
{"I", "I;16", 16, unpackI16},
{"I", "I;16S", 16, unpackI16S},
{"I", "I;16B", 16, unpackI16B},
{"I", "I;16BS", 16, unpackI16BS},
{"I", "I;16N", 16, unpackI16N},
{"I", "I;16NS", 16, unpackI16NS},
{"I", "I;32", 32, unpackI32},
{"I", "I;32S", 32, unpackI32S},
{"I", "I;32B", 32, unpackI32B},
{"I", "I;32BS", 32, unpackI32BS},
{"I", "I;32N", 32, unpackI32N},
{"I", "I;32NS", 32, unpackI32NS},
/* floating point variations */
{"F", "F", 32, copy4},
{"F", "F;8", 8, unpackF8},
{"F", "F;8S", 8, unpackF8S},
{"F", "F;16", 16, unpackF16},
{"F", "F;16S", 16, unpackF16S},
{"F", "F;16B", 16, unpackF16B},
{"F", "F;16BS", 16, unpackF16BS},
{"F", "F;16N", 16, unpackF16N},
{"F", "F;16NS", 16, unpackF16NS},
{"F", "F;32", 32, unpackF32},
{"F", "F;32S", 32, unpackF32S},
{"F", "F;32B", 32, unpackF32B},
{"F", "F;32BS", 32, unpackF32BS},
{"F", "F;32N", 32, unpackF32N},
{"F", "F;32NS", 32, unpackF32NS},
{"F", "F;32F", 32, unpackF32F},
{"F", "F;32BF", 32, unpackF32BF},
{"F", "F;32NF", 32, unpackF32NF},
#ifdef FLOAT64
{"F", "F;64F", 64, unpackF64F},
{"F", "F;64BF", 64, unpackF64BF},
{"F", "F;64NF", 64, unpackF64NF},
#endif
/* storage modes */
{"I;16", "I;16", 16, copy2},
{"I;16B", "I;16B", 16, copy2},
{"I;16L", "I;16L", 16, copy2},
{NULL} /* sentinel */
};
Первая колонка - логический режим.
Сколько заглавных букв/цифр - столько каналов.
Например, в RGBA - четыре канала. Красный, зеленый, синий и прозрачность.
RGB - то же но без прозрачности.
F - картинка всего в один канал, зато он float. Т.е. можно писать числа в очень широком диапазоне.
Например, с пересветом (больше единицы - все равно белый, зато при дальнейшей обработке может стать важным, насколько таки - белый, или слегка серенький все же).
Третья колонка - сколько бит занимает пиксель.
Четвертая - функция кодирования, сейчас она не важна.
Вторая колонка - raw mode.
Описывает физический порядок записи в памяти.
В начале таблицы есть комментарий, разъясняющий принцип кодирования.
Дело в том, что RGB можно записать по разному.
Например, именно как RGB - по байту на красный, зеленый и синий.
Или как BGR - тоже популярная кодировка, красный и синий в памяти переставлены местами.
Или RGBX - последний байт может быть мусором или альфой, но нам он не интересен, игнорируем.
Или даже как RGB;16B - довольно популярный формат, некоторые сканеры умеют давать такую картинку.
По два байта на канал, при этом они в big endian - биты зеркально переставлены. Цвет задается в разы точнее - сами понимаете.
Теперь возвращаемся к вашим баранам.
ImageGrab.grab() - делает скриншот. Для скорости стоит вызывать его только раз - затратная операция каждый раз делать копию экрана ;)
Кстати, у этой картинки mode будет RGB (зачем для скриншота альфа?), а raw mode - BGR (так уж в bmp принято).
Вам raw mode в данном случае не интересен - ведь есть нормальный Image и все тут.
Правда, существует ньюанс - пока raw mode у исходной и результирующей картинки один и тот же - затратные преобразования битов делать не нужно, все просто летает.
возвращаемый буфер - это именно битовое представление о картинке. Без информации о том, как именно ее следует читать - просто серия байт.
Чтобы затянуть эту мешанину обратно через .fromstring(), нужно правильно указать ее raw mode - иначе все перепутается, синий станет красным и т.д. даже если общие размеры совпадут.
Уффф. Устал. Надеюсь, длинная писанина хоть немного расставила все по местам.