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 "../../gui/statusWidget.h" 00019 00020 //---------------------------------------------- 00021 // Inputs: 00022 // ------- 00023 // QString filename - location of original image on disk 00024 // StatusWidget* status - widget for making progress visible to user 00025 // 00026 // Outputs: 00027 // -------- 00028 // QImage* returned - constructed image 00029 // 00030 // Description: 00031 // ------------ 00032 // This method constructs a grayscale version of 00033 // the image by computing a gray value for each pixel. A naive 00034 // approach would use the average the red, green, and blue components 00035 // at each pixel for the new pixel component values, that is: 00036 // 00037 // gray = (r+g+b) / 3; 00038 // r' = gray; g' = gray; b'= gray 00039 // 00040 // The problem with this approach is that image luminance 00041 // (observed brightness) is not maintained. Instead, we conpute 00042 // the brightness at each pixel using a weighted sum of the color 00043 // components. Weights vary depending on display device, but 00044 // decent ones, suggest by theGimp, are r,g,b: (0.3, 0.59, 0.11). 00045 // (see http://www.gimp.org/tutorials/Color2BW) 00046 // The resulting gray value is clamped to fall within the 00047 // [0-255] range and assigned to the pixel in the new image. 00048 //---------------------------------------------- 00049 00050 //============================================== 00051 QImage* blackWhiteEffect( QString filename, StatusWidget* status ) 00052 { 00053 //load image 00054 QImage* editedImage = new QImage( filename ); 00055 00056 //determine if busy indicators will be used 00057 bool useBusyIndicators = (status != NULL); 00058 00059 //setup progress bar 00060 if(useBusyIndicators) 00061 { 00062 QString statusMessage = qApp->translate( "blackWhiteEffect", "Applying Black + White Effect:" ); 00063 status->showProgressBar( statusMessage, 100 ); 00064 qApp->processEvents(); 00065 } 00066 00067 //update progress bar for every 1% of completion 00068 const int updateIncrement = (int) ( 0.01 * editedImage->width() * editedImage->height() ); 00069 int newProgress = 0; 00070 00071 //iterate over each selected scanline 00072 int x, y, grayValue; 00073 QRgb* rgb; 00074 uchar* scanLine; 00075 for( y=0; y<editedImage->height(); y++) 00076 { 00077 //iterate over each selected pixel in scanline 00078 scanLine = editedImage->scanLine(y); 00079 for( x=0; x<editedImage->width(); x++) 00080 { 00081 //compute gray value based on the display luminance of color coordinates 00082 rgb = ((QRgb*)scanLine+x); 00083 grayValue = (int) (0.3*qRed(*rgb) + 0.59*qGreen(*rgb) + 0.11*qBlue(*rgb)); 00084 00085 //clamp to ensure it falls in the 0-255 range 00086 grayValue = QMIN( QMAX( grayValue, 0 ), 255 ); 00087 00088 //set pixel channel values using computed gray value 00089 *rgb = qRgb( grayValue, grayValue, grayValue ); 00090 00091 //update status bar if significant progress has been made since last update 00092 if(useBusyIndicators) 00093 { 00094 newProgress++; 00095 if(newProgress >= updateIncrement) 00096 { 00097 newProgress = 0; 00098 status->incrementProgress(); 00099 qApp->processEvents(); 00100 } 00101 } 00102 00103 } 00104 } 00105 00106 //return pointer to edited image 00107 return editedImage; 00108 } 00109 //==============================================