blackWhite.cpp

Go to the documentation of this file.
00001 //==============================================
00002 //  copyright            : (C) 2003-2005 by Will Stokes
00003 //==============================================
00004 //  This program is free software; you can redistribute it
00005 //  and/or modify it under the terms of the GNU General
00006 //  Public License as published by the Free Software
00007 //  Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //==============================================
00010 
00011 //Systemwide includes
00012 #include <qimage.h>
00013 #include <qstring.h>
00014 #include <qapplication.h>
00015 
00016 //Projectwide includes
00017 #include "blackWhite.h"
00018 #include "manipulationOptions.h"
00019 #include "../../gui/statusWidget.h"
00020 
00021 //----------------------------------------------
00022 // Inputs:
00023 // -------
00024 // QString filename - location of original image on disk
00025 // StatusWidget* status - widget for making progress visible to user
00026 //
00027 // Outputs:
00028 // --------
00029 // QImage* returned - constructed image
00030 //
00031 // Description:
00032 // ------------
00033 // This method constructs a grayscale version of
00034 // the image by computing a gray value for each pixel. A naive
00035 // approach would use the average the red, green, and blue components
00036 // at each pixel for the new pixel component values, that is:
00037 //
00038 // gray = (r+g+b) / 3;
00039 // r' = gray; g' = gray; b'= gray
00040 //
00041 // The problem with this approach is that image luminance 
00042 // (observed brightness) is not maintained. Instead, we conpute
00043 // the brightness at each pixel using a weighted sum of the color
00044 // components. Weights vary depending on display device.
00045 // Old school NTSC TV's which came out in the 50's would
00046 // tell us to use these r,b,g weights (which Gimp uses):
00047 // (see http://www.gimp.org/tutorials/Color2BW)
00048 // (0.3, 0.59, 0.11)
00049 //
00050 // But these days we're using modern monitors and the green phosphur 
00051 // is brigther or something so it's best to use these instead:
00052 // http://lists.trolltech.com/qt-interest/1999-10/thread00337-0.html
00053 // (0.2125, 0.7154, 0.0721)
00054 //
00055 // After weighting, the resulting gray value is clamped to fall within the 
00056 // [0-255] range and assigned to the pixel in the new image.
00057 //----------------------------------------------
00058 
00059 //==============================================
00060 QImage* blackWhiteEffect( QString filename, ManipulationOptions* options )
00061 {
00062   //load image
00063   QImage* editedImage = new QImage( filename );
00064   
00065   //convert to 32-bit depth if necessary
00066   if( editedImage->depth() < 32 )
00067   {
00068     QImage* tmp = editedImage;
00069     editedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
00070     delete tmp; tmp=NULL;
00071   }
00072   
00073   //determine if busy indicators will be used
00074   bool useBusyIndicators = false;
00075   StatusWidget* status = NULL;
00076   if( options != NULL && options->getStatus() != NULL )
00077   {
00078     useBusyIndicators = true;
00079     status = options->getStatus(); 
00080   }
00081   
00082   //setup progress bar
00083   if(useBusyIndicators)
00084   {
00085     QString statusMessage = qApp->translate( "blackWhiteEffect", "Applying Black + White Effect:" );
00086     status->showProgressBar( statusMessage, 100 );
00087     qApp->processEvents();  
00088   }
00089   
00090   //update progress bar for every 1% of completion
00091   const int updateIncrement = (int) ( 0.01 * editedImage->width() * editedImage->height() );
00092   int newProgress = 0; 
00093 
00094   //iterate over each selected scanline 
00095   int x, y, grayValue;
00096   QRgb* rgb;
00097   uchar* scanLine;
00098   for( y=0; y<editedImage->height(); y++)
00099   {   
00100     //iterate over each selected pixel in scanline
00101     scanLine = editedImage->scanLine(y);
00102     for( x=0; x<editedImage->width(); x++)
00103     {
00104       //compute gray value based on the display luminance of color coordinates
00105       rgb = ((QRgb*)scanLine+x);
00106       grayValue = (int) (0.2125*qRed(*rgb) + 0.7154*qGreen(*rgb) + 0.0721*qBlue(*rgb));
00107       
00108       //clamp to ensure it falls in the 0-255 range
00109       grayValue = QMIN( QMAX( grayValue, 0 ), 255 );      
00110       
00111       //set pixel channel values using computed gray value
00112       *rgb = qRgb( grayValue, grayValue, grayValue );      
00113 
00114       //update status bar if significant progress has been made since last update
00115       if(useBusyIndicators)
00116       {
00117         newProgress++;
00118         if(newProgress >= updateIncrement)
00119         {
00120           newProgress = 0;
00121           status->incrementProgress();
00122           qApp->processEvents();  
00123         }
00124       }
00125 
00126     }
00127   }
00128    
00129   //return pointer to edited image
00130   return editedImage;  
00131 }
00132 //==============================================

Generated on Thu Jan 3 10:54:40 2008 for AlbumShaper by  doxygen 1.5.4