Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

pointillism.cpp File Reference

#include <qimage.h>
#include <qstring.h>
#include <cstdlib>
#include <time.h>
#include "pointillism.h"
#include "blackWhite.h"
#include "manipulationOptions.h"

Include dependency graph for pointillism.cpp:

Go to the source code of this file.

Functions

void pickRandomPixelWithinBlock (int width, int height, int blockX, int blockY, int BLOCK_SIZE, int &x, int &y)
bool pixelValid (QImage *image, int x, int y)
double computeLocalGrayVal (QImage *image, int x, int y)
void drawDotAt (QImage *image, int x, int y, int)
QImage * pointillismEffect (QString filename, ManipulationOptions *)


Function Documentation

double computeLocalGrayVal QImage *  image,
int  x,
int  y
 

Definition at line 67 of file pointillism.cpp.

Referenced by pointillismEffect().

00068 { 00069 int weights[3][3] = { {1,2,1}, {2,4,2}, {1,2,1} }; 00070 00071 int divisorSum = 0; 00072 double sum = 0; 00073 int xp, yp; 00074 for(yp = QMAX( y-1, 0); yp < QMIN( image->height()-1, y+1 ); yp++) 00075 { 00076 uchar* scanLine = image->scanLine(yp); 00077 00078 for(xp = QMAX( x-1, 0); xp< QMIN( image->width()-1, x+1 ); xp++) 00079 { 00080 //compute dx and dy values 00081 int dx = xp - x; 00082 int dy = yp - y; 00083 00084 //compute weight index 00085 int weightX = dx+1; 00086 int weightY = dy+1; 00087 00088 //update sum and divisor count 00089 sum+= (weights[weightX][weightY] * qGray( *((QRgb*)scanLine+xp) ) ); 00090 divisorSum+= weights[weightX][weightY]; 00091 } 00092 } 00093 00094 //return weighted average 00095 return sum/divisorSum; 00096 }

void drawDotAt QImage *  image,
int  x,
int  y,
int 
 

Definition at line 98 of file pointillism.cpp.

Referenced by pointillismEffect().

00099 { 00100 //TODO: antialias over grid, for now 00101 //just update this pixel value 00102 uchar* scanLine = image->scanLine(y); 00103 QRgb* rgb = ((QRgb*)scanLine+x); 00104 int red = qRed(*rgb); 00105 red = (int) (0.6*red); 00106 *rgb = qRgb( red, red, red); 00107 }

void pickRandomPixelWithinBlock int  width,
int  height,
int  blockX,
int  blockY,
int  BLOCK_SIZE,
int &  x,
int &  y
 

Definition at line 42 of file pointillism.cpp.

References height, and width.

Referenced by pointillismEffect().

00046 { 00047 int dx = rand() % BLOCK_SIZE; 00048 int dy = rand() % BLOCK_SIZE; 00049 x = blockX*BLOCK_SIZE + dx; 00050 y = blockY*BLOCK_SIZE + dy; 00051 00052 if(x < 0) x = 0; 00053 if(y < 0) y = 0; 00054 if(x >= width ) x = width-1; 00055 if(y >= height) y = height-1; 00056 }

bool pixelValid QImage *  image,
int  x,
int  y
 

Definition at line 58 of file pointillism.cpp.

00059 { 00060 return ( 00061 x >= 0 && 00062 y >= 0 && 00063 x < image->width() && 00064 x < image->height() ); 00065 }

QImage* pointillismEffect QString  filename,
ManipulationOptions
 

Definition at line 109 of file pointillism.cpp.

References blackWhiteEffect(), computeLocalGrayVal(), drawDotAt(), editedImage, and pickRandomPixelWithinBlock().

Referenced by EditingInterface::applyEffect().

00110 { 00111 //intialize seed using current time 00112 srand( unsigned(time(NULL)) ); 00113 00114 //load original image and convert to grayscale 00115 QImage* originalImage = blackWhiteEffect( filename, NULL ); 00116 00117 //construct edited image 00118 QImage* editedImage = new QImage( originalImage->width(), 00119 originalImage->height(), 00120 originalImage->depth() ); 00121 00122 //fill with white since we'll be drawing black/color dots on top 00123 editedImage->fill( qRgb(255,255,255) ); 00124 00125 //break image into BLOCK_SIZE x BLOCK_SIZE blocks. iterate over 00126 //each block and pick a random pixel within. Local 00127 //average gray value in edited image is > originalImage + thresh 00128 //then draw a dot at pixel. continue doing this for each block 00129 //and repeat until ??? 00130 const int BLOCK_SIZE = 8; 00131 00132 //compute image size in blocks 00133 int blocksWide = editedImage->width() / BLOCK_SIZE; 00134 if(blocksWide*BLOCK_SIZE < editedImage->width()) 00135 { blocksWide++; } 00136 00137 int blocksTall = editedImage->height() / BLOCK_SIZE; 00138 if(blocksTall*BLOCK_SIZE < editedImage->height()) 00139 { blocksTall++; } 00140 00141 //iterate over image say 100 times, we'll need to fix this outer loop to be smarter? 00142 int bx,by,x,y; 00143 for(int i=0; i<10; i++) 00144 { 00145 //iterate over all blocks 00146 for(bx=0; bx<blocksWide; bx++) 00147 { 00148 for(by=0; by<blocksTall; by++) 00149 { 00150 //pick random pixel within block 00151 pickRandomPixelWithinBlock( editedImage->width(), 00152 editedImage->height(), 00153 bx, by, 00154 BLOCK_SIZE, 00155 x, y ); 00156 00157 double curGrayVal = computeLocalGrayVal( editedImage, x, y ); 00158 double goalGrayVal = computeLocalGrayVal( originalImage, x, y ); 00159 00160 //too bright -> draw dot 00161 if( curGrayVal > goalGrayVal ) 00162 { drawDotAt( editedImage, x, y, 5 ); } 00163 } 00164 } 00165 } 00166 00167 //free grayscale form of original image 00168 delete originalImage; 00169 originalImage = NULL; 00170 00171 //return pointer to edited image 00172 return editedImage; 00173 }


Generated on Sun Mar 4 19:43:01 2007 for AlbumShaper by doxygen 1.3.7