AlbumShaper
1.0a3
|
#include <qimage.h>
#include <qstring.h>
#include <cstdlib>
#include <time.h>
#include "pointillism.h"
#include "blackWhite.h"
#include "manipulationOptions.h"
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 *) |
double computeLocalGrayVal | ( | QImage * | image, |
int | x, | ||
int | y | ||
) |
Definition at line 67 of file pointillism.cpp.
Referenced by pointillismEffect().
{ int weights[3][3] = { {1,2,1}, {2,4,2}, {1,2,1} }; int divisorSum = 0; double sum = 0; int xp, yp; for(yp = QMAX( y-1, 0); yp < QMIN( image->height()-1, y+1 ); yp++) { uchar* scanLine = image->scanLine(yp); for(xp = QMAX( x-1, 0); xp< QMIN( image->width()-1, x+1 ); xp++) { //compute dx and dy values int dx = xp - x; int dy = yp - y; //compute weight index int weightX = dx+1; int weightY = dy+1; //update sum and divisor count sum+= (weights[weightX][weightY] * qGray( *((QRgb*)scanLine+xp) ) ); divisorSum+= weights[weightX][weightY]; } } //return weighted average return sum/divisorSum; }
void drawDotAt | ( | QImage * | image, |
int | x, | ||
int | y, | ||
int | |||
) |
Definition at line 98 of file pointillism.cpp.
Referenced by pointillismEffect().
{ //TODO: antialias over grid, for now //just update this pixel value uchar* scanLine = image->scanLine(y); QRgb* rgb = ((QRgb*)scanLine+x); int red = qRed(*rgb); red = (int) (0.6*red); *rgb = qRgb( red, red, red); }
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.
Referenced by pointillismEffect().
bool pixelValid | ( | QImage * | image, |
int | x, | ||
int | y | ||
) |
QImage* pointillismEffect | ( | QString | filename, |
ManipulationOptions * | |||
) |
Definition at line 109 of file pointillism.cpp.
References blackWhiteEffect(), computeLocalGrayVal(), drawDotAt(), editedImage, height, pickRandomPixelWithinBlock(), and width.
Referenced by EditingInterface::applyEffect().
{ //intialize seed using current time srand( unsigned(time(NULL)) ); //load original image and convert to grayscale QImage* originalImage = blackWhiteEffect( filename, NULL ); //construct edited image QImage* editedImage = new QImage( originalImage->width(), originalImage->height(), originalImage->depth() ); //fill with white since we'll be drawing black/color dots on top editedImage->fill( qRgb(255,255,255) ); //break image into BLOCK_SIZE x BLOCK_SIZE blocks. iterate over //each block and pick a random pixel within. Local //average gray value in edited image is > originalImage + thresh //then draw a dot at pixel. continue doing this for each block //and repeat until ??? const int BLOCK_SIZE = 8; //compute image size in blocks int blocksWide = editedImage->width() / BLOCK_SIZE; if(blocksWide*BLOCK_SIZE < editedImage->width()) { blocksWide++; } int blocksTall = editedImage->height() / BLOCK_SIZE; if(blocksTall*BLOCK_SIZE < editedImage->height()) { blocksTall++; } //iterate over image say 100 times, we'll need to fix this outer loop to be smarter? int bx,by,x,y; for(int i=0; i<10; i++) { //iterate over all blocks for(bx=0; bx<blocksWide; bx++) { for(by=0; by<blocksTall; by++) { //pick random pixel within block pickRandomPixelWithinBlock( editedImage->width(), editedImage->height(), bx, by, BLOCK_SIZE, x, y ); double curGrayVal = computeLocalGrayVal( editedImage, x, y ); double goalGrayVal = computeLocalGrayVal( originalImage, x, y ); //too bright -> draw dot if( curGrayVal > goalGrayVal ) { drawDotAt( editedImage, x, y, 5 ); } } } } //free grayscale form of original image delete originalImage; originalImage = NULL; //return pointer to edited image return editedImage; }