home *** CD-ROM | disk | FTP | other *** search
- /*
- Ten plik ƒr≤d│owy mo┐e byc dowolnie wykorzystywany, pod warunkiem,
- ┐e ka┐da aplikacja zbudowana z jego wykorzystaniem zawieraµ bΩdzie
- informacje o pochodzeniu niniejszego zestawu funkcji.
- Pawe│ Br╣goszewski, PC World Kompuer 11/2003
- */
-
- #include "fotoretusz.h"
- #include "vcl\Math.hpp"
- #ifndef sqr
- #define sqr(A) (A)*(A)
- #endif
-
- //
- // Zmiana jasnosci bitmapy bmp o wartosc val
- //
- int DostosujJasnosc( Graphics::TBitmap *bmp, int val )
- {
- int wysokosc, szerokosc;
- int r,g,b;
-
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
-
- for( int i=0; i<wysokosc; i++ )
- {
- RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
- for( int j=0; j<szerokosc; j++ )
- {
- //pobierz sk│adowe RGB
- b = wiersz[j].rgbBlue;
- g = wiersz[j].rgbGreen;
- r = wiersz[j].rgbRed;
-
- r += val;
- g += val;
- b += val;
-
- r = (r>255)?255:(r<0)?0:r;
- b = (b>255)?255:(b<0)?0:b;
- g = (g>255)?255:(g<0)?0:g;
-
- //przejdz do nastΩpnego piksela
- wiersz[j].rgbBlue = (BYTE) b;
- wiersz[j].rgbGreen = (BYTE) g;
- wiersz[j].rgbRed = (BYTE) r;
- }
- }
-
- } //DostosujJasnosc
-
- //
- // Zmiana kontrastu bitmapy bmp o wartosc val
- //
- int DostosujKontrast( Graphics::TBitmap *bmp, int val )
- {
- int wysokosc, szerokosc;
- double v = 1.2725*val;
-
- double v1 = 255/(255-2*v);
- double v2 = (255+2*v)/255;
-
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
-
- for( int i=0; i<wysokosc; i++ )
- {
- RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
- for( int j=0; j<szerokosc; j++ )
- {
- //pobierz sk│adowe RGB
- int b = wiersz[j].rgbBlue;
- int g = wiersz[j].rgbGreen;
- int r = wiersz[j].rgbRed;
-
- //zmodyfikuj sk│adowe r,g,b
- if(v>0)
- {
- r = (r<v)?0:(r>255-v)?255:v1*(r-v);
- g = (g<v)?0:(g>255-v)?255:v1*(g-v);
- b = (b<v)?0:(b>255-v)?255:v1*(b-v);
- }
- else if(v<0)
- {
- r = -v+v2*r;
- g = -v+v2*g;
- b = -v+v2*b;
- }
-
- //sprawdƒ zakresy
- r = (r>255)?255:(r<0)?0:r;
- b = (b>255)?255:(b<0)?0:b;
- g = (g>255)?255:(g<0)?0:g;
-
- //przejdz do nastΩpnego piksela
- wiersz[j].rgbBlue = (BYTE) b;
- wiersz[j].rgbGreen = (BYTE) g;
- wiersz[j].rgbRed = (BYTE) r;
- }
- }
-
- } //DostosujKontrast
-
-
- //
- // Zmiana nasycenia kolor≤w o wartosv val
- //
- int DostosujNasycenie( Graphics::TBitmap *bmp, int val )
- {
- int wysokosc, szerokosc;
- double x = 1.0+val/100.0;
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
-
- for( int i=0; i<wysokosc; i++ )
- {
- RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
- for( int j=0; j<szerokosc; j++ )
- {
- //pobierz sk│adowe RGB
- int b = wiersz[j].rgbBlue;
- int g = wiersz[j].rgbGreen;
- int r = wiersz[j].rgbRed;
-
- int szary = (r+g+b)/3.0;
-
- r = szary + (r-szary)*x;
- g = szary + (g-szary)*x;
- b = szary + (b-szary)*x;
-
- r = (r>255)?255:(r<0)?0:r;
- b = (b>255)?255:(b<0)?0:b;
- g = (g>255)?255:(g<0)?0:g;
-
- //przejdz do nastΩpnego piksela
- wiersz[j].rgbBlue = (BYTE) b;
- wiersz[j].rgbGreen = (BYTE) g;
- wiersz[j].rgbRed = (BYTE) r;
- }
- }
-
- } //DostosujNasycenie
-
- // Przygotuj Miniature
- // funkcja tworzy miniature z obrazka oryginal, zapisuj╣c j╣ w miniatura
- // miniature ma wymiary szerokosc,wysokosc
-
- int PrzygotujMiniature( Graphics::TBitmap *oryginal, Graphics::TBitmap *miniatura,int szerokosc, int wysokosc)
- {
- TMemoryStream *pms = new TMemoryStream;
-
- if( szerokosc>0 && wysokosc>0 )
- {
- pms->Position = 0;
- oryginal->SaveToStream(pms);
- pms->Position = 0;
- miniatura->LoadFromStream( pms );
-
- double skok_wys = oryginal->Height/(double)wysokosc;
- double skok_szer = oryginal->Width/(double)szerokosc;
- miniatura->Width = szerokosc;
- miniatura->Height = wysokosc;
-
- int *wiersz_oryginal,*wiersz_min;
-
- for( int i=0; i<wysokosc; i++)
- {
- wiersz_min = (int *) miniatura->ScanLine[i];
- wiersz_oryginal = (int *) oryginal->ScanLine[ (int)(i*skok_wys) ];
- for( int j=0; j<szerokosc; j++)
- {
- wiersz_min[j] = wiersz_oryginal[ (int)(j*skok_szer) ];
- }
- }
- }
-
- delete pms;
- } //PrzygotujMiniature
-
- //
- // Zmien balans kolorow wg xr, xg i xb, odpowiednio modyfikuj╣cych
- // sk│adowe R, G i B
- //
- int DostosujBalans( Graphics::TBitmap *bmp, int xr, int xg, int xb )
- {
- int wysokosc, szerokosc;
- int r,g,b;
-
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
-
- for( int i=0; i<wysokosc; i++ )
- {
- RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
- for( int j=0; j<szerokosc; j++ )
- {
- //pobierz sk│adowe RGB
- int b = wiersz[j].rgbBlue;
- int g = wiersz[j].rgbGreen;
- int r = wiersz[j].rgbRed;
-
- r += xr;
- g += xg;
- b += xb;
-
- r = (r>255)?255:(r<0)?0:r;
- b = (b>255)?255:(b<0)?0:b;
- g = (g>255)?255:(g<0)?0:g;
-
- //przejdz do nastΩpnego piksela
- wiersz[j].rgbBlue = (BYTE) b;
- wiersz[j].rgbGreen = (BYTE) g;
- wiersz[j].rgbRed = (BYTE) r;
- }
- }
-
- } //DostosujBalans
-
- //
- // Przeksztalc bitmapΩ bmp na jej negatyw
- //
- int Negatyw( Graphics::TBitmap *bmp)
- {
- int wysokosc, szerokosc;
-
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
-
- for( int i=0; i<wysokosc; i++ )
- {
- RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
- for( int j=0; j<szerokosc; j++ )
- {
- // tutaj uzyty jest operator negacji bitowej!
- wiersz[j].rgbBlue = ~wiersz[j].rgbBlue;
- wiersz[j].rgbGreen = ~wiersz[j].rgbGreen;
- wiersz[j].rgbRed = ~wiersz[j].rgbRed;
- }
- }
-
- }//Negatyw
-
- //
- // zmien bitmapΩ bmp na obraz w odcieniach szarosci
- //
- int OdcienieSzarosci( Graphics::TBitmap *bmp)
- {
- int wysokosc, szerokosc;
- int szary;
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
-
- for( int i=0; i<wysokosc; i++ )
- {
- RGBQUAD *wiersz = (RGBQUAD *) bmp->ScanLine[i];
- for( int j=0; j<szerokosc; j++ )
- {
- // oblicz poziom szarosci piksela
- szary = (wiersz[j].rgbBlue+wiersz[j].rgbGreen+wiersz[j].rgbRed)/3;
- // podstaw t╣ sam╣ wartosc dla wszystkich skladowych
- wiersz[j].rgbBlue = szary;
- wiersz[j].rgbGreen = szary;
- wiersz[j].rgbRed = szary;
- }
- }
-
- }//OdcienieSzarosci
-
-
- //
- // Filtr3x3 przektsztalca bitmape bmp wg filtru filtr[3][3] i zapisuje
- // wynik w outbmp
- //
- int Filtr3x3( Graphics::TBitmap *bmp, Graphics::TBitmap *outbmp, double filtr[3][3] )
- {
- int wysokosc, szerokosc;
- int i,j;
- RGBQUAD *piksel[3];
-
- wysokosc = bmp->Height;
- szerokosc = bmp->Width;
- //outbmp->Width = szerokosc;
- //outbmp->Height = szerokosc;
-
- double suma = 0;
-
- // oblicz sume elementow tablicy filtru
- for( i=0; i<3; i++)
- for( j=0; j<3; j++)
- suma += filtr[i][j];
-
-
- for( i=0; i<wysokosc; i++ )
- {
- // *wiersz to wskaznik do WYJSCIOWEJ bitmapy
- RGBQUAD *wiersz = (RGBQUAD *) outbmp->ScanLine[i];
-
- // pobierz piksel i jego s╣siad≤w
- // zwracaj╣c uwagΩ na przekroczenie granic obrazka
- // *piksel wksazuje na elementy WEJSCIOWEJ bitmapy
-
- piksel[1] = (RGBQUAD *) bmp->ScanLine[i];
- if(i>0)
- piksel[0] = (RGBQUAD *) bmp->ScanLine[i-1];
- else
- piksel[0] = piksel[1];
-
- if(i<wysokosc-1)
- piksel[2] = (RGBQUAD *) bmp->ScanLine[i+1];
- else
- piksel[2] = piksel[1];
-
-
- for( j=0; j<szerokosc; j++ )
- {
- double b = 0;
- double g = 0;
- double r = 0;
-
- //oblicz wynikow╣ wartosc skladowych r,g,b po zastosowaniu filtru
- for( int k=0; k<3 ; k++ )
- for( int l=0; l<3 ; l++ )
- {
- if(j==0&&k==0)
- {
- r += filtr[k][l]*piksel[l][0].rgbRed;
- g += filtr[k][l]*piksel[l][0].rgbGreen;
- b += filtr[k][l]*piksel[l][0].rgbBlue;
- }
- else if(j==szerokosc-1&&k==2)
- {
- r += filtr[k][l]*piksel[l][j].rgbRed;
- g += filtr[k][l]*piksel[l][j].rgbGreen;
- b += filtr[k][l]*piksel[l][j].rgbBlue;
- }
- else
- {
- r += filtr[k][l]*piksel[l][j-1+k].rgbRed;
- g += filtr[k][l]*piksel[l][j-1+k].rgbGreen;
- b += filtr[k][l]*piksel[l][j-1+k].rgbBlue;
- }
- }
- if( suma!=0 )
- {
- r /= suma;
- g /= suma;
- b /= suma;
- }
-
- //sprawdz zakresy
- r = (r>255)?255:(r<0)?0:r;
- b = (b>255)?255:(b<0)?0:b;
- g = (g>255)?255:(g<0)?0:g;
-
- //zapisz w WYJSCIOWEJ bitmapie
- wiersz[j].rgbBlue = (BYTE) b;
- wiersz[j].rgbGreen = (BYTE) g;
- wiersz[j].rgbRed = (BYTE) r;
- }
- }
-
- } //DostosujBalans
-