Pillow
160 строк · 4.9 Кб
1/*
2* The Python Imaging Library
3* $Id$
4*
5* various special effects and image generators
6*
7* history:
8* 1997-05-21 fl Just for fun
9* 1997-06-05 fl Added mandelbrot generator
10* 2003-05-24 fl Added perlin_turbulence generator (in progress)
11*
12* Copyright (c) 1997-2003 by Fredrik Lundh.
13* Copyright (c) 1997 by Secret Labs AB.
14*
15* See the README file for information on usage and redistribution.
16*/
17
18#include "Imaging.h"19
20#include <math.h>21
22Imaging
23ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) {24/* Generate a Mandelbrot set covering the given extent */25
26Imaging im;27int x, y, k;28double width, height;29double x1, y1, xi2, yi2, cr, ci, radius;30double dr, di;31
32/* Check arguments */33width = extent[2] - extent[0];34height = extent[3] - extent[1];35if (width < 0.0 || height < 0.0 || quality < 2) {36return (Imaging)ImagingError_ValueError(NULL);37}38
39im = ImagingNewDirty("L", xsize, ysize);40if (!im) {41return NULL;42}43
44dr = width / (xsize - 1);45di = height / (ysize - 1);46
47radius = 100.0;48
49for (y = 0; y < ysize; y++) {50UINT8 *buf = im->image8[y];51for (x = 0; x < xsize; x++) {52x1 = y1 = xi2 = yi2 = 0.0;53cr = x * dr + extent[0];54ci = y * di + extent[1];55for (k = 1;; k++) {56y1 = 2 * x1 * y1 + ci;57x1 = xi2 - yi2 + cr;58xi2 = x1 * x1;59yi2 = y1 * y1;60if ((xi2 + yi2) > radius) {61buf[x] = k * 255 / quality;62break;63}64if (k > quality) {65buf[x] = 0;66break;67}68}69}70}71return im;72}
73
74Imaging
75ImagingEffectNoise(int xsize, int ysize, float sigma) {76/* Generate Gaussian noise centered around 128 */77
78Imaging imOut;79int x, y;80int nextok;81double this, next;82
83imOut = ImagingNewDirty("L", xsize, ysize);84if (!imOut) {85return NULL;86}87
88next = 0.0;89nextok = 0;90
91for (y = 0; y < imOut->ysize; y++) {92UINT8 *out = imOut->image8[y];93for (x = 0; x < imOut->xsize; x++) {94if (nextok) {95this = next;96nextok = 0;97} else {98/* after numerical recipes */99double v1, v2, radius, factor;100do {101v1 = rand() * (2.0 / RAND_MAX) - 1.0;102v2 = rand() * (2.0 / RAND_MAX) - 1.0;103radius = v1 * v1 + v2 * v2;104} while (radius >= 1.0);105factor = sqrt(-2.0 * log(radius) / radius);106this = factor * v1;107next = factor * v2;108}109out[x] = CLIP8(128 + sigma * this);110}111}112
113return imOut;114}
115
116Imaging
117ImagingEffectSpread(Imaging imIn, int distance) {118/* Randomly spread pixels in an image */119
120Imaging imOut;121int x, y;122
123imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize);124
125if (!imOut) {126return NULL;127}128
129#define SPREAD(type, image) \130if (distance == 0) { \131for (y = 0; y < imOut->ysize; y++) { \132for (x = 0; x < imOut->xsize; x++) { \133imOut->image[y][x] = imIn->image[y][x]; \134} \135} \136} else { \137for (y = 0; y < imOut->ysize; y++) { \138for (x = 0; x < imOut->xsize; x++) { \139int xx = x + (rand() % distance) - distance / 2; \140int yy = y + (rand() % distance) - distance / 2; \141if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) { \142imOut->image[yy][xx] = imIn->image[y][x]; \143imOut->image[y][x] = imIn->image[yy][xx]; \144} else { \145imOut->image[y][x] = imIn->image[y][x]; \146} \147} \148} \149}150
151if (imIn->image8) {152SPREAD(UINT8, image8);153} else {154SPREAD(INT32, image32);155}156
157ImagingCopyPalette(imOut, imIn);158
159return imOut;160}
161