AlbumShaper 1.0a3
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

◆ computeLocalGrayVal()

double computeLocalGrayVal ( QImage * image,
int x,
int y )

Definition at line 67 of file pointillism.cpp.

68{
69 int weights[3][3] = { {1,2,1}, {2,4,2}, {1,2,1} };
70
71 int divisorSum = 0;
72 double sum = 0;
73 int xp, yp;
74 for(yp = QMAX( y-1, 0); yp < QMIN( image->height()-1, y+1 ); yp++)
75 {
76 uchar* scanLine = image->scanLine(yp);
77
78 for(xp = QMAX( x-1, 0); xp< QMIN( image->width()-1, x+1 ); xp++)
79 {
80 //compute dx and dy values
81 int dx = xp - x;
82 int dy = yp - y;
83
84 //compute weight index
85 int weightX = dx+1;
86 int weightY = dy+1;
87
88 //update sum and divisor count
89 sum+= (weights[weightX][weightY] * qGray( *((QRgb*)scanLine+xp) ) );
90 divisorSum+= weights[weightX][weightY];
91 }
92 }
93
94 //return weighted average
95 return sum/divisorSum;
96}

Referenced by pointillismEffect().

◆ drawDotAt()

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

Definition at line 98 of file pointillism.cpp.

99{
100 //TODO: antialias over grid, for now
101 //just update this pixel value
102 uchar* scanLine = image->scanLine(y);
103 QRgb* rgb = ((QRgb*)scanLine+x);
104 int red = qRed(*rgb);
105 red = (int) (0.6*red);
106 *rgb = qRgb( red, red, red);
107}

Referenced by pointillismEffect().

◆ pickRandomPixelWithinBlock()

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.

46{
47 int dx = rand() % BLOCK_SIZE;
48 int dy = rand() % BLOCK_SIZE;
49 x = blockX*BLOCK_SIZE + dx;
50 y = blockY*BLOCK_SIZE + dy;
51
52 if(x < 0) x = 0;
53 if(y < 0) y = 0;
54 if(x >= width ) x = width-1;
55 if(y >= height) y = height-1;
56}
int width
Definition blur.cpp:79
int height
Definition blur.cpp:79

References height, and width.

Referenced by pointillismEffect().

◆ pixelValid()

bool pixelValid ( QImage * image,
int x,
int y )

Definition at line 58 of file pointillism.cpp.

59{
60 return (
61 x >= 0 &&
62 y >= 0 &&
63 x < image->width() &&
64 x < image->height() );
65}

References height, and width.

◆ pointillismEffect()

QImage * pointillismEffect ( QString filename,
ManipulationOptions * options )

Definition at line 109 of file pointillism.cpp.

110{
111 //intialize seed using current time
112 srand( unsigned(time(NULL)) );
113
114 //load original image and convert to grayscale
115 QImage* originalImage = blackWhiteEffect( filename, NULL );
116
117 //construct edited image
118 QImage* editedImage = new QImage( originalImage->width(),
119 originalImage->height(),
120 originalImage->depth() );
121
122 //fill with white since we'll be drawing black/color dots on top
123 editedImage->fill( qRgb(255,255,255) );
124
125 //break image into BLOCK_SIZE x BLOCK_SIZE blocks. iterate over
126 //each block and pick a random pixel within. Local
127 //average gray value in edited image is > originalImage + thresh
128 //then draw a dot at pixel. continue doing this for each block
129 //and repeat until ???
130 const int BLOCK_SIZE = 8;
131
132 //compute image size in blocks
133 int blocksWide = editedImage->width() / BLOCK_SIZE;
134 if(blocksWide*BLOCK_SIZE < editedImage->width())
135 { blocksWide++; }
136
137 int blocksTall = editedImage->height() / BLOCK_SIZE;
138 if(blocksTall*BLOCK_SIZE < editedImage->height())
139 { blocksTall++; }
140
141 //iterate over image say 100 times, we'll need to fix this outer loop to be smarter?
142 int bx,by,x,y;
143 for(int i=0; i<10; i++)
144 {
145 //iterate over all blocks
146 for(bx=0; bx<blocksWide; bx++)
147 {
148 for(by=0; by<blocksTall; by++)
149 {
150 //pick random pixel within block
152 editedImage->height(),
153 bx, by,
154 BLOCK_SIZE,
155 x, y );
156
157 double curGrayVal = computeLocalGrayVal( editedImage, x, y );
158 double goalGrayVal = computeLocalGrayVal( originalImage, x, y );
159
160 //too bright -> draw dot
161 if( curGrayVal > goalGrayVal )
162 { drawDotAt( editedImage, x, y, 5 ); }
163 }
164 }
165 }
166
167 //free grayscale form of original image
168 delete originalImage;
169 originalImage = NULL;
170
171 //return pointer to edited image
172 return editedImage;
173}
QImage * blackWhiteEffect(QString filename, ManipulationOptions *options)
double computeLocalGrayVal(QImage *image, int x, int y)
void pickRandomPixelWithinBlock(int width, int height, int blockX, int blockY, int BLOCK_SIZE, int &x, int &y)
void drawDotAt(QImage *image, int x, int y, int)
QImage * editedImage

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

Referenced by EditingInterface::applyEffect().