==== Types.h ====
#ifndef TYPES_HEADER
#define TYPES_HEADER
#include "CImg.h"
namespace Xelous
{
 ///<Summary>
 /// Wrapping the unweidly CImg class type into
 /// an easy nemonic
 ///</Summary>
 typedef cimg_library::CImg<unsigned char> Bitmap;
}
#endif
==== GreyscaleHelpers.h ====
#ifndef GREYSCALE_HELPERS_HEADER
#define GREYSCALE_HELPERS_HEADER
#include "Types.h"
namespace Xelous
{
 ///<Summary>
 /// The types of Greyscaling algorithms
 ///</Summary>
 enum GreyscaleAlgorithms
 {
  Average,
  Lightness,
  Luminosity
 };
 ///<Summary>
 /// The colour channels used in
 /// CImg data
 ///</Summary>
 enum ColourChannels
 {
  Red,
  Green,
  Blue
 };
 ///<Summary>
 /// The greyscale helper
 /// class
 ///</Summary>
 class GreyscaleHelper
 {
  private:
   ///<Summary>
   /// Average Grey
   ///</Summary>
   static double Average(const unsigned char& p_red,
    const unsigned char& p_green,
    const unsigned char& p_blue);
   ///<Summary>
   /// Lightness grey
   ///</Summary>
   static double Lightness(const unsigned char& p_red,
    const unsigned char& p_green,
    const unsigned char& p_blue);   
   ///<Summary>
   /// Luminosity grey
   ///</Summary>
   static double Luminosity(const unsigned char& p_red,
    const unsigned char& p_green,
    const unsigned char& p_blue);
   ///<Summary>
   /// Double rounded to integer
   ///</Summary>
   static int DoubleToInteger(const double& p_Value);
  public:
   ///<Summary>
   /// Converts the given image to greyscale
   /// with the indicated algorithm
   ///</Summary>
   static void ConvertToGreyscale(Bitmap* p_InputImage,
    const GreyscaleAlgorithms& p_Algorithm);
 };
}
#endif
==== GreyscaleHelpers.cpp ====
#include "GreyscaleHelpers.h"
#include <algorithm>
namespace Xelous
{
 ///<Summary>
 /// Average Grey
 ///</Summary>
 double GreyscaleHelper::Average(const unsigned char& p_red,
  const unsigned char& p_green,
  const unsigned char& p_blue)
 {
  int l_t = static_cast<int>(p_red)+
   static_cast<int>(p_green)+
   static_cast<int>(p_blue);
  return l_t / 3.0f;
 }
 ///<Summary>
 /// Lightness grey
 ///</Summary>
 double GreyscaleHelper::Lightness(const unsigned char& p_red,
  const unsigned char& p_green,
  const unsigned char& p_blue)
 {
  int l_max = std::max(
   static_cast<int>(p_red),
   std::max(
    static_cast<int>(p_green),
    static_cast<int>(p_blue)));
  int l_min = std::min(
   static_cast<int>(p_red),
   std::min(
    static_cast<int>(p_green),
    static_cast<int>(p_blue)));
  return (l_max + l_min) / 2.0f;
 }
 ///<Summary>
 /// Luminosity grey
 ///</Summary>
 double GreyscaleHelper::Luminosity(const unsigned char& p_red,
  const unsigned char& p_green,
  const unsigned char& p_blue)
 {
  double l_red = 0.21 * static_cast<int>(p_red);
  double l_green = 0.72 * static_cast<int>(p_green);
  double l_blue = 0.07 * static_cast<int>(p_blue);
  return (l_red + l_green + l_blue);
 }
 ///<Summary>
 /// Double rounded to integer
 ///</Summary>
 int GreyscaleHelper::DoubleToInteger(const double& p_Value)
 {
  return static_cast<int>(std::round(p_Value));
 }
 ///<Summary>
 /// Converts the given image to greyscale
 /// with the indicated algorithm
 ///</Summary>
 void GreyscaleHelper::ConvertToGreyscale(Bitmap* p_InputImage, 
  const GreyscaleAlgorithms& p_Algorithm)
 {
  if (p_InputImage != nullptr)
  {
   for (int y = 0; y < p_InputImage->height(); ++y)
   {
    for (int x = 0; x < p_InputImage->width(); ++x)
    {
     unsigned char l_r = *p_InputImage->data(x, y, 0, ColourChannels::Red);
     unsigned char l_g = *p_InputImage->data(x, y, 0, ColourChannels::Green);
     unsigned char l_b = *p_InputImage->data(x, y, 0, ColourChannels::Blue);
     double l_a = 0;
     switch (p_Algorithm)
     {
     case GreyscaleAlgorithms::Average:
      l_a = DoubleToInteger(Average(l_r, l_g, l_b));
      break;
     case GreyscaleAlgorithms::Lightness:
      l_a = Lightness(l_r, l_g, l_b);
      break;
     case GreyscaleAlgorithms::Luminosity:
      l_a = Luminosity(l_r, l_g, l_b);
      break;
     }
     int l_n = DoubleToInteger(l_a);
     *p_InputImage->data(x, y, 0, ColourChannels::Red) = static_cast<unsigned char>(l_n);
     *p_InputImage->data(x, y, 0, ColourChannels::Green) = static_cast<unsigned char>(l_n);
     *p_InputImage->data(x, y, 0, ColourChannels::Blue) = static_cast<unsigned char>(l_n);
    }
   }
  }
 }
}
==== main.cpp ====
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include "Types.h"
#include "GreyscaleHelpers.h"
Xelous::Bitmap* LoadTest(const std::string& p_Filename);
int main(int p_argc, char* p_argv[])
{
 std::cout << "Hello World" << std::endl;
 Xelous::Bitmap* l_BmpAverage = LoadTest("C:\\Code\\Items1.bmp");
 Xelous::GreyscaleHelper::ConvertToGreyscale(l_BmpAverage, Xelous::GreyscaleAlgorithms::Average);
 l_BmpAverage->save("C:\\Code\\Items1_Average.bmp");
 delete l_BmpAverage;
 Xelous::Bitmap* l_BmpLuminosity = LoadTest("C:\\Code\\Items1.bmp");
 Xelous::GreyscaleHelper::ConvertToGreyscale(l_BmpLuminosity, Xelous::GreyscaleAlgorithms::Luminosity);
 l_BmpLuminosity->save("C:\\Code\\Items1_Luminosity.bmp");
 delete l_BmpLuminosity;
 Xelous::Bitmap* l_BmpLightness = LoadTest("C:\\Code\\Items1.bmp");
 Xelous::GreyscaleHelper::ConvertToGreyscale(l_BmpLightness, Xelous::GreyscaleAlgorithms::Lightness);
 l_BmpLightness->save("C:\\Code\\Items1_Lightness.bmp");
 delete l_BmpLightness; 
}
Xelous::Bitmap* LoadTest(const std::string& p_Filename)
{ 
 return new Xelous::Bitmap(p_Filename.c_str()); 
}
No comments:
Post a Comment