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 4 von 4   « Erste     234   
EWeiss
(Gast)

n/a Beiträge
 
#31

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 09: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 09:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 10: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
EWeiss
(Gast)

n/a Beiträge
 
#33

AW: Nach CopyMemory werden Daten nicht übernommen

  Alt 7. Jan 2014, 17:46
@Zacherl

Zitat:
@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
Aber gerne doch wenn Sie Vorteile für (mein) das Programm bringt

gruss

Geändert von EWeiss ( 8. Jan 2014 um 01:24 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 4   « Erste     234   


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 22:49 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