Wolne operacje

0

Mam pytanka.
1) Jak sprawic aby obliczenia byly wykonywane szybciej, chodzi mi dokladnie o grafike, czyli jak szybko w trybie rzeczywistym wykonac pewne efekty graficzne, jak chocby przyczerwienienie (kod mam). Wszystko dziala ladnie, iestety dziala to stanowczo za wolno.
2)Chcialem tez wykorzystac DelphiX, lecz to mnie nie zadowolilo, czesc operacji ktore chcialem bykonywano sie rownie wolno a rysowanie ich bylo w pewnym stopniu utrudnione. Dlatego chce sie nauczyc PowerDraw, tzn obslugi tego pakietu, gdzie mozna znalezc jakis porzadny kurs? (mam jakies kursiki z delphi.bajo.pl ale to nie jest kurs tylko cos na wzor FAQ)

pozdrawiam

0

Do mnie doszły słuchy, że dzielenie jest zdecydowanie najwolniejsze, więc jeżeli w kodzie masz szansę napisać (x * 0.5) zamiast (x / 2) to byłoby bardzo wskazane.

0

Najwolniejsze jest odwołanie do pikseli płótna (canvas.pixels), a tak zazwyczaj bywa że jest ono umieszczone w podwójnej pętli (np dla obrazka 100 x 100 wykonuje się ono 10000 razy). Koniecznie przerzuć się na ScanLine.

0

Ale jak to mozna wykorzystac do zmiany barwy obrazka?
Moze i jestem glupcem ale nie potrafie, pogubilem sie.

Do zmiany koloru uzywam czegos takiego:

function czerwony(kolorek:tcolor):tcolor;
var
 R, G, B: Byte;
begin
 R := GetRValue(kolorek);
 G := GetGValue(kolorek);
 B := GetBValue(kolorek);
 if r <255 then R := round(R*15*0.01)+  Round(255 - 15*0.01*255);
 Result := RGB(R, G, B);
end;

(za rada usunolem dzielenia, lecz nie pomoglo to zbytnio)

0

if r <255 then R := round(R150.01)+ Round(255 - 150.01255);

Po co to wyrażenie????

Round(255 - 15*0.01*255)

skoro można od razu wpisać zamiast tego <font color="blue">216</span> :|

Tak samo zamiast 15*0.01 od razu 0.15

Ale nie tu tkwi problem - pokaż nam jak używasz tej funkcji - czy to jest przy Pixels czy przy ScanLine.

0

masz racje, walnolem gafe [wstyd] . To dlatego ze wyzucilem jedna zmienna. Masz racje, juz to poprawilem.
na razie niestety piksele, i tu tkwi problem jak sadze i jak sasugerowano wyzej, lecz nie potrafie przerobic tego na scanline [wstyd]

begin
 Pic := TBitmap.Create;
 try
  Pic.Assign(obraz.Picture.Graphic);
  for Ij := 0 to pic.Width do
   for J := 0 to pic.Height do
    Pic.Canvas.Pixels[ij, j] := czerwony(Pic.Canvas.Pixels[ij, j]);
  obraz.Picture.Graphic := Pic;
 finally
    Pic.Free;
 end;
end;

czy przypisanie jest dobre, czy tez sie da przyspieszyc? a moze od razu robic na canvasie Timage?

// jestem tylko czlowiekiem, moglem przeoczyc.
wiecie czemu nie dziala encyklopedia, przynajmniej u mnie

0

Zaraz mnie szlag trafi, albo ciebie moja zemsta! Po kiego wała ja pisał ScanLine Demo? Po to by teraz nikomu niechciało się tam zaglądać? a wystarczy poczytac dosłownie kilka linijek... Ech, co z tym swiatem się dzieje?

0

Zamiast DelphiX proponuję skorzystać bezpośrednio z DirectX i nagłówków Delphi do niego (od D7 są standardowo w pakiecie, a do wcześniejszych wersji można znaleźć w sieci). W DirectX już nie będziesz się przez Canvas odwoływać i będzie działać znacznie szybciej.
A co do ScanLine, to patrz post wyżej.

/* W pełni rozumiem ból Johnnego_Bit */

0

Mialem podobny problem (dalem sobie spokuj, bo nie bylo mi potrzebne)... Jak juz wszystko rozwiazesz, to mozesz jeszcze dac najwyzszy pryiorytet (zyskasz jakies 4 sec.) [browar] [cya]

0

Dziekuje wam za pomoc, udalo mi sie zrobic cos takiego:

procedure TForm1.Button2Click(Sender: TObject);
var
  x1, y1, t: integer;
  linia: PByteArray;
  bmp2: tbitmap;
  pix: TColor;
begin
bmp2:=TBitmap.Create;
  bmp2.Assign(Image1.Picture.Bitmap);
 for y1:=0 to Image1.Picture.Bitmap.Height-1 do
  begin
    linia:=Image1.Picture.Bitmap.ScanLine[y1];
    for x1:=0 to Image1.Picture.Bitmap.Width-1 do
    begin
        bmp2.Canvas.Pixels[x1,y1]:=RGB(round(linia[x1*3+2]*0.15)+216, (linia[x1*3+1]), (linia[x1*3]));
        end;
  end;
  Image1.Picture.Bitmap.Assign(bmp2);
  bmp2.Free;
end;

czas: przy pixels: 561 (okolo)
powyzszy kod: 150

zaoszczedzilem sporo czasu, ale czyu nie da sie tego jeszcze jakos przyspieszyc?

pozdrawiam

0

LOL :-D

bmp2.Canvas.Pixels[x1,y1]:=RGB(round(linia[x13+2]0.15)+216, (linia[x13+1]), (linia[x13]));

Scanline i Pixels w jednym ? A to ci heca.. ja wiem że to ma prawo działać ale gdzie tu logika ? (nie bierz tego do siebie, każdy kiedyś się uczył.. ale to taki błąd jakbyś na jednym dyktandzie w jednym zdaniu napisał duży a w drugim dórzy, rozumiesz.. bądź konsekwentny) Popraw to..

0

ogólnie rzecz biorąc ponieważ

bmp2.Canvas.Pixels[x1,y1]:=RGB(round(linia[x13+2]0.15)+216, (linia[x13+1]), (linia[x13]));
jest dość marnym pomysłem, a ScanLines są zapisywane jako BRG to ten kodzik mozna by było zapisać:

linia[x1*3+2]:=round(linia[x1*3+2]*0.15)+216;

a skoro nie ruszasz nic oprócz czerwonego w tym kodzie, to tyle wystarczy. optymalizacja jak sie patrzy :-D

0

Widac jestem totalnym kretynem.
nie moge uzyc twego kodu johnny_bit. skopoiwalem go zamiast tamtego...nic, zmienilem x1 na y1....tez nic, cos tam jeszcze z tym robilem...tez nic. Operacja jest szybka ale bez widocznych efektow.
Wybaczcie mi prosze ze tak sie osmieszam

// dziekuje. [wstyd] nie zauwazylem tego... dziekuje wam wszystkim.

0
procedure TForm1.Button2Click(Sender: TObject);
var
   x1, y1, t: integer;
   linia: PByteArray;
   bmp2: TBitmap;
   pix: TColor;
begin
bmp2:=TBitmap.Create;
   bmp2.Assign(Image1.Picture.Bitmap);
   for y1:=0 to Image1.Picture.Bitmap.Height-1 do
   begin
      linia:=bmp2.ScanLine[y1];  // << TU BYŁO  ZŁE PRZYPISANIE!      
      for x1:=0 to Image1.Picture.Bitmap.Width-1 do
         procedukra Jonny'ego..

   end;
   Image1.Picture.Bitmap.Assign(bmp2);
   bmp2.Free;
end; 

Sprawdź.. nie testowałem.. ale na oko jest ok.

1 użytkowników online, w tym zalogowanych: 0, gości: 1