AlbumShaper  1.0a3
sepia.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 "sepia.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 sepia version of
00034 // the image by computing a sepia value for each pixel. 
00035 // The sepia effect is intended to mimick sepia coloring 
00036 // obtained during traditional film development.
00037 //
00038 // First, a sepia color is chosen with a nice yellowy-orange tone
00039 // (r,g,b = 162,128,101). This color is next converted to HSL 
00040 // (hue, saturation, luminance) space and used during sepia coloring.
00041 // 
00042 // For each pixel, we construct a modified sepia color where the original
00043 // luminance (brightness) is replaced with that pixels luminance using
00044 // a weighted sum of the color channels. (For more information on image
00045 // luminance see the blackWhite effect). This modified sepia color is
00046 // converted back to RGB color space and used for the pixel color
00047 // in the modified image. This way image brightness is maintained
00048 // while color information is replaced with the sepia color. The
00049 // sepia color can be adjusted to produce a differnt overall color
00050 // feeling by changing the original sepia color.
00051 //----------------------------------------------
00052 
00053 //==============================================
00054 QImage* sepiaEffect( QString filename, ManipulationOptions* options )
00055 {
00056   //load image
00057   QImage* editedImage = new QImage( filename );
00058   
00059   //convert to 32-bit depth if necessary
00060   if( editedImage->depth() < 32 )
00061   {
00062     QImage* tmp = editedImage;
00063     editedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
00064     delete tmp; tmp=NULL;
00065   }
00066 
00067   //determine if busy indicators will be used
00068   bool useBusyIndicators = false;
00069   StatusWidget* status = NULL;
00070   if( options != NULL && options->getStatus() != NULL )
00071   {
00072     useBusyIndicators = true;
00073     status = options->getStatus(); 
00074   }
00075   
00076   //setup progress bar
00077   if(useBusyIndicators)
00078   {
00079     QString statusMessage = qApp->translate( "sepiaEffect", "Applying Sepia Effect:" );
00080     status->showProgressBar( statusMessage, 100 );
00081     qApp->processEvents();  
00082   }
00083   
00084   //update progress bar for every 1% of completion
00085   const int updateIncrement = (int) ( 0.01 * editedImage->width() * editedImage->height() );
00086   int newProgress = 0; 
00087 
00088   //compute the hsl/hsv coordinates of sepia color
00089   int sepiaH, sepiaS, sepiaL;
00090   QColor(162,128,101).getHsv( &sepiaH, &sepiaS, &sepiaL );
00091   
00092   //iterate over each selected scanline 
00093   int x, y, pixelLuminance;
00094   QRgb* rgb;
00095   QColor sepiaColor;
00096   uchar* scanLine;
00097   
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       pixelLuminance = (int) (0.2125*qRed(*rgb) + 0.7154*qGreen(*rgb) + 0.0721*qBlue(*rgb));
00107       
00108       //compute and set sepia color
00109       sepiaColor.setHsv( sepiaH, sepiaS, pixelLuminance );      
00110       *rgb = sepiaColor.rgb();
00111       
00112       //update status bar if significant progress has been made since last update
00113       if(useBusyIndicators)
00114       {
00115         newProgress++;
00116         if(newProgress >= updateIncrement)
00117         {
00118           newProgress = 0;
00119           status->incrementProgress();
00120           qApp->processEvents();  
00121         }
00122       }
00123       
00124     }
00125   }
00126   
00127   //return pointer to edited image
00128   return editedImage;  
00129 }
00130 //==============================================