Delphi-PRAXiS
Seite 7 von 8   « Erste     567 8      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Geht das noch schneller? - Bitmap-Verrechnung (https://www.delphipraxis.net/182859-geht-das-noch-schneller-bitmap-verrechnung.html)

Harry Stahl 29. Nov 2014 08:01

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Amateurprofi (Beitrag 1281418)
Delphi-Quellcode:
PROCEDURE Blend32(Source,Dest:pRGBQuad; Width,Height,OOffset,UOffset:Integer);
....

Ja, das gute alte Assembler...

Wäre noch etwas schneller als meine letzte Variante (hier zuletzt ca. 62 MS, die ASM ca. 47 MS), allerdings ist das Ergebnis erkennbar falsch, siehe Screenshot).

Harry Stahl 29. Nov 2014 08:05

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
[QUOTE=hanvas;1281434]
Zitat:

Zitat von Harry Stahl (Beitrag 1281237)

Danke für den Tipp. Allerdings möchte ich erst mal nur 2-3 bestehende Grafik-Funktionen unter Weiterverwendung von TBitmap und meines bisherigen Source-Codes beschleunigen.

Die Konsequenz, das ganze Programm umzuschreiben, möchte ich derzeit noch ganz gerne vermeiden...

hanvas 29. Nov 2014 10:39

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Zitat:

Zitat von Harry Stahl (Beitrag 1281543)

Danke für den Tipp. Allerdings möchte ich erst mal nur 2-3 bestehende Grafik-Funktionen unter Weiterverwendung von TBitmap und meines bisherigen Source-Codes beschleunigen.

Bearbeitest Du eigentlich nur ein Bild, oder wird deer Funktion eine Serie von Bildern, eines nach dem anderen übergeben? Im ersten Fall glaube ich das das Optimierungspotiental - abgesehen von den bereits erfolgten Hinweisen, ziemlisch ausgeschöpft.

cu HaJoe

Amateurprofi 29. Nov 2014 12:26

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Zitat:

Zitat von Harry Stahl (Beitrag 1281542)
Zitat:

Zitat von Amateurprofi (Beitrag 1281418)
Delphi-Quellcode:
PROCEDURE Blend32(Source,Dest:pRGBQuad; Width,Height,OOffset,UOffset:Integer);
....

Ja, das gute alte Assembler...

Wäre noch etwas schneller als meine letzte Variante (hier zuletzt ca. 62 MS, die ASM ca. 47 MS), allerdings ist das Ergebnis erkennbar falsch, siehe Screenshot).

Hab ich geprüft.
Das Label "Next:" gehört 2 Code-Zeilen höher.
So wie es war, wurde bei rgbReserved=0 zum nächsten Zeilenanfang gesprungen statt zum nächsten Pixel.
Bei meiner Prüfung auf identische Ergebnisse hatte ich dummerweise immer alle rgbReserved<>0, so dass dieser Fehler nicht auftrat.

Delphi-Quellcode:
PROCEDURE Blend32(Source,Dest:pRGBQuad; Width,Height,OOffset,UOffset:Integer);
const
   RegSize=4;
   WOffs=6*RegSize; HOffs=12*RegSize; OOffs=11*RegSize; UOffs=10*RegSize;
asm
         pushad
         mov     ebp,ecx               // Width
         lea     esi,[eax+ebp*4]       // Source
         lea     edi,[edx+ebp*4]       // Dest
         neg     ebp
         mov     [esp+WOffs],ebp
@Loop:  mov     bl,[esi+ebp*4].TRgbQuad.rgbReserved // S.Reserved
         test    bl,bl
         jz      @Next
         // Red
         mov     al,[esi+ebp*4].TRgbQuad.rgbRed     // S.Red
         mov     cl,[edi+ebp*4].TRgbQuad.rgbRed     // D.Red
         sub     al,cl                              // S.Red-D.Red
         imul    bl                                 // (S.Red-D.Red)*S.Reserved
         add     ah,cl                              // ((S.Red-D.Red)*S.Reserved) shr 8 + D.Red
         mov     dx,ax
         // Green
         mov     al,[esi+ebp*4].TRgbQuad.rgbGreen   // S.Green
         mov     cl,[edi+ebp*4].TRgbQuad.rgbGreen   // D.Green
         sub     al,cl                              // S.Green-D.Green
         imul    bl                                 // (S.Green-D.Green)*S.Reserved
         mov     dl,ah                              // ((S.Green-D.Green)*S.Reserved) shr 8
         add     dl,cl                              // ((S.Green-D.Green)*S.Reserved) shr 8 + D.Green
         shl     edx,8
         // Blue
         mov     al,[esi+ebp*4].TRgbQuad.rgbBlue    // S.Blue
         mov     cl,[edi+ebp*4].TRgbQuad.rgbBlue    // D.Blue
         sub     al,cl                              // S.Blue-D.Blue
         imul    bl                                 // (S.Blue-D.Blue)*S.Reserved
         mov     dl,ah                              // ((S.Blue-D.Blue)*S.Reserved) shr 8
         add     dl,cl                              // ((S.Blue-D.Blue)*S.Reserved) shr 8 + D.Blue
         // Reserved
         or      edx,$FF000000
         mov     [edi+ebp*4],edx
@Next:  add     ebp,1
         jl      @Loop
         // Nächste Zeile
         add     esi,[esp+OOffs]
         add     edi,[esp+UOffs]
         mov     ebp,[esp+WOffs]
         sub     [esp+HOffs],1
         jnz     @Loop
@End:   popad
end;

Harry Stahl 29. Nov 2014 16:30

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
@Amateurprofi:

Danke, dass Du Dich der Sache noch mal angenommen hast. Allerdings stimmt das Ergebnis immer noch nicht.

Falls Du die Sache noch weiter verfolgen willst, kannst Du hier im Thread-Beitrag Nr. 26 das Demoprojekt laden, das ich gepostet habe.

Da brauchst Du nur im Button-Click Event folgendes zu machen, um Deine Procedure einzubinden:

Delphi-Quellcode:
  for L := 1 to count do begin
    AsmDraw32BitToBitmap (b, b3);
    //Draw32BitToBitmapnew (b, b3);
  end;
Dann Siehst Du direkt im Vergleich, ob beide Bilder den gleichen Inhalt haben.

Harry Stahl 29. Nov 2014 20:52

[Gelöst] AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Ich habe nun den Rat gefolgt und habe mir die Graphics32-Unit mal angehen.

Der Grafk-Typ TBitmap32 ist zwar ein eigener Klassen-Typ, aber die Lowlowel-Routinen, die dahinter liegen, kann man auch auf TBitmap anwenden.

Die Lösung besteht also nun darin, GR32 und GR32_Blend aus der Graphics32 einzubinden und dann kann man die Funktion mit einer Zeile (1) benutzen, die dann auch nur noch 31 MS benötigt, um das Bild zu verrechnen:

Delphi-Quellcode:
procedure Draw32BitToBitmap(const BitOben: TBitmap; BitUnten: TBitmap);
begin
  BLEND_LINE[cmBlend]^(pColor32(BitOben.ScanLine[BitUnten.Height-1]),
    pColor32(BitUnten.ScanLine[BitUnten.Height-1]), BitUnten.Width* BitUnten.Height);
end;

Amateurprofi 29. Nov 2014 23:39

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Zitat:

Zitat von Harry Stahl (Beitrag 1281595)
Allerdings stimmt das Ergebnis immer noch nicht.
Falls Du die Sache noch weiter verfolgen willst, kannst Du hier im Thread-Beitrag Nr. 26 das Demoprojekt laden, das ich gepostet habe.

@Harry:
Habe ich geprüft.
Ich habe eine 8Bit-Integer-Multipikation benutzt, bei der Byte-Werte > $7F als negativ betrachtet werden.
Im Debugger sah ich dann, dass bei Deiner Prozedur eine 32Bit-Integer Multiplikation verwendet wird.
Bei den Tests fiel das nicht ins Gewicht, weil ich einfach den gesamten Screen nach BitOben und BitUnten kopiert hatte.
Somit waren die Rgb-Werte in Oben und Unten gleich und die Subtraktion von z.B. Oben.rgbRed - Unten.rgbRed ergab immer 0.
Nachdem ich die Bitmaps mit Zufallswerten gefüllt hatte konnte den Grund der Abweichungen finden.
Ich habe die Prozedur Blend32 umgeschrieben. Für mich sehr überraschend, ist sie dadurch schneller geworden; ich hatte das Gegenteil erwartet.

Dein Beispiel Projekt läßt sich bei mir (XE2) nicht kompilieren.

Delphi-Quellcode:
PROCEDURE Blend32(Source,Dest:pRGBQuad; Width,Height,OOffset,UOffset:Integer);
const
   RegSize=4;
   WOffs=6*RegSize; HOffs=12*RegSize; OOffs=11*RegSize; UOffs=10*RegSize;
asm
         pushad
         lea     esi,[eax+ecx*4]       // Source
         lea     edi,[edx+ecx*4]       // Dest
         neg     ecx
         mov     [esp+WOffs],ecx
         mov     ebp,[esp+HOffs]
@Loop:  movzx   ebx,[esi+ecx*4].TRgbQuad.rgbReserved // S.Reserved
         test    ebx,ebx
         jz      @Next
         // Blue
         movzx   eax,[esi+ecx*4].TRgbQuad.rgbBlue    // S.Blue
         movzx   edx,[edi+ecx*4].TRgbQuad.rgbBlue    // D.Blue
         sub     eax,edx                             // S.Blue-D.Blue
         imul    ebx                                 // (S.Blue-D.Blue)*S.Reserved
         add     [edi+ecx*4].TRgbQuad.rgbBlue,ah
         // Green
         movzx   eax,[esi+ecx*4].TRgbQuad.rgbGreen   // S.Green
         movzx   edx,[edi+ecx*4].TRgbQuad.rgbGreen   // D.Green
         sub     eax,edx                             // S.Green-D.Green
         imul    ebx                                 // (S.Green-D.Green)*S.Reserved
         add     [edi+ecx*4].TRgbQuad.rgbGreen,ah
         // Red
         movzx   eax,[esi+ecx*4].TRgbQuad.rgbRed     // S.Red
         movzx   edx,[edi+ecx*4].TRgbQuad.rgbRed     // D.Red
         sub     eax,edx                             // S.Red-D.Red
         imul    ebx                                 // (S.Red-D.Red)*S.Reserved
         add     [edi+ecx*4].TRgbQuad.rgbRed,ah
         // Reserved
         mov     [edi+ecx*4].TRgbQuad.rgbReserved,$FF
@Next:  add     ecx,1
         jl      @Loop
         // Nächste Zeile
         add     esi,[esp+OOffs]
         add     edi,[esp+UOffs]
         mov     ecx,[esp+WOffs]
         sub     ebp,1
         jnz     @Loop
@End:   popad
end;

Harry Stahl 30. Nov 2014 10:41

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Um das jetzt noch zu vervollständigen: Jetzt funktioniert auch Deine Lösung mit ca. 32 MS recht schnell und richtig.:thumb:

Wenn man die Graphics32 also nicht verwenden möchte, wäre Deine Lösung auch noch eine Variante.

OK, mit XE2 kannst Du das Demo nicht kompilieren, da ja dort noch nicht die TParallel-Library zur Verfügung stand.

Wenn Du aber die "System.Threading" Unit rausnimmst und "Draw32BitToBitmappara" auskommentierst sollte es gehen.

Codix32 30. Nov 2014 12:43

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Ich bitte um Entschuldigung, wenn ich eine Frage habe, die nicht ganz zum Thread passt, aber:

Frage:
Gibt es eine Möglichkeit, ein Bitmap mit geringer Auflösung (72dpi), das sich beim vergrößern total verpixelt, irgendwie so zu schärfen, dass die Details sichtbar werden?

also in Krimisendungen habe ich das schon gesehen, dass dort Aufnahmen vergrößert werden, dann verpixelt sind, dann mit einem Programm dennoch geschärft werden. Mir geht es dabei nicht, um irgendwelche verpixelten Gesichter zu erkennen, sondern um andere Objekte.

Enthält also eine kleine Grafik genug Infos, um die beim Vergrößern entstehenden Quadrate mit einem Algorythmus so zu bearbeiten, dass daraus ein größeres scharfes Bild wird?
Enthalten die Blöcke oder Quadrate überhaupt genug Farbinfos dafür?

Oder geht da wohl nur was mit Vectoren...?

Valle 30. Nov 2014 12:57

AW: Geht das noch schneller? - Bitmap-Verrechnung
 
Dann eröffne doch bitte einen neuen Thread für eine andere Frage.

Dann musst du doch nicht den Thread vom armen Harry durcheinander bringen. :(

Kurze Antwort: Nein, das geht nicht zufriedenstellend automatisch. Reine Fiktion.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:25 Uhr.
Seite 7 von 8   « Erste     567 8      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz