Предполагая, что вы на самом деле работаете с растровыми изображениями, вам, вероятно, будет проще просто позволить библиотеке сделать это за вас.
Класс System.Drawing.Graphics
имеет свойство CompositingMode
, которое можно установить либо на SourceCopy
(по умолчанию - перезаписывает цвет фона), либо на SourceOver
(смешивается с цветом фона).
Подробнее см. MSDN: как использовать режим наложения для управления альфа-смешиванием .
Если вам нужна только математика, альфа-смешивание довольно простое. Для альфа-значения a между 0,0 и 1,0 результат должен быть:
(aOld * oldValue) + ((1 - aOld) * aNew * newValue)
Где oldValue
- предыдущее значение перед наложением, newValue
- то, с чем вы хотите наложить, а aOld
и aNew
- старое и новое альфа-значения соответственно. Очевидно, что вам нужно выполнить этот расчет для значений R, G и B. отдельно.
См. Также: Альфа-композитинг (вики-ссылка) для более подробного объяснения.
Обновление: я думаю, что должно быть легко понять, как адаптировать это к коду в OP, но я думаю, что не все математики.
Я собираюсь предположить, что byte[]
является повторяющейся последовательностью значений A, R, G, B (поэтому Length
будет кратным 4). Если это не так, вам придется адаптировать этот код к любому формату хранения, который вы используете.
bytes[] result = new bytes[first.Length];
for(i = 0; i < first.Length; i += 4)
{
byte a1 = first[i];
byte a2 = second[i];
byte r1 = first[i+1];
byte r2 = second[i+1];
byte g1 = first[i+2];
byte g2 = second[i+2];
byte b1 = first[i+3];
byte b2 = second[i+3];
byte a = a1 + (255 - a1) * a2 / 255;
byte r = r1 * a1 / 255 + r2 * (255 - a1) * a2 / 65025;
byte g = g1 * a1 / 255 + g2 * (255 - a1) * a2 / 65025;
byte b = b1 * a1 / 255 + b2 * (255 - a1) * a2 / 65025;
result[i] = a;
result[i+1] = r;
result[i+2] = g;
result[i+3] = b;
}