Autor Beitrag
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Mo 12.03.12 23:32 
Hallo!

Ich bin echt irritiert, dass dazu nichts in der Library ist - oder ich es nicht finde. ;)

Wie auch immer: ich habe ein TBitmap und ein TCanvas eines Fensters. Das Bitmap soll gestretcht werden. Das grundsätzlich in ganzzahligen Faktoren, also 1fache, doppelte, 3fache Größe etc (immer vergrößern also).
StretchDraw hat da ein Problem: es ist eben eine Allzweck-Funktion und als solche etwas langsam - das geht manuell mit Sicherheit schneller. Glaub ich :think:

Das Problem ist aber, dass die üblichen ScanLine-basierten Varianten natürlich ein Bitmap als Ziel brauchen. Ich möchte aber nicht noch ein Bitmap haben. Das Fenster ist ja im Prinzip schon eins ;)


Also: was ist schneller als StretchDraw und kann ein Bitmap fix skaliert auf ein Canvas werfen?

Viele Grüße,
Martok

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 13.03.12 01:19 
ich weiß nicht ob es schneller ist, aber man kann auch das Canvas vor dem "Malen" transformieren

www.delphipraxis.net...rehung-und-zoom.html

unit ExCanvasTools;

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 13.03.12 07:45 
Am schnellsten ist da vermutlich das schnell selbst zu implementieren. Hätte ich jetzt 10 Minuten würde ich es machen, aber ich muss gleich los...
Die Idee ist simpel:
Größe passend setzen, dann die Zeilen von unten nach oben mit Scanline durchgehen.
Martok Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Di 13.03.12 08:06 
Danke für die Ideen!

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
ich weiß nicht ob es schneller ist, aber man kann auch das Canvas vor dem "Malen" transformieren
Warum grade ich das übersehen hab, löse doch sonst alles mit GM_ADVANCED... ist aber exakt gleich schnell.

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Größe passend setzen, dann die Zeilen von unten nach oben mit Scanline durchgehen.
Schon klar, aber wie ich schrieb:
user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Ich möchte aber nicht noch ein Bitmap haben. Das Fenster ist ja im Prinzip schon eins
Ich mein, nochmal 5MB für ein weiteres Offscreen-Bitmap wäre nicht das Problem, aber schöner würde ich das schon finden. Schon weil ich vermute, dass nochmal umkopieren dann auch ncht schneller wird ;)

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 13.03.12 08:25 
Wo habe ich etwas von einer zusätzlichen Bitmap geschrieben? :gruebel:

Ich meine sowas, mit den äußersten Pixeln bin ich grad nicht sicher ohne es zu testen, den Rest machst du schon:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
type
  TPseudoRGB = packed record
    First: Word;
    Last: Byte;
  end;
  PPseudoRGB = ^TPseudoRGB;
var
  Test: TBitmap;
  NewLine, OldLine, LastOldLine, OldWidth: Integer;
  x, x2, OldPixel, NewPixel1, NewPixel2, NewPixel3: PPseudoRGB;
begin
  Test := TBitmap.Create;
  try
    Test.LoadFromFile(...);
    Test.PixelFormat := pf24bit;
    LastOldLine := Test.Height - 1;
    OldWidth := Test.Width - 1;
    Test.SetSize(Test.Width * 3, Test.Height * 3);
    for OldLine := LastOldLine downto 0 do
    begin
      OldPixel := Test.ScanLine[OldLine];
      NewLine := OldLine * 3;
      NewPixel1 := Test.ScanLine[NewLine];
      NewPixel2 := Test.ScanLine[NewLine + 1];
      NewPixel3 := Test.ScanLine[NewLine + 2];
      for x := 1 to OldWidth do
      begin
        for x2 := 1 to 3 do
        begin
          NewPixel1.First := OldPixel.First;
          NewPixel1.Last := OldPixel.Last;
          Inc(NewPixel1);
          NewPixel2.First := OldPixel.First;
          NewPixel2.Last := OldPixel.Last;
          Inc(NewPixel2);
          NewPixel3.First := OldPixel.First;
          NewPixel3.Last := OldPixel.Last;
          Inc(NewPixel3);
        end;
        Inc(OldPixel);
      end;
    end;
    Test.SaveToFile(...);
  finally
    Test.Free;
  end;

Für diesen Beitrag haben gedankt: BenBE, Martok
Blup
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173
Erhaltene Danke: 43



BeitragVerfasst: Di 13.03.12 11:34 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ich meine sowas, mit den äußersten Pixeln bin ich grad nicht sicher ohne es zu testen, den Rest machst du schon:

Da gibt es tatsächlich noch Probleme, aber so gehts:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
procedure SkaliereBMP(ABitmap: TBitmap; AFaktorX, AFaktorY: Integer);
type
  TBGR = packed record
    B: Byte;
    G: Byte;
    R: Byte;
  end;
  PBGR = ^TBGR;
var
  OldWidth, OldHeight, NewWidth, NewHeight, x1, x2, y1, y2: Integer;
  OldPixel, NewPixel: PBGR;
begin
  ABitmap.Pixelformat := pf24Bit;
  OldWidth  := ABitmap.Width;
  OldHeight := ABitmap.Height;
  NewWidth  := OldWidth  * AFaktorX;
  NewHeight := OldHeight * AFaktorY;
  {horizontal Skalieren}
  if AFaktorX > 1 then
  begin
    ABitmap.SetSize(NewWidth, OldHeight);
    for y1 := 0 to OldHeight - 1 do
    begin
      OldPixel := ABitmap.ScanLine[y1];
      NewPixel := OldPixel;
      Inc(OldPixel, OldWidth);
      Inc(NewPixel, NewWidth);
      for x1 := OldWidth - 1 downto 0 do
      begin
        Dec(OldPixel);
        for x2 := AFaktorX - 1 downto 0 do
        begin
          Dec(NewPixel);
          NewPixel^ := OldPixel^;
        end;
      end;
    end;
  end;
  {vertikal Skalieren}
  if AFaktorY > 1 then
  begin
    ABitmap.SetSize(NewWidth, NewHeight);
    for y1 := OldHeight - 1 downto 0 do
    begin
      OldPixel := ABitmap.ScanLine[y1];
      for y2 := AFaktorY - 1 downto 0 do
      begin
        NewPixel := ABitmap.ScanLine[y1 * AFaktorY + y2];
        Move(OldPixel^, NewPixel^, SizeOf(TBGR) * NewWidth);
      end;
    end;
  end;
end;

Für diesen Beitrag haben gedankt: BenBE, Martok
Martok Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Di 13.03.12 21:58 
Danke euch Beiden. Funktioniert wunderbar - ist aber noch langsamer :D

Allerdings hat mich das dazu gebracht, mal etwas zu testen, und ich hab einfach mal ein Bitmap in der Endgröße ohne irgendwelche Bearbeitung geblittet. Wie sich rausstellt, ist tatsächlich das Kopieren der Pixel an sich so langsam, die Skalierung ist schon verdammt schnell.

Wobei langsam auch relativ ist. Schnell genug ist das auch so, aber: 60FPS kosten 80% auf einem Kern, da ist nicht mehr viel Luft für Logik...

Immerhin: falls mal jemand so eine Funktion sucht, wird er jetzt eine finden :zustimm:

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."

Für diesen Beitrag haben gedankt: BenBE
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Mi 14.03.12 22:26 
StretchDraw ist ziemlich schnell. Wichtig ist, dass du nicht die Farbtiefe änderts d.h. das Pixelformat des ZielBitmaps sollte auf das des Ausgangsbitmaps gesetzt werden. Außerdem solltest du das Zielbitmap nur ein einziges mal erstellen wenn du mehrere Frames bearbeitest. Farbraumwechsel + Speicher reservieren ist langsam, wobei ersteres noch vernachlässigbar ist.

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit

Für diesen Beitrag haben gedankt: BenBE
platzwart
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Do 15.03.12 00:56 
Schau dir mal die Graphics32 an (dort beispielsweise TBitmap32 oder so ähnlich). Die sind extrem schnell. Hatte mir bei einem Projekt gegenüber dem Standard TBitmap einen Performanceschub von über dem 50-fachen gebracht. Konnte damit auf einem Vierkernprozessor 4 Bilder gleichzeitig verarbeiten und dabei 110.000.000 Pixelzugriffe pro Sekunde realisieren...

_________________
Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
mvollmer
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 42
Erhaltene Danke: 3


Delphi (Seattle), C (MPLAB X)
BeitragVerfasst: Do 15.03.12 13:03 
[OT]
graphics32.org/wiki/Main/TBitmap

Zitat:
Main /
TBitmap

WTF?

:D
[/OT]

Btw: Was ist mit StrechtBlt?