Искажение изображения с синусом / косинусом - PullRequest
0 голосов
/ 24 августа 2010

Можно ли исказить изображение с помощью тригонометрических функций, таких как синус и косинус , чтобы оно получалось волнистым.

Если так, то как.

PHP является предпочтительным языком , но может быть любым ...

Ответы [ 3 ]

3 голосов
/ 24 августа 2010

Да, это возможно.Изображение - это просто двумерный массив пикселей, и их можно свободно реорганизовать.Одним простым способом является создание нового изображения и выборки пикселей из исходного изображения с помощью некоторой функции искажения.

$original = read_image_pixels(); // using GD or some other way
for ($x = 0; $x < $width; $x++) {
  for ($y = 0; $y < $height; $y++) {
    // we are adding $height and taking modulo
    // to insure that $distorted_y is positive and less then $height.
    $distorted_y = ($y + round(10*sin($x/20)) + $height) % $height;

    $distorted[$x][$y] = $original[$x][$distorted_y];
  }
}

Редактировать: это можно обобщить еще дальше.Многие знакомые эффекты, такие как размытие и нерезкость, являются фильтрами свертки.Они довольно хорошо объяснены в статье GameDev .Мы можем рассматривать вышеупомянутое sin-искажение как фильтр свертки с пространственно-переменным ядром (матрица коэффициентов).

3 голосов
/ 24 августа 2010

Используя ответ Фадежа, я получил решение ...

Картинка такая ...

alt text

Код -

<?php
    header("Content-type: image/png");
    $im = imagecreatefrompng('pic.png');
    $newim = imagecreatetruecolor(imagesx($im),imagesy($im));
    for ($x = 0; $x < imagesx($im); $x++) {
        for ($y = 0; $y < imagesy($im); $y++) {

        $rgba = imagecolorsforindex($im, imagecolorat($im, $x, $y));
        $col = imagecolorallocate($newim, $rgba["red"], $rgba["green"], $rgba["blue"]);


        $distorted_y = ($y + round(100*sin($x/50)) + imagesy($im)) % imagesy($im);
        imagesetpixel($newim, $x, $distorted_y, $col);
        }
    }

    imagepng($newim);
    ?>

Выход

alt text

2 голосов
/ 24 августа 2010

Многое зависит от того, как работает ваше изображение. Я не говорю на PHP, так что это общее решение.

Если мы можем переместить отдельные пиксели, концептуально самый простой способ сделать это будет сказать

y old = старая y-позиция пикселя
y new = новая y-позиция пикселя
х = х-позиция пикселя
L = длина изображения в пикселях
N = количество применяемых тригонометрических циклов (т. Е. Число синусоидальных волн)

Тогда мы просто перебираем изображение. Для каждого значения x мы перемещаем пиксель y:

y new = y old * (1 + sin (N π x / L)) / 2

...