Перетворити кольорове зображення в чорно-біле (відтінки сірого) можна дуже швидко, витративши 3 такту CPU на піксель.
У типі TColor червоний колір зберігається в молодшому байті, далі зелений, за ним синій. Вони можуть бути вилучені за допомогою наступних операторів:
Добре відома формула для обчислення яскравості кольорового зображення по інтенсивності колірних складових:
або в целочисленной арифметиці:
Нове значення кольору пікселя в градаціях сірого виходить за допомогою завдання однакової інтенсивності всіх колірних складових:
Здавалося б, все просто. Але якщо запрограмувати алгоритм в лоб, то виявиться, що перетворення зображення розміром 800x600 з дозволом 32bpp займає більше секунди:
Спробуємо прискорити обчислення нового кольору пікселя. Звернемо увагу на те, що фактично обчислення яскравості пікселя в процедурі Grayscale1 проводиться в байті з номером 1, який потім зсувається в молодший байт (байт номер 0). Все це вимагає попереднього переміщення значень колірних складових в молодший байт. Якщо ж обчислення яскравості виконувати в старшому байті (байт номер 3), то можна обійтися без попереднього зсуву:
Зауважимо також, що множення синьою і червоною складових можна поєднати. При цьому в двох молодших байтах буде додатково обчислено твір Blue * 77, яке не матиме впливу на результат через подальше зрушення:
Крім того, можна обійтися без виділення зеленої складової, і помножити на відповідний їй ваговий коефіцієнт всі кольори, а червону і зелену складові потім помножити на менший коефіцієнт:
І, нарешті, логічне множення на константу $ 00FFFFFF зайве, тому що при множенні старшого байта Color на (150 * 256) все одно буде отримано нуль. Після чергового спрощення отримуємо:
В результаті процедура перетворення стала в півтора-два рази швидше. Повністю вона тепер виглядає наступним чином:
Якщо розгорнути цикл, то можна отримати прискорення ще приблизно в 1.25 рази:
Нижче результати експериментів зведені в таблицю. Для вимірі продуктивності використовувався фоновий малюнок 'Безмятежность.bmp' розміром 800x600 з Windows XP. Всі процедури, за винятком першої, викликалися в циклі 4000 разів.
Швидкість роботи початкової реалізації перевищена в 3000-4000 разів. При цьому процесорам E6850 і i5-2300 треба було всього 3 такту на обробку одного пікселя.