Gradient

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Gradient

Nowy postprzez Corvis » środa, 9 grudnia 2009, 12:39

Witam,

Napisałem znalazłem i przerobiłem funkcję która rysuje gradient

Kod: Zaznacz cały
void TForm1::GradVertical(TCanvas *Canvas, TRect Rect, TColor FromColor, TColor ToColor) {
  int Y;
  double dr,dg,db;
  TColor C1,C2;
  int r1,r2,g1,g2,b1,b2;
  int R,G,B;
  double cnt;
   
   C1 = FromColor;
   
   r1 = GetRValue(C1) ;
   g1 = GetGValue(C1) ;
   b1 = GetBValue(C1) ;

   C2  = ToColor;
   
   r2 = GetRValue(C2) ;
   g2 = GetGValue(C2) ;
   b2 = GetBValue(C2) ;

   dr = double(r2-r1) / Rect.Bottom-Rect.Top;
   dg = double(g2-g1) / Rect.Bottom-Rect.Top;
   db = double(b2-b1) / Rect.Bottom-Rect.Top;

   cnt = 0;
   for(Y=Rect.top; Y<Rect.Bottom-1;++Y) {
      R = r1+dr*(cnt) ;
      G = g1+dg*(cnt) ;
      B = b1+db*(cnt) ;

      Canvas->Pen->Color = RGB(R,G,B) ;
      Canvas->MoveTo(Rect.Left,Y) ;
      Canvas->LineTo(Rect.Right,Y) ;
      cnt+=1;
   }
}



Efektem jej dzialania jest gradient ale jak by skrócony ( wynik w załączniku )

Paleta kolorów na górze pokazuje jak aktualnie to działa Paleta kolorów na dole pokazuje jaki efekt bym chciał uzyskać. Spotkał się ktoś kiedyś z takim problem ??

Może ma ktoś jakis pomysł jak to rozwiązać ??

Pozdrawiam
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez polymorphism » środa, 9 grudnia 2009, 13:39

Zrób tak: 255,0,0 -> 255,0,255 -> 0,0,255 -> 0,255,255 -> 0,255,0 -> itd... (R,G,B). W zasadzie to pierwsze 2 przejścia ( -> ) ciebie interesują...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » środa, 9 grudnia 2009, 14:12

Sorry, ale nie bardzo kumam chodzi ci na sztywno tak pętle ustawić, żeby wyszła taka sekwencja jak piszesz ??
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez polymorphism » środa, 9 grudnia 2009, 15:32

Pokazałem Ci przedziały kolorów, które powinny dać efekt, o którym pisałeś. A czy na sztywno? Nie wiem. Nie wiem jakie to ma mieć zastosowanie. Jeśli to ma być funkcja, która wypełnia pole zwykłym gradientem, to nie ma co kombinować - tak jak masz jest dobrze.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » środa, 9 grudnia 2009, 15:57

Dokładnie to ma być wykres 3d i są co do niego wymagania ( przejścia kolorów jak na rysunku )

Dzięki pokombinuje coś jeszcze będzie jazda żeby gradientem wypełnić coś innego niż prostokąt a np. dowolny kształt 4 punktowy. ;D
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez polymorphism » środa, 9 grudnia 2009, 16:13

Corvis napisał(a):będzie jazda żeby gradientem wypełnić coś innego niż prostokąt a np. dowolny kształt 4 punktowy. ;D

Paths + Regiony?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » czwartek, 10 grudnia 2009, 09:26

Dzięki za odp,

Masz może jakiś przypład użycia lub przykadł wypełnienia gradientem jakiegoś kształtu ( tylko nie prostokąta ;) ) ? Bo nie mogę znaleść.

pozdrawiam
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez polymorphism » czwartek, 10 grudnia 2009, 11:42

Tu masz przykład wypełnienia elipsy:
Kod: Zaznacz cały
if(BeginPath(hdc))
{
   Ellipse(hdc,100,100,500,200);

   if(EndPath(hdc) && SelectClipPath(hdc,RGN_COPY))
   {
      TRIVERTEX      trivert[2];
      GRADIENT_RECT   grad_rect;

      trivert [0] .x      = 100;
      trivert [0] .y      = 100;
      trivert [0] .Red    = 0xff00;
      trivert [0] .Green  = 0;
      trivert [0] .Blue   = 0;
      trivert [0] .Alpha  = 0;

      trivert [1] .x      = 500;
      trivert [1] .y      = 200;
      trivert [1] .Red    = 0;
      trivert [1] .Green  = 0;
      trivert [1] .Blue   = 0xff00;
      trivert [1] .Alpha  = 0;

      grad_rect.UpperLeft  = 0;
      grad_rect.LowerRight = 1;
      GradientFill(hdc, trivert,2,&grad_rect,1,GRADIENT_FILL_RECT_V);
   }
}

Do wypełnienia gradientem użyłem systemowej GradientFill, ale równie dobrze możesz użyć własnej funkcji (choć nie wiem czy jest sens), bylebyś nie zmieniał przypisanego kontekstowi regionu.

Oczywiście zamiast Ellipse możesz użyć innych funkcji rysujących, po szczegóły odsyłam do PSDK. Przy opisie BeginPath będziesz miał listę dopuszczalnych funkcji.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Corvis
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Cyfrowy Baron » czwartek, 10 grudnia 2009, 11:54

Może powinieneś zapoznać się bliżej z GDI+.
► patrz serwis: Cyfrowy Baron dział: porady -> grafika -> Wyświetlanie grafiki z wykorzystaniem biblioteki gdiplus.dll GDI+.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » czwartek, 10 grudnia 2009, 14:08

Wielkie dzięki :)
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » czwartek, 10 grudnia 2009, 16:37

Wymiękłem z tymi gradientami. Próbowałem na różne sposoby zrobić to ale nie działa.

Musze wypełnić obszar podobny do tego na rysunku gradientem ale nie tym standardowym tylko tym 2 co podałem na rysunku. Widział ktoś może kiedyś jakąś funkcję API która może to zrobić ??

Z góry sorry za tyle pytań ale nigdy z grafiką nie byłem zaprzyjaźniony :\
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez polymorphism » czwartek, 10 grudnia 2009, 17:14

Próbowałeś z tymi przedziałami, które podałem?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » piątek, 11 grudnia 2009, 10:14

Robię to tak:

Kod: Zaznacz cały
  HDC hdc = GetDC(Handle);   
    if(BeginPath(hdc))
    {
        TPoint pkt[4];

        pkt[0].x = 0;
        pkt[0].y = 100;

        pkt[1].x = 50;
        pkt[2].y = 20;

        pkt[1].x = 100;
        pkt[2].y = 40;
     
   
        Polygon(hdc,pkt,3);

       if(EndPath(hdc) && SelectClipPath(hdc,RGN_COPY)) {
          TRIVERTEX      trivert[3];
          GRADIENT_RECT   grad_rect;

          trivert [0] .x      = 0;
          trivert [0] .y      = 150;
     
          trivert [0] .Red    = 0x0FF00;
          trivert [0] .Green  = 0;
          trivert [0] .Blue   = 0;
          trivert [0] .Alpha  = 0;

          trivert [1] .x      = 50;
          trivert [1] .y      = 20;
     
          trivert [1] .Red    = 0;
          trivert [1] .Green  = 0x0FF00;
          trivert [1] .Blue   = 0;
          trivert [1] .Alpha  = 0;


          trivert [2] .x      = 80;
          trivert [2] .y      = 130;
     
          trivert [2] .Red    = 0;
          trivert [2] .Green  = 0;
          trivert [2] .Blue   = 0x0FF00;
          trivert [2] .Alpha  = 0;


          grad_rect.UpperLeft  = 1;
          grad_rect.LowerRight = 0;
     
          GradientFill(hdc, trivert,3,&grad_rect,1,GRADIENT_FILL_RECT_V);
           
       }
    }


Powinien przejść przez 3 kolory a nie przechodzi


Ps. ZNalazłem właśnie takie coś

http://www.flounder.com/gradientfiller.htm


gdzie wsio jest bardzo ładnie opisane cały proces jest dośc skomplikowany ale jest do zrobienia :)
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez polymorphism » piątek, 11 grudnia 2009, 10:56

Jesteś pewny, że to jest dobrze?
Kod: Zaznacz cały
pkt[1].x = 50;
pkt[2].y = 20;
pkt[1].x = 100;
pkt[2].y = 40;




Funkcją GradientFill raczej nie da się zrobić dwóch gradientów jednym wywołaniem, trzeba je robić po kolei:
Kod: Zaznacz cały
if(BeginPath(hdc))
{
   POINT pkt[5] = {{100,300},{200,100},{300,400},{200,250},{100,300}};
   Polygon(hdc,pkt,5);

   if(EndPath(hdc) && SelectClipPath(hdc,RGN_COPY))
   {
      TRIVERTEX      trivert[2];
      GRADIENT_RECT   grad_rect;

      grad_rect.UpperLeft  = 0;
      grad_rect.LowerRight = 1;

      trivert [0] .x      = 100;
      trivert [0] .y      = 100;
      trivert [0] .Red    = 0xffff;
      trivert [0] .Green  = 0;
      trivert [0] .Blue   = 0;
      trivert [0] .Alpha  = 0;

      trivert [1] .x      = 500;
      trivert [1] .y      = 250;
      trivert [1] .Red    = 0xffff;
      trivert [1] .Green  = 0;
      trivert [1] .Blue   = 0xffff;
      trivert [1] .Alpha  = 0;

      GradientFill(hdc, trivert,2,&grad_rect,1,GRADIENT_FILL_RECT_V);

      trivert [0] .x      = 100;
      trivert [0] .y      = 250;
      trivert [0] .Red    = 0xffff;
      trivert [0] .Green  = 0;
      trivert [0] .Blue   = 0xffff;
      trivert [0] .Alpha  = 0;

      trivert [1] .x      = 500;
      trivert [1] .y      = 400;
      trivert [1] .Red    = 0;
      trivert [1] .Green  = 0;
      trivert [1] .Blue   = 0xffff;
      trivert [1] .Alpha  = 0;

      GradientFill(hdc, trivert,2,&grad_rect,1,GRADIENT_FILL_RECT_V);
   }
}
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Corvis
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Gradient

Nowy postprzez Corvis » piątek, 11 grudnia 2009, 11:00

Faktycznie :D Dzięki jak skończe wkleje jak to wsio wygląda :)


Mam jeszcze jedno pytanie. Wiesz może jak skopiować to co narysowane jest na HDC na Canvasa ???

EDIT: ZNALAZŁEM ROZWIĄZANIE :

Kod: Zaznacz cały
    HDC hdc = GetDC(Form1->Handle);   
    if(BeginPath(hdc)) {
        POINT pkt[4] = {{100,300},{200,100},{300,400},{200,250}};
        Polygon(hdc,pkt,4);

        if(EndPath(hdc) && SelectClipPath(hdc,RGN_COPY)) {
            TRIVERTEX      trivert[2];
            GRADIENT_RECT   grad_rect;

            grad_rect.UpperLeft  = 0;
            grad_rect.LowerRight = 1;

            trivert [0] .x      = 100;
            trivert [0] .y      = 100;
            trivert [0] .Red    = 255<<8;
            trivert [0] .Green  = 0;
            trivert [0] .Blue   = 0;
 

            trivert [1] .x      = 500;
            trivert [1] .y      = 250;
           
            trivert [1] .Red    = 0;
            trivert [1] .Green  = 255<<8;
            trivert [1] .Blue   = 0;
         

            GradientFill(hdc, trivert,2,&grad_rect,1,GRADIENT_FILL_RECT_V);

            trivert [0] .x      = 100;
            trivert [0] .y      = 250;
           
            trivert [0] .Red    = 0;
            trivert [0] .Green  = 255<<8;
            trivert [0] .Blue   = 0;
            trivert [0] .Alpha  = 0;

            trivert [1] .x      = 500;
            trivert [1] .y      = 400;
           
            trivert [1] .Red    = 0;
            trivert [1] .Green  = 0;
            trivert [1] .Blue   = 255<<8;

            GradientFill(hdc, trivert,2,&grad_rect,1,GRADIENT_FILL_RECT_V);

            Graphics::TBitmap* bmp = new Graphics::TBitmap;
            Graphics::TCanvas* cnvs = new Graphics::TCanvas;

            cnvs->Handle = hdc;

            TRect rect = cnvs->ClipRect;
            rect.Right = rect.Right - rect.Left;
            rect.Bottom = rect.Bottom - rect.Top;
            rect.Top = 0;
            rect.Left = 0;

            bmp->Width = rect.Right;
            bmp->Height= rect.Bottom;
            bmp->Canvas->CopyRect(rect, cnvs,cnvs->ClipRect);


            Image1->Picture->Bitmap = bmp;

            delete bmp;
            delete cnvs;           
        }
    }
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    NieznanyNieznana


Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość

cron