AlbumShaper 1.0a3
blackWhite.cpp
Go to the documentation of this file.
1//==============================================
2// copyright : (C) 2003-2005 by Will Stokes
3//==============================================
4// This program is free software; you can redistribute it
5// and/or modify it under the terms of the GNU General
6// Public License as published by the Free Software
7// Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//==============================================
10
11//Systemwide includes
12#include <qimage.h>
13#include <qstring.h>
14#include <qapplication.h>
15
16//Projectwide includes
17#include "blackWhite.h"
18#include "manipulationOptions.h"
20
21//----------------------------------------------
22// Inputs:
23// -------
24// QString filename - location of original image on disk
25// StatusWidget* status - widget for making progress visible to user
26//
27// Outputs:
28// --------
29// QImage* returned - constructed image
30//
31// Description:
32// ------------
33// This method constructs a grayscale version of
34// the image by computing a gray value for each pixel. A naive
35// approach would use the average the red, green, and blue components
36// at each pixel for the new pixel component values, that is:
37//
38// gray = (r+g+b) / 3;
39// r' = gray; g' = gray; b'= gray
40//
41// The problem with this approach is that image luminance
42// (observed brightness) is not maintained. Instead, we conpute
43// the brightness at each pixel using a weighted sum of the color
44// components. Weights vary depending on display device.
45// Old school NTSC TV's which came out in the 50's would
46// tell us to use these r,b,g weights (which Gimp uses):
47// (see http://www.gimp.org/tutorials/Color2BW)
48// (0.3, 0.59, 0.11)
49//
50// But these days we're using modern monitors and the green phosphur
51// is brigther or something so it's best to use these instead:
52// http://lists.trolltech.com/qt-interest/1999-10/thread00337-0.html
53// (0.2125, 0.7154, 0.0721)
54//
55// After weighting, the resulting gray value is clamped to fall within the
56// [0-255] range and assigned to the pixel in the new image.
57//----------------------------------------------
58
59//==============================================
60QImage* blackWhiteEffect( QString filename, ManipulationOptions* options )
61{
62 //load image
63 QImage* editedImage = new QImage( filename );
64
65 //convert to 32-bit depth if necessary
66 if( editedImage->depth() < 32 )
67 {
68 QImage* tmp = editedImage;
69 editedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
70 delete tmp; tmp=NULL;
71 }
72
73 //determine if busy indicators will be used
74 bool useBusyIndicators = false;
75 StatusWidget* status = NULL;
76 if( options != NULL && options->getStatus() != NULL )
77 {
78 useBusyIndicators = true;
79 status = options->getStatus();
80 }
81
82 //setup progress bar
83 if(useBusyIndicators)
84 {
85 QString statusMessage = qApp->translate( "blackWhiteEffect", "Applying Black + White Effect:" );
86 status->showProgressBar( statusMessage, 100 );
87 qApp->processEvents();
88 }
89
90 //update progress bar for every 1% of completion
91 const int updateIncrement = (int) ( 0.01 * editedImage->width() * editedImage->height() );
92 int newProgress = 0;
93
94 //iterate over each selected scanline
95 int x, y, grayValue;
96 QRgb* rgb;
97 uchar* scanLine;
98 for( y=0; y<editedImage->height(); y++)
99 {
100 //iterate over each selected pixel in scanline
101 scanLine = editedImage->scanLine(y);
102 for( x=0; x<editedImage->width(); x++)
103 {
104 //compute gray value based on the display luminance of color coordinates
105 rgb = ((QRgb*)scanLine+x);
106 grayValue = (int) (0.2125*qRed(*rgb) + 0.7154*qGreen(*rgb) + 0.0721*qBlue(*rgb));
107
108 //clamp to ensure it falls in the 0-255 range
109 grayValue = QMIN( QMAX( grayValue, 0 ), 255 );
110
111 //set pixel channel values using computed gray value
112 *rgb = qRgb( grayValue, grayValue, grayValue );
113
114 //update status bar if significant progress has been made since last update
115 if(useBusyIndicators)
116 {
117 newProgress++;
119 {
120 newProgress = 0;
122 qApp->processEvents();
123 }
124 }
125
126 }
127 }
128
129 //return pointer to edited image
130 return editedImage;
131}
132//==============================================
QImage * blackWhiteEffect(QString filename, ManipulationOptions *options)
StatusWidget * getStatus()
void showProgressBar(QString message, int numSteps)
Initializes the progress bar.
void incrementProgress()
Updates the progress bar by one step.
int updateIncrement
QImage * editedImage
StatusWidget * status
int newProgress