sybic Posted October 26, 2010 Report Share Posted October 26, 2010 Postanowiłem sobie zrobić swoje narzędzie do ustawiania koloru w aplikacji, dokładnie takie same jak jest w Photoshopie, czy innych programach graficznych. Mianowicie zmieniam sobie kolor H, a w drugim obrazku rysuje mi się cała paleta odcieni saturacji i jasności. O takie : http://img838.imageshack.us/img838/298/przyklad.png wszystko super, ale jest jeden problem, gdy zmieniam kolorem H, obrazek (359x359) z odcieniami zmienia się bardzo wolno. Może trwa to 0.5 s, ale to wystarczy by narzędzie jako mało komfortowe i całkowiece nie do użytku. W Photoshopie dzieje się to bezzwłocznie... Pytanie : Jak to należy zrobić że tak powiem profesjonalnie? Ja to robię ScanLine procedure Rysuj_Odcienie(rysunek:TImage; seH_value:double); var x,y : integer; P : PByteArray; H,S,V:double; rgb: results; begin H:=seH_value; rysunek.Picture.BitMap.PixelFormat:=pf24Bit; with rysunek.Picture.Bitmap do for y:=0 to Height-1 do begin V:=(height-y)/height*255; P:=ScanLine[y]; x:=0; repeat S:=(x/3)/width; rgb:=hsv2rgb_(H,S,V); p[x]:=trunc(rgb[3]); p[x+1]:=trunc(rgb[2]); p[x+2]:=trunc(rgb[1]); x:=x+3; until x>(Width-1)*3; end; rysunek.Invalidate; end; ^rjvŁ),)zgŚ-źgjqnkbs6ŁqĄVvkkZui' function hsv2rgb_(hue: double; sat: double; val: double): results; var red, grn, blu :double; i, f, p, q, t: double; rgb: results; begin red := 0; grn := 0; blu := 0; if val=0 then begin red := 0; grn := 0; blu := 0; end else begin hue := 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 then begin red:=val; grn:=t; blu:=p; end else if i=1 then begin red:=q; grn:=val; blu:=p; end else if i=2 then begin red:=p; grn:=val; blu:=t; end else if i=3 then begin red:=p; grn:=q; blu:=val; end else if i=4 then begin red:=t; grn:=p; blu:=val; end else if i=5 then begin red:=val; grn:=p; blu:=q; end; end; rgb[1] := red; rgb[2] := grn; rgb[3] := blu; result := rgb; end; Tylko, czy z tym można coś jeszcze zrobić, jakoś zoptymalizować? Jestem niezwykle ciekaw jak to robią profesjonaliści, bo ja pisząc sobie takie narzędzie odniosłem małą porażkę. Link to comment Share on other sites More sharing options...
xevil21 Posted October 26, 2010 Report Share Posted October 26, 2010 Witam! Ja mogę dodać, że nie używają tak zagnieżdżonych instrukcji IF THEN ELSE !!! Zamień ten fragment kodu, na: case wyrażenie of wybór 1: (kod); ... wybór n: (kod); else (kod) end; Nie podoba mi się również, w jaki sposób funkcja zwraca wartości: KOD rgb[1] := red; rgb[2] := grn; rgb[3] := blu; result := rgb; Głębiej nie wnikam, ponieważ już mnie sen łapie. Pozdrawiam! Link to comment Share on other sites More sharing options...
sybic Posted October 27, 2010 Author Report Share Posted October 27, 2010 Zrobiłem parę poprawek, eliminując w pętli i samej procedury zbędne operacje umieszczając je przed wywołaniem pętli. Udało mi się to wszystko przyspieszyć co najmniej 3-krotnie. Przy szybkich komputerach może to być do przyjęcia, ale daleko jeszcze do szybkości procedur jakie są w PS procedure hsv2rgb_(i:byte; f : double; sat: double; val: double; var red, grn, blu:Byte); var p, q, t: double; begin if val=0 then begin red := 0; grn := 0; blu := 0; end else begin p := val*(1-sat); q := val*(1-(sat*f)); t := val*(1-(sat*(1-f))); case i of 0:begin red:=round(val); grn:=round(t); blu:=round(p); end; 1:begin red:=round(q); grn:=round(val); blu:=round(p); end; 2:begin red:=round(p); grn:=round(val); blu:=round(t); end; 3:begin red:=round(p); grn:=round(q); blu:=round(val); end; 4:begin red:=round(t); grn:=round(p); blu:=round(val); end; 5:begin red:=round(val); grn:=round(p); blu:=round(q); end; end; end; end; procedure Paint_Odcienie(rysunek:TImage; seH_value:double); var x,y : integer; P : PByteArray; H,S,V:double; hue60,f:double; i:integer; begin H:=seH_value; hue60 := H/60; i := trunc(floor(hue60)); f := hue60-i; rysunek.Picture.BitMap.PixelFormat:=pf24Bit; with rysunek.Picture.Bitmap do for y:=0 to Height-1 do begin V:=(height-y)/height*255; P:=ScanLine[y]; x:=0; repeat S:=x/(3*width); hsv2rgb_(i,f,S,V, p[x+2], p[x+1], p[x]); inc(x,3); until x>(Width-1)*3; end; rysunek.Invalidate; end; Link to comment Share on other sites More sharing options...
sazian Posted October 28, 2010 Report Share Posted October 28, 2010 poza samą optymalizacją można by wrzucić odrysowywanie w osobny wątek Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.