home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2003 November / PCWK1103B.iso / PCWK-txt / Warsztat_Cpp_Builder / fotoretusz.cpp < prev    next >
C/C++ Source or Header  |  2003-10-02  |  9KB  |  363 lines

  1. /*
  2.   Ten plik ƒr≤d│owy mo┐e byc dowolnie wykorzystywany, pod warunkiem,
  3.   ┐e ka┐da aplikacja zbudowana z jego wykorzystaniem zawieraµ bΩdzie
  4.   informacje o pochodzeniu niniejszego zestawu funkcji.
  5.   Pawe│ Br╣goszewski, PC World Kompuer 11/2003
  6. */
  7.  
  8. #include "fotoretusz.h"
  9. #include "vcl\Math.hpp"
  10. #ifndef sqr
  11. #define sqr(A) (A)*(A)
  12. #endif
  13.  
  14. //
  15. // Zmiana jasnosci bitmapy bmp o wartosc val
  16. //
  17. int DostosujJasnosc( Graphics::TBitmap *bmp, int val )
  18. {
  19.   int wysokosc, szerokosc;
  20.   int r,g,b;
  21.  
  22.   wysokosc = bmp->Height;
  23.   szerokosc = bmp->Width;
  24.  
  25.   for( int i=0; i<wysokosc; i++ )
  26.   {
  27.      RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
  28.      for( int j=0; j<szerokosc; j++ )
  29.      {
  30.        //pobierz sk│adowe RGB
  31.        b = wiersz[j].rgbBlue;
  32.        g = wiersz[j].rgbGreen;
  33.        r = wiersz[j].rgbRed;
  34.  
  35.        r += val;
  36.        g += val;
  37.        b += val;
  38.  
  39.        r = (r>255)?255:(r<0)?0:r;
  40.        b = (b>255)?255:(b<0)?0:b;
  41.        g = (g>255)?255:(g<0)?0:g;
  42.  
  43.        //przejdz do nastΩpnego piksela
  44.        wiersz[j].rgbBlue = (BYTE) b;
  45.        wiersz[j].rgbGreen = (BYTE) g;
  46.        wiersz[j].rgbRed = (BYTE) r;
  47.      }
  48.   }
  49.  
  50. } //DostosujJasnosc
  51.  
  52. //
  53. // Zmiana kontrastu bitmapy bmp o wartosc val
  54. //
  55. int DostosujKontrast( Graphics::TBitmap *bmp, int val )
  56. {
  57.   int wysokosc, szerokosc;
  58.   double v = 1.2725*val;
  59.  
  60.   double v1 = 255/(255-2*v);
  61.   double v2 = (255+2*v)/255;
  62.  
  63.   wysokosc = bmp->Height;
  64.   szerokosc = bmp->Width;
  65.  
  66.   for( int i=0; i<wysokosc; i++ )
  67.   {
  68.      RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
  69.      for( int j=0; j<szerokosc; j++ )
  70.      {
  71.        //pobierz sk│adowe RGB
  72.        int b = wiersz[j].rgbBlue;
  73.        int g = wiersz[j].rgbGreen;
  74.        int r = wiersz[j].rgbRed;
  75.  
  76.        //zmodyfikuj sk│adowe r,g,b
  77.        if(v>0)
  78.        {
  79.          r = (r<v)?0:(r>255-v)?255:v1*(r-v);
  80.          g = (g<v)?0:(g>255-v)?255:v1*(g-v);
  81.          b = (b<v)?0:(b>255-v)?255:v1*(b-v);
  82.        }
  83.        else if(v<0)
  84.        {
  85.          r = -v+v2*r;
  86.          g = -v+v2*g;
  87.          b = -v+v2*b;
  88.        }
  89.  
  90.        //sprawdƒ zakresy
  91.        r = (r>255)?255:(r<0)?0:r;
  92.        b = (b>255)?255:(b<0)?0:b;
  93.        g = (g>255)?255:(g<0)?0:g;
  94.  
  95.        //przejdz do nastΩpnego piksela
  96.        wiersz[j].rgbBlue = (BYTE) b;
  97.        wiersz[j].rgbGreen = (BYTE) g;
  98.        wiersz[j].rgbRed = (BYTE) r;
  99.      }
  100.   }
  101.  
  102. } //DostosujKontrast
  103.  
  104.  
  105. //
  106. // Zmiana nasycenia kolor≤w o wartosv val
  107. //
  108. int DostosujNasycenie( Graphics::TBitmap *bmp, int val )
  109. {
  110.   int wysokosc, szerokosc;
  111.   double x = 1.0+val/100.0;
  112.   wysokosc = bmp->Height;
  113.   szerokosc = bmp->Width;
  114.  
  115.   for( int i=0; i<wysokosc; i++ )
  116.   {
  117.      RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
  118.      for( int j=0; j<szerokosc; j++ )
  119.      {
  120.        //pobierz sk│adowe RGB
  121.        int b = wiersz[j].rgbBlue;
  122.        int g = wiersz[j].rgbGreen;
  123.        int r = wiersz[j].rgbRed;
  124.  
  125.        int szary = (r+g+b)/3.0;
  126.  
  127.        r = szary + (r-szary)*x;
  128.        g = szary + (g-szary)*x;
  129.        b = szary + (b-szary)*x;
  130.  
  131.        r = (r>255)?255:(r<0)?0:r;
  132.        b = (b>255)?255:(b<0)?0:b;
  133.        g = (g>255)?255:(g<0)?0:g;
  134.  
  135.        //przejdz do nastΩpnego piksela
  136.        wiersz[j].rgbBlue = (BYTE) b;
  137.        wiersz[j].rgbGreen = (BYTE) g;
  138.        wiersz[j].rgbRed = (BYTE) r;
  139.      }
  140.   }
  141.  
  142. } //DostosujNasycenie
  143.  
  144. // Przygotuj Miniature
  145. // funkcja tworzy miniature z obrazka oryginal, zapisuj╣c j╣ w miniatura
  146. // miniature ma wymiary szerokosc,wysokosc
  147.  
  148. int PrzygotujMiniature( Graphics::TBitmap *oryginal, Graphics::TBitmap *miniatura,int szerokosc, int wysokosc)
  149. {
  150.  TMemoryStream *pms = new TMemoryStream;
  151.  
  152.  if( szerokosc>0 && wysokosc>0 )
  153.  {
  154.    pms->Position = 0;
  155.    oryginal->SaveToStream(pms);
  156.    pms->Position = 0;
  157.    miniatura->LoadFromStream( pms );
  158.  
  159.    double skok_wys = oryginal->Height/(double)wysokosc;
  160.    double skok_szer = oryginal->Width/(double)szerokosc;
  161.    miniatura->Width = szerokosc;
  162.    miniatura->Height = wysokosc;
  163.  
  164.    int *wiersz_oryginal,*wiersz_min;
  165.  
  166.    for( int i=0; i<wysokosc; i++)
  167.    {
  168.      wiersz_min = (int *) miniatura->ScanLine[i];
  169.      wiersz_oryginal = (int *) oryginal->ScanLine[ (int)(i*skok_wys) ];
  170.      for( int j=0; j<szerokosc; j++)
  171.      {
  172.        wiersz_min[j] = wiersz_oryginal[ (int)(j*skok_szer) ];
  173.      }
  174.    }
  175.  }
  176.  
  177.  delete pms;
  178. } //PrzygotujMiniature
  179.  
  180. //
  181. // Zmien balans kolorow wg xr, xg i xb, odpowiednio modyfikuj╣cych
  182. // sk│adowe R, G i B
  183. //
  184. int DostosujBalans( Graphics::TBitmap *bmp, int xr, int xg, int xb )
  185. {
  186.   int wysokosc, szerokosc;
  187.   int r,g,b;
  188.  
  189.   wysokosc = bmp->Height;
  190.   szerokosc = bmp->Width;
  191.  
  192.   for( int i=0; i<wysokosc; i++ )
  193.   {
  194.      RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
  195.      for( int j=0; j<szerokosc; j++ )
  196.      {
  197.        //pobierz sk│adowe RGB
  198.        int b = wiersz[j].rgbBlue;
  199.        int g = wiersz[j].rgbGreen;
  200.        int r = wiersz[j].rgbRed;
  201.  
  202.        r += xr;
  203.        g += xg;
  204.        b += xb;
  205.  
  206.        r = (r>255)?255:(r<0)?0:r;
  207.        b = (b>255)?255:(b<0)?0:b;
  208.        g = (g>255)?255:(g<0)?0:g;
  209.  
  210.        //przejdz do nastΩpnego piksela
  211.        wiersz[j].rgbBlue = (BYTE) b;
  212.        wiersz[j].rgbGreen = (BYTE) g;
  213.        wiersz[j].rgbRed = (BYTE) r;
  214.      }
  215.   }
  216.  
  217. } //DostosujBalans
  218.  
  219. //
  220. // Przeksztalc bitmapΩ bmp na jej negatyw
  221. //
  222. int Negatyw( Graphics::TBitmap *bmp)
  223. {
  224.   int wysokosc, szerokosc;
  225.  
  226.   wysokosc = bmp->Height;
  227.   szerokosc = bmp->Width;
  228.  
  229.   for( int i=0; i<wysokosc; i++ )
  230.   {
  231.      RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
  232.      for( int j=0; j<szerokosc; j++ )
  233.      {
  234.        // tutaj uzyty jest operator negacji bitowej!
  235.        wiersz[j].rgbBlue = ~wiersz[j].rgbBlue;
  236.        wiersz[j].rgbGreen = ~wiersz[j].rgbGreen;
  237.        wiersz[j].rgbRed = ~wiersz[j].rgbRed;
  238.      }
  239.   }
  240.  
  241. }//Negatyw
  242.  
  243. //
  244. // zmien bitmapΩ bmp na obraz w odcieniach szarosci
  245. //
  246. int OdcienieSzarosci( Graphics::TBitmap *bmp)
  247. {
  248.   int wysokosc, szerokosc;
  249.   int szary;
  250.   wysokosc = bmp->Height;
  251.   szerokosc = bmp->Width;
  252.  
  253.   for( int i=0; i<wysokosc; i++ )
  254.   {
  255.      RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
  256.      for( int j=0; j<szerokosc; j++ )
  257.      {
  258.        // oblicz poziom szarosci piksela
  259.        szary = (wiersz[j].rgbBlue+wiersz[j].rgbGreen+wiersz[j].rgbRed)/3;
  260.        // podstaw t╣ sam╣ wartosc dla wszystkich skladowych
  261.        wiersz[j].rgbBlue = szary;
  262.        wiersz[j].rgbGreen = szary;
  263.        wiersz[j].rgbRed = szary;
  264.      }
  265.   }
  266.  
  267. }//OdcienieSzarosci
  268.  
  269.  
  270. //
  271. // Filtr3x3 przektsztalca bitmape bmp wg filtru filtr[3][3] i zapisuje
  272. // wynik w outbmp
  273. //
  274. int Filtr3x3( Graphics::TBitmap *bmp, Graphics::TBitmap *outbmp, double filtr[3][3] )
  275. {
  276.   int wysokosc, szerokosc;
  277.   int i,j;
  278.   RGBQUAD *piksel[3];
  279.  
  280.   wysokosc = bmp->Height;
  281.   szerokosc = bmp->Width;
  282.   //outbmp->Width = szerokosc;
  283.   //outbmp->Height = szerokosc;
  284.  
  285.   double suma = 0;
  286.  
  287.   // oblicz sume elementow tablicy filtru
  288.   for( i=0; i<3; i++)
  289.         for( j=0; j<3; j++)
  290.                 suma += filtr[i][j];
  291.  
  292.  
  293.   for( i=0; i<wysokosc; i++ )
  294.   {
  295.      // *wiersz to wskaznik do WYJSCIOWEJ bitmapy
  296.      RGBQUAD *wiersz = (RGBQUAD *) outbmp->ScanLine[i];
  297.  
  298.      // pobierz piksel i jego s╣siad≤w
  299.      // zwracaj╣c uwagΩ na przekroczenie granic obrazka
  300.      // *piksel wksazuje na elementy WEJSCIOWEJ bitmapy
  301.  
  302.      piksel[1] = (RGBQUAD *) bmp->ScanLine[i];
  303.      if(i>0)
  304.        piksel[0] = (RGBQUAD *) bmp->ScanLine[i-1];
  305.      else
  306.        piksel[0] = piksel[1];
  307.  
  308.      if(i<wysokosc-1)
  309.         piksel[2] = (RGBQUAD *) bmp->ScanLine[i+1];
  310.      else
  311.         piksel[2] = piksel[1];
  312.  
  313.  
  314.      for( j=0; j<szerokosc; j++ )
  315.      {
  316.        double b = 0;
  317.        double g = 0;
  318.        double r = 0;
  319.  
  320.        //oblicz wynikow╣ wartosc skladowych r,g,b po zastosowaniu filtru
  321.        for( int k=0; k<3 ; k++ )
  322.                for( int l=0; l<3 ; l++ )
  323.                {
  324.                  if(j==0&&k==0)
  325.                  {
  326.                         r += filtr[k][l]*piksel[l][0].rgbRed;
  327.                         g += filtr[k][l]*piksel[l][0].rgbGreen;
  328.                         b += filtr[k][l]*piksel[l][0].rgbBlue;
  329.                  }
  330.                  else if(j==szerokosc-1&&k==2)
  331.                  {
  332.                         r += filtr[k][l]*piksel[l][j].rgbRed;
  333.                         g += filtr[k][l]*piksel[l][j].rgbGreen;
  334.                         b += filtr[k][l]*piksel[l][j].rgbBlue;
  335.                  }
  336.                  else
  337.                  {
  338.                         r += filtr[k][l]*piksel[l][j-1+k].rgbRed;
  339.                         g += filtr[k][l]*piksel[l][j-1+k].rgbGreen;
  340.                         b += filtr[k][l]*piksel[l][j-1+k].rgbBlue;
  341.                  }
  342.                }
  343.        if( suma!=0 )
  344.        {
  345.          r /= suma;
  346.          g /= suma;
  347.          b /= suma;
  348.        }
  349.  
  350.        //sprawdz zakresy
  351.        r = (r>255)?255:(r<0)?0:r;
  352.        b = (b>255)?255:(b<0)?0:b;
  353.        g = (g>255)?255:(g<0)?0:g;
  354.  
  355.        //zapisz w WYJSCIOWEJ bitmapie
  356.        wiersz[j].rgbBlue = (BYTE) b;
  357.        wiersz[j].rgbGreen = (BYTE) g;
  358.        wiersz[j].rgbRed = (BYTE) r;
  359.      }
  360.   }
  361.  
  362. } //DostosujBalans
  363.