Обычно простые эффекты, подобные этому, реализуются с использованием ядра свертки, где изображение преобразуется из его источника в новую копию. Каждый новый пиксель вычисляется как линейная комбинация (, т.е. взвешенная сумма) его исходного пикселя и подмножества его соседей в исходном изображении.
Например, вы можете (абстрактно) определить ядро, например:
0 0 0
0 9 -3
0 -3 -3
Здесь центр матрицы представляет взвешивание, примененное к соответствующему исходному пикселю для каждого нового значения пикселя, которое должно быть вычислено. Окружающие значения представляют весовые коэффициенты, которые должны быть применены к соответствующим соседним пикселям перед суммированием для вычисления общего значения нового пикселя.
На практике это может быть применено для создания нового рельефного изображения со следующим псевдокодом:
for y in source.height:
for x in source.width:
newImage[x,y] = source[x,y]*9
+ source[x+1,y]*-3
+ source[x,y+1]*-3
+ source[x+1,y+1]*-3
Существуют очевидные детали реализации, такие как обработка края изображения (один из вариантов - предположить, что изображение зеркально отражено вокруг его краев), а также фактическое применение произвольной матрицы коэффициентов, а не жесткой кодирование взвешенной суммы, как указано выше. Надеюсь, это, по крайней мере, говорит о том, насколько проста операция в своей основе.