Nadesłany przez Tomasz Lubiński, 27 listopada 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
YUV - C++/Unit1.cpp:
// Model YUV // www.algorytm.org // (c)2007 by Tomasz Lubinski //--------------------------------------------------------------------------- #include <vcl.h> #include "math.h" #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } void YUV2RGB(double y, double u, double v, double &r, double &g, double &b) { r = 1*y + 0*u + 1.13983*v; g = 1*y -0.39465*u + -0.58060*v; b = 1*y + 2.03211*u + 0*v; if (r>1) r =1; if (g>1) g =1; if (b>1) b =1; if (r<0) r =0; if (g<0) g =0; if (b<0) b =0; } void RGB2YUV(double &y, double &u, double &v, double r, double g, double b) { y = 0.299*r + 0.587*g + 0.114*b; u = 0.493*(b - y); v = 0.877*(r - y); } void __fastcall TForm1::Button1Click(TObject *Sender) { double r,g,b,y,u,v; int step, width, shift_x, shift_y; int side, side_sign; Model->Canvas->Brush->Color = clWhite; Model->Canvas->Rectangle(0, 0, Model->Width, Model->Height); width = StrToInt(Width->Text); shift_x = Model->Width / 2 - width / 1.5; shift_y = width * 1.5 + 50; if (black->Checked) { side = 0; side_sign = -1; } else { side = 1; side_sign = 1; } for (int i=0; i<width; i++) { for (int j=0; j<width; j++) { y = side; u = (0.436 - (0.872/width)*i)*side_sign; v = (0.615 - (1.23/width)*j)*side_sign; YUV2RGB(y, u, v, r, g, b); if (i==0 || j==0 || j == width -1) { g = 0; b= 0; r = 0; } Model->Canvas->Pixels[i+shift_x][shift_y-j] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } for (int i=0; i<width; i++) { for (int j=0; j<width/2; j++) { y = (side - j/(width/2.0))*side_sign; u = (0.436 - (0.872/width)*i)*side_sign; v = (-0.615)*side_sign; YUV2RGB(y, u, v, r, g, b); if (i==0 || i == width-1 || j == width/2 -1) { b= 0; g = 0; r = 0; } Model->Canvas->Pixels[i+j+shift_x][shift_y-j-width] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } for (int i=0; i<width/2; i++) { for (int j=0; j<width; j++) { y = (side - i/(width/2.0))*side_sign; u = (-0.436)*side_sign; v = (0.615 - (1.23/width)*j)*side_sign; YUV2RGB(y, u, v, r, g, b); if (i==0 || j==0 || i == width/2-1) { b= 0; g = 0; r = 0; } Model->Canvas->Pixels[i+shift_x+width][shift_y-j-i-1] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } Model->Canvas->MoveTo(shift_x, shift_y + 20); Model->Canvas->LineTo(shift_x + width, shift_y + 20); Model->Canvas->LineTo(shift_x + width - 5, shift_y + 15); Model->Canvas->MoveTo(shift_x + width, shift_y + 20); Model->Canvas->LineTo(shift_x + width - 5, shift_y + 25); Model->Canvas->TextOutA(shift_x + 10, shift_y + 7, "U"); Model->Canvas->MoveTo(shift_x - 20, shift_y); Model->Canvas->LineTo(shift_x - 20, shift_y - width); Model->Canvas->LineTo(shift_x - 25, shift_y - width + 5); Model->Canvas->MoveTo(shift_x - 20, shift_y - width); Model->Canvas->LineTo(shift_x - 15, shift_y - width + 5); Model->Canvas->TextOutA(shift_x - 15, shift_y - 20, "V"); Model->Canvas->MoveTo(shift_x + width + 2, shift_y + 18); Model->Canvas->LineTo(shift_x + width * 1.5 + 2, shift_y + 18 - width / 2); Model->Canvas->LineTo(shift_x + width * 1.5 - 5, shift_y + 18 - width / 2); Model->Canvas->MoveTo(shift_x + width * 1.5 + 2, shift_y + 18 - width / 2); Model->Canvas->LineTo(shift_x + width * 1.5 + 2, shift_y + 25 - width / 2); Model->Canvas->TextOutA(shift_x + width + 10, shift_y - 10, "Y"); Model->Refresh(); } //--------------------------------------------------------------------------- void __fastcall TForm1::YButtonClick(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::UButtonClick(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::VButtonClick(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::ReDrawProbe(TObject *Sender) { double y, u, v, r, g, b; Byte *P; y = StrToFloat(Y->Text); u = StrToFloat(U->Text); v = StrToFloat(V->Text); ProbeSmall->Canvas->Brush->Color = clWhite; ProbeSmall->Canvas->Rectangle(0, 0, ProbeSmall->Width, ProbeSmall->Height); ProbeSmall->Picture->Bitmap->PixelFormat = pf32bit; if (YButton->Checked) { for (int i=0; i<256; i++) { y = 1 - i/255.0; YUV2RGB(y, u, v, r, g, b); P = (Byte *)ProbeSmall->Picture->Bitmap->ScanLine[i]; for (int j=0; j<ProbeSmall->Picture->Bitmap->Width; j++) { *P = (Byte)(b*255); P++; *P = (Byte)(g*255); P++; *P = (Byte)(r*255); P++; P++; } } } else if (UButton->Checked) { for (int i=0; i<256; i++) { u = 0.436 - i/292.43; YUV2RGB(y, u, v, r, g, b); P = (Byte *)ProbeSmall->Picture->Bitmap->ScanLine[i]; for (int j=0; j<ProbeSmall->Picture->Bitmap->Width; j++) { *P = (Byte)(b*255); P++; *P = (Byte)(g*255); P++; *P = (Byte)(r*255); P++; P++; } } } else if (VButton->Checked) { for (int i=0; i<256; i++) { v = 0.615 - i/207.31; YUV2RGB(y, u, v, r, g, b); P = (Byte *)ProbeSmall->Picture->Bitmap->ScanLine[i]; for (int j=0; j<ProbeSmall->Picture->Bitmap->Width; j++) { *P = (Byte)(b*255); P++; *P = (Byte)(g*255); P++; *P = (Byte)(r*255); P++; P++; } } } y = StrToFloat(Y->Text); u = StrToFloat(U->Text); v = StrToFloat(V->Text); ProbeLarge->Canvas->Brush->Color = clWhite; ProbeLarge->Canvas->Rectangle(0, 0, ProbeLarge->Width, ProbeLarge->Height); ProbeLarge->Picture->Bitmap->PixelFormat = pf32bit; if (YButton->Checked) { for (int j=0; j<256; j++) { P = (Byte *)ProbeLarge->Picture->Bitmap->ScanLine[255-j]; for (int i=0; i<256; i++) { u = i/292.43 - 0.436; v = j/207.31 - 0.615; YUV2RGB(y, u, v, r, g, b); *P = (Byte)(b*255); P++; *P = (Byte)(g*255); P++; *P = (Byte)(r*255); P++; P++; } } } else if (UButton->Checked) { for (int j=0; j<256; j++) { P = (Byte *)ProbeLarge->Picture->Bitmap->ScanLine[255-j]; for (int i=0; i<256; i++) { y = i/255.0; v = j/207.31 - 0.615; YUV2RGB(y, u, v, r, g, b); *P = (Byte)(b*255); P++; *P = (Byte)(g*255); P++; *P = (Byte)(r*255); P++; P++; } } } else if (VButton->Checked) { for (int j=0; j<256; j++) { P = (Byte *)ProbeLarge->Picture->Bitmap->ScanLine[255-j]; for (int i=0; i<256; i++) { y = i/255.0; u = j/292.43 - 0.436; YUV2RGB(y, u, v, r, g, b); *P = (Byte)(b*255); P++; *P = (Byte)(g*255); P++; *P = (Byte)(r*255); P++; P++; } } } ReDrawRectangle(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::ReDrawRectangle(TObject *Sender) { double y, u, v, r, g, b; y = StrToFloat(Y->Text); u = StrToFloat(U->Text); v = StrToFloat(V->Text); YUV2RGB(y, u, v, r, g, b); Probe->Canvas->Brush->Color = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); Probe->Canvas->Rectangle(0, 0, Probe->Width, Probe->Height); if (YButton->Checked) { ProbeSmall->Canvas->Ellipse(5, (1-y)*255-3, 13, (1-y)*255+3); ProbeLarge->Canvas->Ellipse((u+0.436)*292.43-3, (0.615-v)*207.31-3, (u+0.436)*292.43+3, (0.615-v)*207.31+3); } else if (UButton->Checked) { ProbeSmall->Canvas->Ellipse(5, (0.436-u)*292.43-3, 13, (0.436-u)*292.43+3); ProbeLarge->Canvas->Ellipse(y*255-3, (0.615-v)*207.31-3, y*255+3, (0.615-v)*207.31+3); } else if (VButton->Checked) { ProbeSmall->Canvas->Ellipse(5, (0.615-v)*207.31-3, 13, (0.615-v)*207.31+3); ProbeLarge->Canvas->Ellipse(y*255-3, (0.436-u)*292.43-3, y*255+3, (0.436-u)*292.43+3); } } //--------------------------------------------------------------------------- void __fastcall TForm1::YChange(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::UChange(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::VChange(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::ProbeLargeMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (YButton->Checked) { this->U->Text = FloatToStr(X/292.43 - 0.436); this->V->Text = FloatToStr(0.615 - Y/207.31); } else if (UButton->Checked) { this->Y->Text = FloatToStr(X/255.0); this->V->Text = FloatToStr(0.615 - Y/207.31); } else if (VButton->Checked) { this->Y->Text = FloatToStr(X/255.0); this->U->Text = FloatToStr(0.436 - Y/292.43); } } //--------------------------------------------------------------------------- void __fastcall TForm1::ProbeSmallMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (YButton->Checked) { this->Y->Text = FloatToStr(1 - Y/255.0); } else if (UButton->Checked) { this->U->Text = FloatToStr(0.436 - Y/292.43); } else if (VButton->Checked) { this->V->Text = FloatToStr(0.615 - Y/207.31); } } //--------------------------------------------------------------------------- void __fastcall TForm1::FormActivate(TObject *Sender) { ReDrawProbe(Sender); Button1Click(Sender); Layers(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Layers() { double r, g, b, y, u, v; TColor color; for (int i=0; i<AllLayers->Width; i++) { for (int j=0; j<AllLayers->Height; j++) { color = AllLayers->Canvas->Pixels[i][j]; r = (color & 0xFF) / 255.0; g = ((color & 0xFF00) >> 8) / 255.0; b = ((color & 0xFF0000) >> 16) / 255.0; RGB2YUV(y, u, v, r, g, b); YUV2RGB(y, 0, 0, r, g, b); LayerY->Canvas->Pixels[i][j] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); YUV2RGB(0, u, 0, r, g, b); LayerU->Canvas->Pixels[i][j] = (TColor)((int)(255 - (u+0.416)*306) << 8) + ((int)((u+0.416)*306) << 16); YUV2RGB(0, 0, v, r, g, b); LayerV->Canvas->Pixels[i][j] = (TColor)((v+0.615)*207) + ((int)(255 - (v+0.615)*207) << 8); } } } //---------------------------------------------------------------------------