AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi TBitmap32 in ByteArray (schneller) oder Alternative
Thema durchsuchen
Ansicht
Themen-Optionen

TBitmap32 in ByteArray (schneller) oder Alternative

Ein Thema von Delphi-Narr · begonnen am 15. Apr 2013 · letzter Beitrag vom 16. Apr 2013
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Delphi-Narr
Delphi-Narr

Registriert seit: 29. Aug 2009
Ort: Duisburg
437 Beiträge
 
Delphi 2007 Professional
 
#1

TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 15. Apr 2013, 21:36
Hallo,

ich arbeite immer noch an meinem Plugin für die Logitech G19 und habe nun ein weiteres Problem, welches die Performance betrifft.
Die G19 DLL erlaubt es, ein 320x240 Bitmap auf den Bildschirm der Tastatur zu legen und das bis zu 60 mal pro Sekunde.
Bisher möchte ich lediglich eine Progressbar anzeigen lassen, welche ich zuvor auf ein Bitmap32 zeichne.
Allein das häufige Zeichnen lässt die CPU schon ordentlich arbeiten (5% bei einem AMD FX-8120, per Timer gesteuertes Neuzeichnen alle 30ms) und die
DLL Funktion will das Bitmap auch als Bytearray haben, welches 320*240*4 Bytes enthält.
Ein Pixel setzt sich dabei aus je 4 Bytes zusammen: B G R Alpha
Um das Bitmap jetzt in ein solches Array zu konvertieren wird jedes Mal eine Schleife über alle Pixel des Bitmaps durchlaufen und die Farben dann
in das Array geschrieben (Seit Kurzem gibts dabei jetzt eine Zugriffsverletzung, obwohl es bis eben noch klappte - Reboot wirds schon richten).
Bei diesem Verfahren rackert der Prozessor dann bei 12% und das ist für ein kleines Applet wesentlich zu viel!
Gibt es eine Alternative, die 320*240 Grafiken zu erstellen und diese als Bytearray zu formatieren, ohne dabei derartig Ressourcen zu verballern?

Viele Grüße!

Geändert von Delphi-Narr (15. Apr 2013 um 23:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#2

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 15. Apr 2013, 22:06
Naja, es gibt die Eigenschaft Bitmap32.Bits.

Du könntest also entweder
a) Den Pointer in ein Array casten und dann übergeben. Da musst du nur sichergehen dass die dll da nix dran rumpfuscht und du darfst währenddessen natürlich nix zeichnen.
b) Mit memcpy/Move oder so das ganze in ein Array kopieren. Sollte auch deutlich schneller gehen als Pixelweise.

Ich nehme mal an, die dll erwartet die Pixel im passenden Format (ARGB oder ABGR) - ansonsten musst du wohl doch nochmal mit ner Schleife drüber.

Geändert von jfheins (15. Apr 2013 um 22:09 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Delphi-Narr
Delphi-Narr

Registriert seit: 29. Aug 2009
Ort: Duisburg
437 Beiträge
 
Delphi 2007 Professional
 
#3

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 15. Apr 2013, 22:27
Die Funktionsbeschreibung aus dem SDK häng ich mal als Bild an.
Sieht leider so aus, als ob die Funktion es wohl nicht als ARGB oder ABGR haben will.
Darum werde ich wohl nicht um eine Schleife drumherumkommen... Aber ist es dann effizienter, die Bits zu durchlaufen und dann auseinander zu pflücken?

Viele Grüße
Miniaturansicht angehängter Grafiken
g19.png  
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#4

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 15. Apr 2013, 22:35
Sieht leider so aus, als ob die Funktion es wohl nicht als ARGB oder ABGR haben will.
Hm? Doch genau so sieht es aus. Und du hast sogar nich Glück, weil Windows GDI mit BGR arbeitet, TBitmap32 UND die dll aber mit ARGB

Die visuelle Anordnung mag zwar eine andere sein, aber in der Doku zu TBitmap32 steht:
Zitat:
Bits 32...24 Bits 23...16 Bits 15...8 Bits 7...0
Alpha Red Green Blue
Und genau das gleiche steht auch in dem Bild, das du angehängt hast. Dass Blau die Bits 0..7 hat, bedeutet ja dass das Byte ganz am Anfang steht. Little Endian sei dank
  Mit Zitat antworten Zitat
Benutzerbild von Delphi-Narr
Delphi-Narr

Registriert seit: 29. Aug 2009
Ort: Duisburg
437 Beiträge
 
Delphi 2007 Professional
 
#5

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 15. Apr 2013, 23:01
Hm ok ich stehe wohl etwas auf dem Schlauch

Delphi-Quellcode:

var
    Pic2:TByteArray;
    i,j,ges:integer;
    R,G,B:byte;
    color:TColor;
    P: PColor32Array;
    C: TColor32;
begin
    SetLength(Pic2,320*240*4);

   ges:=0;
   P:=VirtualBitmap.Bits;
   for I := 0 to 320*240-1 do
    begin
      C:=P[i];
      Pic2[ges]:=TColor32Entry(C).R;
      Pic2[ges+1]:=TColor32Entry(C).G;
      Pic2[ges+2]:=TColor32Entry(C).B;
      Pic2[ges+3]:=255;
      ges:=ges+4;
    end;
   // ...
   LogiLcdColorSetBackground(Pic2);
So sieht das bisher bei mir aus - ist etwas umständlich gemacht, weil die Schleife noch von der alten Methode übrig geblieben ist.
Die benötigten Werte stehen ja auch in C.Planes drin vermute ich?!
Auf diese Weise erhalte ich zwar generell das gewünschte Bild auf dem G19 LCD, doch lediglich den ersten Frame - nach dem Update (LogiLcdColorSetBackground)
kommt eine schöne Fehlermeldung:

Zitat:
In Projekt xyz.exe trat ein problem mit folgender Meldung auf: 'pivileged instuction at 0x0018fd95'. ...
Da scheint wohl irgendein Problem beim Aufruf vorzuliegen...
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#6

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 15. Apr 2013, 23:29
Ich würde es jetzt einfach mal so probieren:
Delphi-Quellcode:
// ggf. casten
    LogiLcdColorSetBackground(VirtualBitmap.Bits);
// Vielleicht erwartet die Funktion aber auch nen Pointer?
    LogiLcdColorSetBackground(@VirtualBitmap.Bits);
Zu verlieren hast du ja nix
  Mit Zitat antworten Zitat
Benutzerbild von Delphi-Narr
Delphi-Narr

Registriert seit: 29. Aug 2009
Ort: Duisburg
437 Beiträge
 
Delphi 2007 Professional
 
#7

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 16. Apr 2013, 09:54
Also beide Varianten lösen dennoch Fehlermeldungen aus, die direkte Übergabe verändert dabei am Bildschirm rein gar nichts.
Der Pointer lässt ein paar wahllos platzierte Punkte erscheinen.
Die Übergabe des manuell erstellten Bytearrays führt zu einer korrekten Anzeige und einer anschließenden Fehlermeldung.
Ersetze ich das TBitmap32 durch TBitmap und verwende dann die Canvas Funktionen, so funktioniert die Anzeige anschließend ohne Problem und Fehler.

Es funktioniert auch ohne Fehler, wenn ich beim Bitmap32 die Farben über Canvas.Pixels abfrage. Dabei sind dann jedoch Rot und Blau vertauscht (ist ja an sich auch logisch).

So noch eine kleine Änderung, mit

Delphi-Quellcode:
P:=VirtualBitmap.Bits;
   for I := 0 to 320*240-1 do
    begin
      color:=WinColor(P[i]);
      R:=color and $FF;
      G:=(Color shr 8) and $FF;
      B:=(Color shr 16) and $FF;
      Pic2[I*4]:=R;
      Pic2[I*4+1]:=G;
      Pic2[I*4+2]:=B;
      Pic2[I*4+3]:=255;
    end;
klappt es eigentlich ganz gut, CPU Last ist jedoch immer noch bei 7%.

Geändert von Delphi-Narr (16. Apr 2013 um 10:13 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 16. Apr 2013, 10:25
Ich komme nicht ganz hinterher.

1) TByteArray
Das ist doch einfach nur type TByteArray = array [0..32767] of Byte; . Ich habe in Delphi (aus Zeitgründen) nach wie vor gewaltige Lücken, aber Delphi hat doch für Arrays wie für Strings bsp. Referenzzählung? Wer weiß, was da noch alles drinsteckt was die DLL eigentlich nicht brauchen kann und dementsprechend durcheinanderkommt. Ich verstehe das Schlüsselwort packed noch nicht wirklich, vielleicht kann das helfen?

2) Geschwindigkeit
Die CPU-Auslastung ist wirklich extrem hoch, ohne wirklich Ahnung zu haben würde ich die benutzten Delphi-Routinen bzgl. Farben beschuldigen. Kannst du mittels FillChar oder ähnlichem einfach das Bild immer Schwarz/Weiß flackern lassen? Hast du mal versucht mit einer TStopWatch zu messen, welche Aufrufe hier so lange brauchen?
  Mit Zitat antworten Zitat
Benutzerbild von Delphi-Narr
Delphi-Narr

Registriert seit: 29. Aug 2009
Ort: Duisburg
437 Beiträge
 
Delphi 2007 Professional
 
#9

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 16. Apr 2013, 10:56
Also das von mir definierte ByteArray hat keine feste Größe, sondern kann dynamisch verändert werden.
Mit diesem Array aus Bytes kommt die DLL inzwischen auch wunderbar klar, wenn ich die Farben aus dem Bitmap32.Canvas.Pixels auslese und nicht aus Bitmap32.pixel
Somit wird die Anzeige jetzt recht flüssig dargestellt.
Wenn ich die gesamte Anzeige rausnehme (Sowohl das Erstellen als auch das Aufbereiten und Ausgeben), ist die CPU immernoch bei 7% - es liegt
anscheinend einfach daran, dass der Timer sehr sehr oft den Status der Buttons der G19 abfragt, um entsprechend zu reagieren.
Da währenddessen auch noch immer über eine OleVariant die aktuelle Titelposition, Name, Interpret, Album, Lautstärke etc. aus iTunes abgefragt werden, wird die CPU Auslastung
anscheinend doch hierbei erzeugt.
Die grafische Darstellung fällt dank Bitmap32 fast nicht mehr ins Gewicht.

Viele Grüße!
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: TBitmap32 in ByteArray (schneller) oder Alternative

  Alt 16. Apr 2013, 11:07
CPU-Auslastung gehört zu iTunes wie das Amen in der Kirche
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:06 Uhr.
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