AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Nach CopyMemory werden Daten nicht übernommen
Thema durchsuchen
Ansicht
Themen-Optionen

Nach CopyMemory werden Daten nicht übernommen

Ein Thema von EWeiss · begonnen am 5. Jan 2014 · letzter Beitrag vom 7. Jan 2014
Antwort Antwort
Seite 1 von 2  1 2      
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 05:55
Zitat:
AtmoLockTransferBuffer um den Pointer auf den Buffer zu holen
Nö sperrt den Transfer des Buffer (Lock)

Zitat:
Bei dir erzeugst du jedes mal den Buffer neu. Aber warum sollte das bei Verwendung von COM notwendig sein?
Weil das Bild sich jede MS ändert.
Ich habe es auch versucht mit einem Flag welches prüft ob die Funktion schon aufgerufen wurde.
Das Ergebnis war das die Anwendung einen AV gemeldet hat.
Daher gehe ich erstmal davon aus das es so sein muss.

AtmoCreateTransferBuffers
Wird der Header der Bitmap erstellt also vorbereitet zum senden.

Danach werden die Pixel gesendet mit AtmoSendPixelData.

Ich kann mir das aber nochmal genau anschauen ob ich dahingehend noch was ändern kann / muss.

Delphi-Quellcode:
// *********************************************************************//
// richtet den Pixeltransferbuffer für den LiveSource Modus mit externer Quelle ein.
// FourCC enthält dabei den Code wie die Pixeldatei aufgebaut sind - derzeit sind
// folgende Codes in AtmoWinA.exe implementiert - andere Codes werden einfach ignoriert.

// FourCC = "HSVI" steht für ein Bild was bereits in HSV Daten vorliegt...
// oder man übergibt die in Windows.h? definierte Konstante "BI_RGB" was
// signalisiert dass es sich um unkomprimierte Pixeldaten handelt.

// bytePerPixel = legt fest wieviel Byte ein Pixel benötigt
// für HSVI wird der Wert 3 erwartet.
// für BI_RGB sind die Werte 2, 3 oder 4 zulässig.
// für 2 ist RGB 565 definiert!
// width = Breite des Bildauszugs derzeit ist nur 64 zulässig!
// height = Höhe des Bildauszugs derzeit ist nur 48 zulässig!
// *********************************************************************//
procedure TAtmoCtrlLib.AtmoCreateTransferBuffers(FourCC, bytePerPixel, width,
  height: Integer);

begin

  if Assigned(PbitmapInfoArr) then
  begin
    SafeArrayDestroy(PbitmapInfoArr);
    PbitmapInfoArr := nil;
  end;

  PbitmapInfoArr := SafeArrayCreateVector(VT_UI1, 0, sizeof(BITMAPINFOHEADER));

  SafeArrayAccessData(PbitmapInfoArr, Pointer(pheader));
  pheader.biSize := sizeof(BITMAPINFOHEADER);
  pheader.biWidth := width;
  pheader.biHeight := height;
  pheader.biBitCount := bytePerPixel * 8;
  pheader.biCompression := FourCC;
  SafeArrayUnaccessData(PbitmapInfoArr);
end;
Danke für die Infos.

PS:
Da bin ich auch noch nicht hinter gestiegen was damit gemeint ist.
Zitat:
für BI_RGB sind die Werte 2, 3 oder 4 zulässig.
Was für einen Wert 2,3 oder 4 bei mir ist BI_RGB = 0 welche Werte sollte man dann da noch addieren.
Na ok! Ich denke die meinen damit die Anzahl der Bytes wie bei 24 Bit Bitmaps = 4 Byte
32 Bit Bitmaps werden dann ignoriert weil mehr als 4 Bytes
Etwas undurchsichtig


gruss

Geändert von EWeiss ( 7. Jan 2014 um 06:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 06:28
Da bin ich auch noch nicht hinter gestiegen was damit gemeint ist.
Zitat:
für BI_RGB sind die Werte 2, 3 oder 4 zulässig.
Was für einen Wert 2,3 oder 4 bei mir ist BI_RGB = 0 welche Werte sollte man dann da noch addieren.
Na ok! Ich denke die meinen damit die Anzahl der Bytes wie bei 24 Bit Bitmaps = 4 Byte
32 Bit Bitmaps werden dann ignoriert weil mehr als 4 Bytes
So wie ich das verstanden habe, beziehen sich 2, 3 und 4 auf den Wert den bytePerPixel haben kann, wenn FourCC auf BI_RGB gesetzt ist. Das heißt, du kannst in diesem Falle 16, 24 und 32 Bit Bitmaps verwenden.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 06:57
Hmmm hab es mit 32 Bitmaps versucht das geht nicht.
32 Bitmaps sind 8 Byte per Pixel (incl. Alpha Channel) Oder?

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 07:19
Hmmm hab es mit 32 Bitmaps versucht das geht nicht.
32 Bitmaps sind 8 Byte per Pixel (incl. Alpha Channel) Oder?
32 Bit Bitmaps sind 4 Byte pro Pixel. Jeweils 1 Byte für A, R, G und B.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 07:23
Hmmm hab es mit 32 Bitmaps versucht das geht nicht.
32 Bitmaps sind 8 Byte per Pixel (incl. Alpha Channel) Oder?
32 Bit Bitmaps sind 4 Byte pro Pixel. Jeweils 1 Byte für A, R, G und B.
Ich will dir ja gerne glauben .. Aber dann schreibt jeder etwas anderes.

Zitat:
32 bpp.. Das Format ist wie bei BI_BITFIELDS, wenn folgende Farbmasken verwendet würden: 0x00FF0000 für den Rot-Kanal0x0000FF00 für den Grün-Kanal0x000000FF für den Blau-Kanal.
Jeder Farbkanal ist 8 Bit pro Pixel groß; insgesamt ergeben sich 16.777.216 mögliche Farben (8 Bit sind ungenutzt).
Einige Programme wie etwa Adobe Photoshop interpretieren die verbleibenden 8 Bits (0xFF000000) als Alphakanal mit 256 möglichen Transparenzstufen.
Dies ist jedoch von der Spezifikation nicht vorgesehen.
Kann auch sein das ich leicht übermüdet bin ... hehehehee

gruss

Geändert von EWeiss ( 7. Jan 2014 um 07:28 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 07:37
Bist du. Da steht 8 Bit pro Pixel, was genau 1 Byte ist. Bit <> Byte. Es gibt keine Windows-Nativen Bitmaps mit mehr als 8 Bit/Pixel, und das sind eben 32Bit Bitmaps. Schon immer gewesen. Oftmals sind sogar 24Bit Bitmaps zu 32Bit Bitmaps identisch ausgerichtet weil es für den Zugriff deutlich günstiger ist als 3 Byte; das vierte bleibt dabei dann (wie das Wiki ja schon sagt) einfach unbenutzt.
(Und sei mal etwas unempfindlicher. Was ist falsch daran, sich mit den verfügbaren Tools mal auseinanderzusetzen? Hilfe zur Selbsthilfe nennt sich das. Wenn du jemanden dein Programm genau vorkauen lassen möchtest, leg wat aufn Tisch.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium ( 7. Jan 2014 um 07:39 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 07:41
Zitat:
Bit <> Byte
Arghh... yeah immer das gleiche mit mir sehe den Unterschied zwischen Bit und Byte.. nicht.

Danke für die Richtigstellung.
Zitat:
Und sei mal etwas unempfindlicher. Was ist falsch daran, sich mit den verfügbaren Tools mal auseinanderzusetzen?
Nichts.. Aber darauf hinzuweisen das man zu blöd ist zum debuggen schon..
Aber egal lassen wird das.

Zitat:
Wenn du jemanden dein Programm genau vorkauen lassen möchtest
Mein Programm? Nö ich mache das für die Leute bei MediaPortal (Hobby) und dafür will ich nichts
Warum sollte ich dann anderen was bezahlen?

gruss

Geändert von EWeiss ( 7. Jan 2014 um 07:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.055 Beiträge
 
Delphi 12 Athens
 
#8

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 08:05
Zitat:
AtmoLockTransferBuffer um den Pointer auf den Buffer zu holen
Nö sperrt den Transfer des Buffer (Lock)
Zitat:
sperrt den Transferbuffer für den aktuellen Thread und liefert einen Zeiger auf den
Speicherblock zurück.
Wo du das Array überhaupt mit der AtmoCtrlLib in Verbindung bringst, ist mir aus deinem letzten Quelltext auch nicht klar. Du rufst dort nur AtmoCtrlLib.AtmoCreateTransferBuffers auf und dann AtmoCtrlLib.AtmoSendPixelData. Bei beiden Aufrufen ist aber keinerlei Verbindung zu deinem Array involviert.

Deshalb würde ich erwarten, dass es in dem Objekt irgendwo auch ein Zugriff auf den Buffer möglich ist.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 08:12
Zitat:
Wo du das Array überhaupt mit der AtmoCtrlLib in Verbindung bringst, ist mir aus deinem letzten Quelltext auch nicht klar.
PpixelDataArr: PSafeArray = nil;

Ist global in der AtmoCtrl Unit definiert.

Delphi-Quellcode:
// *********************************************************************//
// schickt den Inhalt des Buffers an den COM Server der AtmoWinA.exe und hebt die Sperre
// des Buffers auf.
// *********************************************************************//
procedure TAtmoCtrlLib.AtmoSendPixelData; stdcall;
var
  pALVC: IAtmoLiveViewControl;

begin
  pALVC := getAtmoLiveViewControl;
  if Assigned(PpixelDataArr) and Assigned(pALVC) then
  begin
    SafeArrayUnaccessData(PpixelDataArr);
    pALVC.setPixelData(PbitmapInfoArr, PpixelDataArr);
  end;

  if Assigned(pALVC) then
  begin
    if Assigned(PpixelDataArr) then
    begin
      SafeArrayDestroy(PpixelDataArr);
      PpixelDataArr := nil;
    end;

    if Assigned(PbitmapInfoArr) then
    begin
      SafeArrayDestroy(PbitmapInfoArr);
      PbitmapInfoArr := nil;
    end;

    pALVC := nil;

  end;

end;
Delphi-Quellcode:
// *********************************************************************//
//sperrt den Transferbuffer für den aktuellen Thread und liefert einen Zeiger auf den
//Speicherblock zurück.
//Sollte die DLL noch nicht initialisiert oder kein Aufruf von AtmoCreateTransferBuffers
//im voraus erfolgt sein - liefert die Funktion "NULL"!
// *********************************************************************//
function TAtmoCtrlLib.AtmoLockTransferBuffer: Pointer; stdcall;
var
  pixelData: pByte;

begin
  if Assigned(PpixelDataArr) then
    SafeArrayAccessData(PpixelDataArr, Pointer(pixelData));

  result := pixelData;
end;
gruss

Geändert von EWeiss ( 7. Jan 2014 um 08:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 09:43
Da ich den Source nicht mehr wirklich durchblicke, habe ich mir schnell mal ein eigenes Testprogramm angelegt, welches soweit zu meiner Zufriedenheit funktioniert

Der Start des Live Bildes sieht etwa so aus:
Delphi-Quellcode:
procedure TAtmoWinLive.Start(Format: TPixelFormat);
begin
  if (not (Format in [pf16Bit, pf24Bit, pf32Bit])) then
  begin
    raise Exception.Create('Unsupported pixel format.');
  end;
  FFormat := Format;
  FAtmoWin.SetEffect(cemLivePicture, FOldEffect);
  FOldLiveViewSource := FAtmoWin.GetLiveViewSource;
  FAtmoWin.SetLiveViewSource(lvsExternal);
  CreateTransferBuffers;
  FInitialized := true;
end;
Die Transfer Buffer werden, wie schon von jaenicke korrekt vorgeschlagen, nur einmal pro "Session" erstellt und für jeden Frame wiederverwendet. Ebenfalls initialisiere ich hier ein internes Bitmap mit der von AtmoWin gelieferten Zielgröße:
Delphi-Quellcode:
procedure TAtmoWinLive.CreateTransferBuffers;
var
  W, H, ImageSize: Integer;
  Header: PBitmapInfoHeader;
begin
  FAtmoWin.GetLiveViewResolution(W, H);
  FBitmapHeader := SafeArrayCreateVector(VT_UI1, 0, SizeOf(TBitmapInfoHeader));
  if (not Assigned(FBitmapHeader)) then
  begin
    raise Exception.Create('Failed to create bitmap header buffer.');
  end;
  OleCheck(SafeArrayAccessData(FBitmapHeader, Pointer(Header)));
  try
    ZeroMemory(Header, SizeOf(Header));
    Header^.biSize := SizeOf(TBitmapInfoHeader);
    Header^.biWidth := W;
    Header^.biHeight := H;
    Header^.biPlanes := 1;
    case FFormat of
      pf16bit: Header^.biBitCount := 16;
      pf24bit: Header^.biBitCount := 24;
      pf32bit: Header^.biBitCount := 32;
    end;
    Header^.biCompression := BI_RGB;
    ImageSize := W * H * Header^.biBitCount;
  finally
    OleCheck(SafeArrayUnaccessData(FBitmapHeader));
  end;
  FBitmapData := SafeArrayCreateVector(VT_UI1, 0, ImageSize);
  if (not Assigned(FBitmapData)) then
  begin
    DestroyTransferBuffers;
    raise Exception.Create('Failed to create bitmap data buffer.');
  end;
  FBitmap := TBitmap.Create;
  FBitmap.PixelFormat := FFormat;
  FBitmap.Width := W;
  FBitmap.Height := H;
end;
Die eigentlichen Farbwerte sende ich mit folgender Funktion. Hierbei mache ich mir zu nutzen, dass die Berechnung der AmbiLight Farben im Grunde genommen ja nur auf der Berechnung des Durchschnittsfarbwertes für einen bestimmten Quadranten des Bildschirms beruht. Diese Berechnung nehme ich nicht per Hand vor, sondern benutze ein einfaches GDI StretchBlt im HALFTONE Mode. Danach werden die Pixel Daten in das entsprechende Array kopiert und an AtmoWin gesendet:
Delphi-Quellcode:
procedure TAtmoWinLive.Update(B: TBitmap);
var
  Data: Pointer;
  BPP, H: Integer;
begin
  if (not FInitialized) then Exit;
  if (B.PixelFormat <> FFormat) then
  begin
    raise Exception.Create('Invalid pixel format.');
  end;
  SetStretchBltMode(FBitmap.Canvas.Handle, HALFTONE);
  StretchBlt(FBitmap.Canvas.Handle, 0, 0, FBitmap.Width, FBitmap.Height, B.Canvas.Handle,
    0, 0, B.Width, B.Height, SRCCOPY);
  OleCheck(SafeArrayAccessData(FBitmapData, Data));
  try
    BPP := 2;
    case FFormat of
      pf24bit: BPP := 3;
      pf32bit: BPP := 4;
    end;
    for H := 0 to FBitmap.Height - 1 do
    begin
      {$WARNINGS OFF}
      CopyMemory(Pointer(NativeUInt(Data) + H * FBitmap.Width * BPP),
        FBitmap.ScanLine[H], FBitmap.Width * BPP);
      {$WARNINGS ON}
    end;
  finally
    OleCheck(SafeArrayUnaccessData(FBitmapData));
  end;
  FAtmoWin.SetLiveViewPixelData(FBitmapHeader, FBitmapData);
end;
Und schließlich wird beim Beenden des Live Bilds noch der vorher gesicherte Modus wiederhergestellt:
Delphi-Quellcode:
procedure TAtmoWinLive.Stop;
begin
  FInitialized := false;
  DestroyTransferBuffers;
  if (FOldLiveViewSource <> lvsExternal) then
  begin
    FAtmoWin.SetLiveViewSource(FOldLiveViewSource);
  end;
  if (FOldEffect <> cemLivePicture) then
  begin
    FAtmoWin.SetEffect(FOldEffect);
  end;
end;
@Emil: Wenn du magst, kannst du meine Klassen gerne für dein Projekt übernehmen. Im Grunde musst du nur die Update Funktion mit deinem DirectX Screenshot füttern

Viele Grüße
Zacherl
Angehängte Dateien
Dateityp: rar AtmoWin.rar (89,3 KB, 5x aufgerufen)
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  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 04:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz