algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Model HSV - Implementacja w C/C++
Ocena użytkownikóww: *****  / 3
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 05 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.

HSV - C++/Unit1.cpp:
// Model HSV
// 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"

#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void HSV2RGB(float hue, float sat, float val, float &red, float &grn, float &blu)
{
int i;
float f, p, q, t;
if(val==0) {red=0; grn=0; val=0;}
else{
 hue/=60;
 i = floor(hue);
 f = hue-i;
 p = val*(1-sat);
 q = val*(1-(sat*f));
 t = val*(1-(sat*(1-f)));
 if (i==0) {red=val; grn=t; blu=p;}
 else if (i==1) {red=q; grn=val; blu=p;}
 else if (i==2) {red=p; grn=val; blu=t;}
 else if (i==3) {red=p; grn=q; blu=val;}
 else if (i==4) {red=t; grn=p; blu=val;}
 else if (i==5) {red=val; grn=p; blu=q;}
}
}

void RGB2HSV(float &hue, float &sat, float &val, float red, float grn, float blu){
        float x, f, i;

        x = MIN(MIN(red, grn), blu);
        val = MAX(MAX(red, grn), blu);
        if (x == val){
                hue = 0;
                sat = 0;
        }
        else {
                f = (red == x) ? grn-blu : ((grn == x) ? blu-red : red-grn);
                i = (red == x) ? 3 : ((grn == x) ? 5 : 1);
                hue = fmod((i-f/(val-x))*60, 360);
                sat = ((val-x)/val);
        }
}

void __fastcall TForm1::DrawArc(float x, float y, float r1, float s, float v, int shift)
{
        float h, r, g, b, r2;
        float incr = 45 / r1;

        r2 = r1 / 3.0;
        for (float i=180; i<360; i+=incr)
        {
                h = fmod(i + shift, 360);
                HSV2RGB(h, s, v, r, g, b);
                Model->Canvas->Pixels[r1*cos(i*M_PI/180)+x][-r2*sin(i*M_PI/180)+y] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
        }
}

void __fastcall TForm1::FillCircle(float x, float y, float maxr, int shift)
{
        float h, s, v, r, g, b, r1, r2;
        float incr;

        for (float j=1; j<maxr; j++)
        {
                r1 = j;
                r2 = r1 / 3.0;
                s = j / (maxr);
                v = 1;
                incr = 45 / r1;

                for (float i=0; i<360; i+=incr)
                {
                        h = fmod(i + shift, 360);
                        HSV2RGB(h, s, v, r, g, b);
                        Model->Canvas->Pixels[r1*cos(i*M_PI/180)+x][-r2*sin(i*M_PI/180)+y] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
                }
        }
}


void __fastcall TForm1::Button1Click(TObject *Sender)
{
   float h,s,v,r,g,b,step;
   int width, height, shift, shift_x, shift_y;
   float r1, r2;
   float incr;

   Model->Canvas->Brush->Color = clWhite;
   Model->Canvas->Rectangle(0, 0, Model->Width, Model->Height);

   width = StrToInt(Width->Text);
   height = StrToInt(Height->Text);
   shift = StrToInt(Shift->Text);

   shift_x = Model->Width / 2;
   shift_y = 50;

   step = (width*1.0)/height;
   for (float k=height-1; k>=0; k--)
   {
        s = 1.0 - (1 / (width - (step*k)));
        v = 1 - (k / height);

        DrawArc(shift_x, shift_y + k, width - (step*k), s, v, shift);
   }

   FillCircle(shift_x, shift_y,  width, shift);

   //draw H, S and V crosses
   r1 = width;
   r2 = r1 / 3.0;
   shift_y -= 10;
   incr = 45 / r1;
   for (float i=0; i<270; i+=incr)
   {
      Model->Canvas->Pixels[r1*cos(i*M_PI/180)+shift_x][-r2*sin(i*M_PI/180)+shift_y] = (TColor)(int)0;
   }
   Model->Canvas->MoveTo(r1*cos(270*M_PI/180)+shift_x, -r2*sin(270*M_PI/180)+shift_y);
   Model->Canvas->LineTo(r1*cos(270*M_PI/180)+shift_x-5, -r2*sin(270*M_PI/180)+shift_y-5);
   Model->Canvas->MoveTo(r1*cos(270*M_PI/180)+shift_x, -r2*sin(270*M_PI/180)+shift_y);
   Model->Canvas->LineTo(r1*cos(270*M_PI/180)+shift_x-5, -r2*sin(270*M_PI/180)+shift_y+5);
   Model->Canvas->TextOutA(r1*cos(140*M_PI/180)+shift_x-30, -r2*sin(140*M_PI/180)+shift_y+5, "H");

   Model->Canvas->MoveTo(shift_x - r1 - 10, shift_y + r2/2 + height);
   Model->Canvas->LineTo(shift_x - r1 - 10, shift_y + r2/2);
   Model->Canvas->LineTo(shift_x - r1 - 15, shift_y + r2/2 + 5);
   Model->Canvas->MoveTo(shift_x - r1 - 10, shift_y + r2/2);
   Model->Canvas->LineTo(shift_x - r1 - 5, shift_y + r2/2 + 5);
   Model->Canvas->TextOutA(shift_x - r1 - 20, shift_y + r2/2 + 15, "V");

   Model->Canvas->MoveTo(shift_x, shift_y + r2/2 + height);
   Model->Canvas->LineTo(shift_x - r1, shift_y + r2/2 + height);
   Model->Canvas->LineTo(shift_x - r1 + 5, shift_y + r2/2 + height - 5);
   Model->Canvas->MoveTo(shift_x - r1, shift_y + r2/2 + height);
   Model->Canvas->LineTo(shift_x - r1 + 5, shift_y + r2/2 + height + 5);
   Model->Canvas->TextOutA(shift_x - r1 + 15, shift_y + r2/2 + height - 15, "S");


   Model->Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   for (int i=0; i<=360; i+=10)
   {
      Shift->Text = IntToStr(i);
      Button1Click(Sender);
   }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::HButtonClick(TObject *Sender)
{
        ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SButtonClick(TObject *Sender)
{
        ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::VButtonClick(TObject *Sender)
{
        ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ReDrawProbe(TObject *Sender)
{
   float h, s, v, r, g, b;
   h = StrToInt(H->Text);
   s = StrToInt(S->Text) / 100.0;
   v = StrToInt(V->Text) / 100.0;

   ProbeSmall->Canvas->Brush->Color = clWhite;
   ProbeSmall->Canvas->Rectangle(0, 0, ProbeSmall->Width, ProbeSmall->Height);

   if (HButton->Checked)
   {
      s = 1;
      v = 1;
      for (int i=0; i<256; i++)
      {
         h = (i * 359.0) / 255;
         HSV2RGB(h, s, v, r, g, b);
         ProbeSmall->Canvas->Pixels[1][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[2][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[3][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[4][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[5][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[6][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[7][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[8][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[9][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[10][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[11][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[12][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[13][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[14][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[15][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }
   else if (SButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         s = i / 255.0;
         HSV2RGB(h, s, v, r, g, b);
         ProbeSmall->Canvas->Pixels[1][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[2][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[3][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[4][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[5][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[6][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[7][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[8][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[9][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[10][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[11][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[12][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[13][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[14][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[15][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }
   else if (VButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         v = i / 255.0;
         HSV2RGB(h, s, v, r, g, b);
         ProbeSmall->Canvas->Pixels[1][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[2][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[3][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[4][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[5][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[6][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[7][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[8][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[9][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[10][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[11][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[12][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[13][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[14][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         ProbeSmall->Canvas->Pixels[15][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }

   h = StrToInt(H->Text);
   s = StrToInt(S->Text) / 100.0;
   v = StrToInt(V->Text) / 100.0;

   ProbeLarge->Canvas->Brush->Color = clWhite;
   ProbeLarge->Canvas->Rectangle(0, 0, ProbeLarge->Width, ProbeLarge->Height);

   if (HButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         for (int j=0; j<256; j++)
         {
            s = i / 255.0;
            v = j / 255.0;
            HSV2RGB(h, s, v, r, g, b);
            ProbeLarge->Canvas->Pixels[i][255-j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         }
      }
   }
   else if (SButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         for (int j=0; j<256; j++)
         {
            h = (i * 359.0) / 255;
            v = j / 255.0;
            HSV2RGB(h, s, v, r, g, b);
            ProbeLarge->Canvas->Pixels[i][255-j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         }
      }
   }
   else if (VButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         for (int j=0; j<256; j++)
         {
            h = (i * 359.0) / 255;
            s = j / 255.0;
            HSV2RGB(h, s, v, r, g, b);
            ProbeLarge->Canvas->Pixels[i][255-j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
         }
      }
   }

   ReDrawRectangle(Sender);
}

//---------------------------------------------------------------------------
void __fastcall TForm1::ReDrawRectangle(TObject *Sender)
{
   float h, s, v, r, g, b;
   h = StrToInt(H->Text);
   s = StrToInt(S->Text) / 100.0;
   v = StrToInt(V->Text) / 100.0;
   HSV2RGB(h, s, v, r, g, b);
   Probe->Canvas->Brush->Color = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
   Probe->Canvas->Rectangle(0, 0, Probe->Width, Probe->Height);

   if (HButton->Checked)
   {
      ProbeSmall->Canvas->Ellipse(5, h*255/359-3, 13, h*255/359+3);
      ProbeLarge->Canvas->Ellipse(s*255-3, 255-v*255-3, s*255+3, 255-v*255+3);
   }
   else if (SButton->Checked)
   {
      ProbeSmall->Canvas->Ellipse(5, s*255-3, 13, s*255+3);
      ProbeLarge->Canvas->Ellipse(h*255/359-3, 255-v*255-3, h*255/359+3, 255-v*255+3);
   }
   else if (VButton->Checked)
   {
      ProbeSmall->Canvas->Ellipse(5, v*255-3, 13, v*255+3);
      ProbeLarge->Canvas->Ellipse(h*255/359-3, 255-s*255-3, h*255/359+3, 255-s*255+3);
   }
}

//---------------------------------------------------------------------------
void __fastcall TForm1::HChange(TObject *Sender)
{
   ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SChange(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 (HButton->Checked)
   {
      S->Text = IntToStr((X*100)/255);
      V->Text = IntToStr(100-(Y*100)/255);
   }
   else if (SButton->Checked)
   {
      H->Text = IntToStr((X*359)/255);
      V->Text = IntToStr(100-(Y*100)/255);
   }
   else if (VButton->Checked)
   {
      H->Text = IntToStr((X*359)/255);
      S->Text = IntToStr(100-(Y*100)/255);
   }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ProbeSmallMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
   if (HButton->Checked)
   {
      H->Text = IntToStr((Y*359)/255);
   }
   else if (SButton->Checked)
   {
      S->Text = IntToStr((Y*100)/255);
   }
   else if (VButton->Checked)
   {
      V->Text = IntToStr((Y*100)/255);
   }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormActivate(TObject *Sender)
{
ReDrawProbe(Sender);
Button1Click(Sender);
Layers();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Layers()
{
   float r, g, b, h, s, 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;
          RGB2HSV(h, s, v, r, g, b);
          HSV2RGB(h, 1, 1, r, g, b);
          LayerH->Canvas->Pixels[i][j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
          HSV2RGB(0, s, 1, r, g, b);
          LayerS->Canvas->Pixels[i][j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
          HSV2RGB(0, 0, v, r, g, b);
          LayerV->Canvas->Pixels[i][j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }
}
Dodaj komentarz