开发者

Image distortion with sine/cosine

开发者 https://www.devze.com 2023-01-13 06:34 出处:网络
Is it possible to distort an image us开发者_JAVA百科ing trigonometric functions like sine and cosine so that it comes out wavy.

Is it possible to distort an image us开发者_JAVA百科ing trigonometric functions like sine and cosine so that it comes out wavy.

If so, how.

PHP is the preferred language but it can be any...


Yes it's possible. An image is just a two dimensional array of pixels and it's possible to reorganize them freely. One easy way is to create new image and sample pixels from original image thru some distortion function.

$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];
  }
}

Edit: This can be generalized even further. Many familiar effects like blur and unsharpen are convolution filters. They are pretty well explained at the GameDev article. We can think the above sin-distortion as a convolution filter with spatially variable kernel (coefficient matrix).


Using phadej's answer I got a solution...

The picture is this...

Image distortion with sine/cosine

The code -

<?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);
    ?>

The output

Image distortion with sine/cosine


It depends a lot on how your image works. I don't speak PHP, so this is a general solution.

If we can move individual pixels, the conceptually simplest way to do this would be to say

yold = old y-position of a pixel
ynew = new y-position of the pixel
x = x-position of the pixel
L = length of the image in pixels
N = number of trigonometric cycles to apply (ie number of sin waves)

Then we just iterate through the image. For each value of x, we move the y-pixel:

ynew = yold * (1+sin(Nπx/L)) / 2

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号