Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Surface Stream (https://www.delphipraxis.net/178269-surface-stream.html)

EWeiss 28. Dez 2013 17:06


Surface Stream
 
Ich möchte mein Surface (nein nicht das man kaufen kann) also das von DirectX in einen Stream(TStream) kopieren.

Ich finde nur Möglichkeiten unter SlimDX

Zitat:

DataRectangle dr = s.LockRectangle(LockFlags.None);
DataStream gs = dr.Data;
Ich möchte das aber unter Delphi bewerkstelligen. DirectX

Was fehlt mir da .. :oops:

SDK SlimDX

Code:

namespace SlimDX
{
  // Summary:
  //     A DataRectangle provides supporting information for a SlimDX.DataStream whose
  //     data is organized within two dimensions (a rectangle).
  public class DataRectangle
  {
    // Summary:
    //     Initializes a new instance of the SlimDX.DataRectangle class.
    //
    // Parameters:
    //   pitch:
    //     The row pitch, in bytes.
    //
    //   data:
    //     The data.
    public DataRectangle(int pitch, DataStream data);

    // Summary:
    //     Gets the SlimDX.DataStream containing the actual data bytes.
    public DataStream Data { get; }
    //
    // Summary:
    //     Gets or sets the number of bytes of data between two consecutive (1D) rows
    //     of data.
    public int Pitch { get; set; }
  }
}
Code:
    // Summary:
    //     Reads a sequence of bytes from the current stream and advances the position
    //     within the stream by the number of bytes read.
    //
    // Parameters:
    //   buffer:
    //     An array of values to be read from the stream.
    //
    //   offset:
    //     The zero-based byte offset in buffer at which to begin storing the data read
    //     from the current stream.
    //
    //   count:
    //     The maximum number of bytes to be read from the current stream.
    //
    // Returns:
    //     The number of bytes read from the stream.
    //
    // Exceptions:
    //   System.NotSupportedException:
    //     This stream does not support reading.
    //
    //   System.ArgumentNullException:
    //     buffer is a null reference.
    //
    //   System.ArgumentOutOfRangeException:
    //     offset or count is negative.
    //
    //   System.ArgumentException:
    //     The sum of offset and count is greater than the buffer length.
    public override int Read(byte[] buffer, int offset, int count);

gruss

EWeiss 28. Dez 2013 19:21

AW: Surface Stream
 
Hab das Surface jetzt erst mal temporär in ein Bitmap gespeichert.
Das wird auf die Platte geschaufelt so alle 250 MS

wenn ich aber die Farben ermittle sind es immer die falschen ;)

Delphi-Quellcode:
function TCapX.GetColor(gs: TMemoryStream; List: TStrings): TColor;
var
  bu : Array[0..3] of byte;
  i: Integer;
  pos: Integer;
begin

  i := 0;
  r := 0;
  g := 0;
  b := 0;

  for pos := 0 to List.Count - 1 do
  begin
    gs.Position := strToInt(List.Strings[pos]);
    //gs.Seek(gs.Position, 4);
    gs.Read(bu, 0);
    r := r + bu[2];
    g := g + bu[1];
    b := b + bu[0];
    inc(I);
  end;

  Result := RGB2TColor(r div i , g div i , b div i);

end;
sorry hab da mit TMemoryStream noch nichts am hut gehabt.

Wollte die Funktion eigentlich so auslegen was aber mit Listen nicht funktioniert.

Delphi-Quellcode:
for Pos in List

gruss

sx2008 28. Dez 2013 19:38

AW: Surface Stream
 
Was ist das denn?
Delphi-Quellcode:
gs.Read(bu, 0);

1. sollte man
Delphi-Quellcode:
Readbuffer
statt Read verwenden und 2. muss das zweite Argument die Anzahl der zu lesenden Bytes enthalten (also sizeof(bu)).

himitsu 28. Dez 2013 19:46

AW: Surface Stream
 
Zitat:

Zitat von sx2008 (Beitrag 1241321)
1. sollte man
Delphi-Quellcode:
Readbuffer
statt Read verwenden

Read liest "maximal" soviele Bytes, wie angegeben und bei weniger (z.B. Ende des Streams) erkennt man das am Result, was er aber nicht auswertet.

ReadBuffer liest genau so viel, wie man angibt und bei weniger, gibt es eine Exception.

EWeiss 28. Dez 2013 20:07

AW: Surface Stream
 
hmm Danke nur was ist jetzt richtig ;)

gruss

EWeiss 28. Dez 2013 23:43

AW: Surface Stream
 
Sorry Change denke hab ne Lösung gefunden.

gruss

himitsu 29. Dez 2013 03:11

AW: Surface Stream
 
Was richtig ist ... das was man benötigt wird.

Wenn du Result selber auswerten willst, dann Read und wenn du einfach blind davon ausgehst, daß es geht und du nir im Fehlerfall eine automatische "Fehlerbehandlung" haben möchtest, dann ReadBuffer.


Keine Ahnung, was bei dem originalen Read der zweite Parameter ist (vermutlich der Anfang im ZielArray), aber im Delphi ist es die Länge, was im Original ganz bestimmt der 3. Parameter war.


Wegen dem Bitmap auf D:\
- Was ist, wenn es kein D: gibt, dieses nicht beschreibbar ist oder die Schreibrechte fehlen?
- Tipp: TPath.GetTempPath oder TPath.GetTempFileName aus IOUtils

EWeiss 29. Dez 2013 08:40

AW: Surface Stream
 
Danke ;)

ich vermisse die Funktion DirectX GraphicsStream man mag es nicht glauben scheint aber unter Delphi nicht zu existieren.

Zitat:

Keine Ahnung, was bei dem originalen Read der zweite Parameter ist (vermutlich der Anfang im ZielArray), aber im Delphi ist es die Länge, was im Original ganz bestimmt der 3. Parameter war.
JO den ich eigentlich (was meine Lösung war) mit GraphicsStream auslesen wollte.

Zitat:

aber im Delphi ist es die Länge, was im Original ganz bestimmt der 3. Parameter war
Delphi-Quellcode:
gs.ReadBuffer(bu, sizeof(bu));
Aber alle meine Farben sind falsch.

Aber die gibt es wieder nicht.
Dann wäre auch das schreiben auf die Platte hinfällig gewesen.

Delphi-Quellcode:
gs: GraphicsStream; // <<< Direct3D9?? nix
gs.Read(bu, 0, sizeof(bu));
Jetzt kann ich beides nicht verwenden
DirectX > GraphicsStream (DataStream in SlimDX)


gruss

Medium 29. Dez 2013 14:08

AW: Surface Stream
 
Sind nur die Farben falsch? Also eigentlich schon das richtige Bild? Dann hat dein Surface vermutlich nicht das Format ABGR wie es für die GDI üblich ist. Gängig wäre noch ARGB, da würde einfach B und R tauschen genügen. Da DX aber ja eine ganze Fülle an Farbformaten unterstützt, kommt es darauf an, wie du dein Surface angelegt hast.

EWeiss 29. Dez 2013 17:33

AW: Surface Stream
 
Zitat:

Zitat von Medium (Beitrag 1241358)
Sind nur die Farben falsch? Also eigentlich schon das richtige Bild? Dann hat dein Surface vermutlich nicht das Format ABGR wie es für die GDI üblich ist. Gängig wäre noch ARGB, da würde einfach B und R tauschen genügen. Da DX aber ja eine ganze Fülle an Farbformaten unterstützt, kommt es darauf an, wie du dein Surface angelegt hast.

Das Bild ist einwandfrei wenn ich es abspeichere
Das Problem ist die Farben zu ermitteln.

TFileStream und TMemoryStream stellen nur zwei Parameter zur Verfügung.

Delphi-Quellcode:
function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
property Position: Int64 read GetPosition write SetPosition;
Ich benötige aber 3 zum lesen
Code:
int DataStream::Read( array<Byte>^ buffer, int offset, int count )
{
   return ReadRange<Byte>( buffer, offset, count );
}

generic<typename T> where T : value class
int DataStream::ReadRange( array<T>^ buffer, int offset, int count )
{
   if( !m_CanRead )
      throw gcnew NotSupportedException();
   
   Utilities::CheckArrayBounds( buffer, offset, count );

   //Truncate the count to the end of the stream
   Int64 elementSize = static_cast<Int64>( sizeof(T) );
   size_t actualCount = min( static_cast<size_t>((Length - m_Position) / elementSize), static_cast<size_t>( count ) );

   pin_ptr<T> pinnedBuffer = &buffer[offset];
   memcpy( pinnedBuffer, m_Buffer + m_Position, static_cast<size_t>( actualCount * elementSize ) );
   m_Position += actualCount * elementSize;
   return static_cast<int>( actualCount );
}
   
Int64 DataStream::Position::get()
{
  return m_Position;
}

void DataStream::Position::set( System::Int64 value )
{
  Seek( value, System::IO::SeekOrigin::Begin );
}
Der DataStream kann nur unter .NET SlimDX benutzt werden.
GraphicsStream gibt es unter Delphi nicht auch dieser hat 3 Parameter.

Deshalb habe ich auch mit Seek versucht auf die richtige Position zu kommen
aber ohne ansprechendes Ergebnis.

Zitat:

//Truncate the count to the end of the stream
Hmm Das macht mich etwas stutzig.
Wird hier der Stream von hinten gelesen?

Eine andere Variante mit "pos in posin"

Delphi-Quellcode:
function TCapX.GetColor(gs: TFileStream; List: TStrings): COLORREF;
var
  bu : Array[0..3] of byte;
  i, n: Integer;
  pos: Integer;
  posin: Array of Integer;
begin

  i := 0;
  r := 0;
  g := 0;
  b := 0;

  SetLength(posin, List.Count);
  for n := 0 to List.Count - 1 do
    posin[n] := StrToInt(List.Strings[n]);

  for pos in posin do
  begin
    gs.Position := pos; //StrToInt(List.Strings[pos]);
    gs.Read(bu, sizeof(bu));
    r := r + bu[2];
    g := g + bu[1];
    b := b + bu[0];
    inc(I);
  end;

  Result := ColorARGB(255, RGB(r div i , g div i , b div i));
  FillChar(posin, SizeOf(posin), 0);

end;
Macht aber keinen unterschied..
Ich glaube langsam das die Streams hier das Problem verursachen.
Normalerweise müsste das letzte Byte bu[3] immer 255 sein da es den AlphaChannel repräsentiert.
Ist es aber nicht.

gruss

sx2008 29. Dez 2013 20:10

AW: Surface Stream
 
Um jetzt vielleicht die
Delphi-Quellcode:
Read()
versus
Delphi-Quellcode:
ReadBuffer()
Diskussion abzuschliesen:
Delphi-Quellcode:
// Das ist der Sourcecode von ReadBuffer
procedure TStream.ReadBuffer(var Buffer; Count: Longint);
begin
  if (Count <> 0) and (Read(Buffer, Count) <> Count) then
    raise EReadError.CreateRes(@SReadError);
end;
Wie man sieht, wird eine Exception geworfen wenn man mehr Bytes lesen möchte als der Stream liefern kann.
Das ist ein äusserst nützliches Sicherheitsfeature. :thumb:
Wenn ein Programmierer z.B. eine Struktur aus einer Datei liest aber die Datei nicht genügend Bytes dafür hat dann hat das sehr unangenehme Folgen.
Die fehlenden Bytes sind dann einfach undefiniert was zu extrem schwer zu findenden Bugs führt.

Wann immer man die Funktionen
Delphi-Quellcode:
Read()
oder
Delphi-Quellcode:
Write()
benützt ist man verpflichtet den Returnwert auszuwerten.
Tut man das nicht handelt man grob fahrlässig.
Das ist vergleichbar mit einem PKW-Fahrer der seinen Sicherheitsgurt nicht benützt obwohl er direkt neben seiner Schulter hängt.

Ich habe hier auf der DP noch nie Sourcecode gesehen, der den Returnwert von Read() oder Write() korrekt auswertet.
Diese Leute möchte ich am liebsten durchschütteln und zurufen "Anschnallen! Nehmt den Sicherheitsgurt!". :wall:


Bleibt vielleicht noch eine Frage offen:
Warum hat Borland die Funktionen
Delphi-Quellcode:
Read()
und
Delphi-Quellcode:
Write()
dann überhaupt
Delphi-Quellcode:
public
gemacht,
Delphi-Quellcode:
protected
hätte ja auch gereicht ?
Nun, neben dem häufig verwendeten
Delphi-Quellcode:
TFileStream
gibt es auch Streams, bei denen man nicht im Vorraus weiss oder erwartet wieviele Bytes denn noch vorhanden sind.
Man liest auf Verdacht einen grossen Block (z.B. 4kB) und wertet dann den Returncode aus weil man sich im Klaren darüber ist dass auch 0 Bytes gelesen worden sein könnten.

Zacherl 29. Dez 2013 20:40

AW: Surface Stream
 
Keine Ahnung, was du bisher hast, aber zum Auslesen der Bildinformationen kannst du IDirect3DSurface9::LockRect verwenden. Dann schreibst du den Wert aus LockedRect.Bits komplett in den Stream (Gröse = Surface.Width * Surface.Height * BytesPerPixel). Bei ARGB (oder jedem anderen "4 Byte per Pixel" Format) musst du den zum padden verwendeten Pitch Wert nicht beachten.

Um jetzt an die einzelnen Pixel zu kommen, berechnest du erstmal die Position des Pixels:
Stream.Position := (YPos * Surface.Width + XPos) * 4;

Danach liest du ein komplettes DWord aus:
Stream.ReadBuffer(Pixel, 4);

Und schließlich decodierst du den Pixel folgendermaßen über eine simple Bitmaske:
Delphi-Quellcode:
procedure COLOR_DECODE_ARGB(Color: DWord; var A, R, G, B: Byte); inline;
begin
  A := (Color and $FF000000) shr 24;
  R := (Color and $00FF0000) shr 16;
  G := (Color and $0000FF00) shr 8;
  B := (Color and $000000FF);
end;

EWeiss 29. Dez 2013 20:55

AW: Surface Stream
 
Zitat:

Zitat von Zacherl (Beitrag 1241401)
Keine Ahnung, was du bisher hast, aber zum Auslesen der Bildinformationen kannst du IDirect3DSurface9::LockRect verwenden. Dann schreibst du den Wert aus LockedRect.Bits komplett in den Stream (Gröse = Surface.Width * Surface.Height * BytesPerPixel). Bei ARGB (oder jedem anderen "4 Byte per Pixel" Format) musst du den zum padden verwendeten Pitch Wert nicht beachten.

Um jetzt an die einzelnen Pixel zu kommen, berechnest du erstmal die Position des Pixels:
Stream.Position := (YPos * Surface.Width + XPos) * 4;

Danach liest du ein komplettes DWord aus:
Stream.ReadBuffer(Pixel, 4);

Und schließlich decodierst du den Pixel folgendermaßen über eine simple Bitmaske:
Delphi-Quellcode:
procedure COLOR_DECODE_ARGB(Color: DWord; var A, R, G, B: Byte); inline;
begin
  A := (Color and $FF000000) shr 24;
  R := (Color and $00FF0000) shr 16;
  G := (Color and $0000FF00) shr 8;
  B := (Color and $000000FF);
end;

Danke .. Hab ich alles schon

Ich speichere das Bitmap
Delphi-Quellcode:
D3DXSaveSurfaceToFileW('D:\paper.bmp', D3DXIFF_BMP, scrSurface, nil, @ARect);


lade es zurück.. in den Stream
Delphi-Quellcode:
gs := TFileStream.Create('D:\paper.bmp', fmOpenRead or fmShareDenyNone);


und werte es mit meiner function GetColor aus.

Das Ergebnis ist aber nicht das was auf die Platte geschrieben wurde denn dann müßten die Farben stimmen.


Delphi-Quellcode:
pos := (y * Screen.PrimaryMonitor.BoundsRect.Right + x) * 4;
Stream.Position := pos
Delphi-Quellcode:
bu : Array[0..3] of byte;
gs.Read(bu, sizeof(bu));
Delphi-Quellcode:
function ColorARGB(AlphaChannel: byte; ColrRGB: COLORREF): COLORREF;
var
  bytestruct: COLORBYTES;
begin

  bytestruct.A := AlphaChannel;
  bytestruct.R := GetRValue(ColrRGB);
  bytestruct.G := GetGValue(ColrRGB);
  bytestruct.B := GetBValue(ColrRGB);

  Result := MakeColor(bytestruct.A, bytestruct.R, bytestruct.G, bytestruct.B);
end;
IDirect3DSurface9::LockRect brauche ich nicht da die Daten über D3DXSaveSurfaceToFileW abgespeichert werden.
Aber auch damit habe ich es versucht.
Delphi-Quellcode:
  p := Cardinal(LockedRect.pBits);

  for i := 0 to Screen.Height - 1 do
  begin
    CopyMemory(BMP.ScanLine[i], Ptr(p), Screen.Width * BitsPerPixel div 8);
    p := p + LockedRect.Pitch;
  end;
Und dann das BMP in eine Datei geschrieben.
Wie ich das jetzt direct in den Stream schreibe ist mir noch nicht klar. (so das ich sie im Speicher habe)

aber alle Versuche schlagen fehl die Farben stimmen nicht.
Sobald ich diese wieder einlade.

gruss

Zacherl 29. Dez 2013 21:01

AW: Surface Stream
 
Versuche mal bitte die Daten wirklich per LockRect in den Stream zu schreiben und nicht den Umweg über das Bitmap zu nehmen. Hierbei lädst du dir nämlich zusätzlich den Bitmap Header in deinen Stream. Wenn die Länge des Bitmap Headers nicht durch 4 teilbar ist, sorgt das dafür, dass sämtliche Pixelinformationen verschoben werden. Desweiteren bin ich mir nicht sicher, ob die D3DX... Funktion das Bitmap nicht einfach (ohne Alpha Channel) als 24-Bit Bitmap speichert.

EWeiss 29. Dez 2013 21:04

AW: Surface Stream
 
Zitat:

Zitat von Zacherl (Beitrag 1241403)
Versuche mal bitte die Daten wirklich per LockRect in den Stream zu schreiben und nicht den Umweg über das Bitmap zu nehmen. Hierbei lädst du dir nämlich zusätzlich den Bitmap Header in deinen Stream. Wenn die Länge des Bitmap Headers nicht durch 4 teilbar ist, sorgt das dafür, dass sämtliche Pixelinformationen verschoben werden. Desweiteren bin ich mir nicht sicher, ob die D3DX... Funktion das Bitmap nicht einfach (ohne Alpha Channel) als 24-Bit Bitmap speichert.

Danke..

Würde ich gerne tun nur habe ich mit streams noch nicht die Erfahrung..
Wie kann ich die Daten direkt da reinschreiben ohne Umweg auf die Platte?

Zitat:

dass sämtliche Pixelinformationen verschoben werden.
Davon muss ich mittlerweile ausgehen denn ansonsten müßten die Daten ja stimmen
da mein Bitmap ansich richtig dargestellt wird.


gruss

Zacherl 29. Dez 2013 21:12

AW: Surface Stream
 
Nur auf die Schnelle geschrieben und ungetestet. Sollte aber so in der Art funktionieren:

Delphi-Quellcode:
var
  LockedRect: TD3DLockedRect;
  MS: TMemoryStream;
  I: Integer;
  Color: DWord;
  A, R, G, B: Byte;
begin
  MS := TMemoryStream.Create;
  try
    if (Surface.LockRect(LockedRect, nil, D3DLOCK_READONLY) = D3D_OK) then
    try
      for I := 0 to SurfaceHeight - 1 do
      begin
        // Pitch = Anzahl Bytes per "Zeile", also SurfaceWidth * SizeOf(Pixel)
        MS.WriteBuffer(Pointer(NativeUInt(LockedRect.pBits) + I * LockedRect.Pitch)^, LockedRect.Pitch);  
      end;
    finally
      Surface.UnlockRect;
    end;
    // Pixel (24,6) auslesen [*4 ausgehend davon, dass das PixelFormat = ARGB ist]
    MS.Position := (6 * SurfaceWidth + 24) * 4;
    MS.ReadBuffer(Color, SizeOf(Color));
    COLOR_DECODE_ARGB(Color, A, R, G, B);
    // ..
  finally
    MS.Free;
  end;
end;

EWeiss 29. Dez 2013 21:16

AW: Surface Stream
 
Das ist nett von dir werde es mal testen.

gruss

EWeiss 29. Dez 2013 21:37

AW: Surface Stream
 
Danke für deine Hilfe

Hmmm... jetzt geht's nach einer kleinen Anpassung der Farbkonvertierung.
Jetzt muss ich mal sehen was da mit meiner Funktion im argen ist.

gruss

EWeiss 30. Dez 2013 00:25

AW: Surface Stream
 
Zitat:

@Zacherl
Danke nochmal für deine Hilfe die Daten in den MemoryStream zu packen.
Wer es Testen will Bitte schön.

Es wird nichts auf die platte geschaufelt.
das Teil emuliert Ambilight und soll nachher in meiner Lib als Dummy Window arbeiten.

PS: Man sollte schon einen bewegten Desktop haben..
Also Winamp starten Milkdrop im Desktop Modus verwenden und das Teil hier starten.

Ob man da an der Auslastung noch was Kitzeln kann?

gruss

Medium 30. Dez 2013 01:40

AW: Surface Stream
 
Das Problem mit deiner Funktion ist einfach, dass du das Bild als Windows-Bitmap speicherst, aber beim laden davon ausgehst, dass in der Datei die Rohdaten der Quell-Streams stehen. Tun sie aber nicht, da das Bitmap-Format zum einen einen eigenen Header (Meta-Daten vor den eigentlichen Bilddaten) in die Datei bringt, und zudem der Standard nicht alle Pixelformate vorsieht, die ein DX Surface haben könnte, weshalb da im schlimmsten Fall sogar noch konvertiert wird. Der Dateiinhalt hat nachher also potenziell kaum noch etwas mit den ursprünglichen Rohdaten im Surface-Buffer gemein.

Wenn du mittels eines Filestreams die Datei liest, und darin gerne genau die Rohdaten des Surfaces haben willst, musst du diese auch genau so in die Datei schreiben - nicht in ein Windows-Bitmap umgewandelt. Entsprechende Stream-Klassen gibt es in C#, und die arbeiten sehr ähnlich wie in Delphi. Da gibt es also einigen Wiedererkennungswert im Umgang. Praktischerweise ist das was SlimDX da liefert ja schon ein Stream :)

Edit: Eventuell ließe sich die IPC hier am besten mit einer Bei Google suchenNamed Pipe, statt einer Datei lösen. Erleichtert vor allem das Gehampel mit den Zugriffsmodi wenn 2 Prozesse um sie dauernd konkurrieren, ist aber im Umgang einer Datei nicht unähnlich, und ohne viel Zutun schon sehr "Stream-Freundlich".

Edit2: Ich hatte es bis gerade so verstanden, dass du ein Surface aus einer C#-Anwendung in eine Delphi-Anwendung schaufeln willst. Ich glaube, da habe ich geirrt :stupid:. Vergiss in diesem Fall mein Edit einfach. Ich war von der Nutzung einer Datei für den Datenaustausch innerhalb ein und des selben Prozesses und dem ganzen geposteten C#-Code ggf. verwirrt.

EWeiss 30. Dez 2013 11:35

AW: Surface Stream
 
Zitat:

Ich hatte es bis gerade so verstanden, dass du ein Surface aus einer C#-Anwendung in eine Delphi-Anwendung schaufeln willst.
Ich wollte von vornherein einen Stream für die Rohdaten verwenden.

Zitat:

Ich möchte mein Surface (nein nicht das man kaufen kann) also das von DirectX in einen Stream(TStream) kopieren.
Ich finde nur Möglichkeiten unter SlimDX
Und das ist es wobei Zacherl mir geholfen hat ;)
Ich war etwas konfus das GraphicStream von Ms aus der DX Bibliothek in Delphi nicht zu finden war.
Hab dann nach alternativen gesucht wie DataStream von SlimDX und habe dabei ganz einfach übersehen das
die Stream Function Ansicht genau vor meiner Nase lagen.

Auf die Platte wird nichts mehr gespeichert ;)
Alles in einem MemoryStream..

gruss

EWeiss 30. Dez 2013 14:01

AW: Surface Stream
 
noch einen Nachtrag..

Zitat:

Das Problem mit deiner Funktion ist einfach, dass du das Bild als Windows-Bitmap speicherst, aber beim laden davon ausgehst, dass in der Datei die Rohdaten der Quell-Streams stehen. Tun sie aber nicht, da das Bitmap-Format zum einen einen eigenen Header (Meta-Daten vor den eigentlichen Bilddaten) in die Datei bringt, und zudem der Standard nicht alle Pixelformate vorsieht, die ein DX Surface haben könnte, weshalb da im schlimmsten Fall sogar noch konvertiert wird. Der Dateiinhalt hat nachher also potenziell kaum noch etwas mit den ursprünglichen Rohdaten im Surface-Buffer gemein.
Das Problem ist eher ein anderes..
Die Farben die nun ermittelt werden muss ich quasi als Quader auf ein Bitmap zeichnen
diese wird dann gestaucht auf eine Größe von 64x48 und anschließend als Bitmap nach AtmoWin geschickt.
Als Bitmap deswegen weil die den Header erwarten!

Code:
BinaryReader reader = new BinaryReader(stream);
 stream.Position = 0; // ensure that what start at the beginning of the stream.
 reader.ReadBytes(14); // skip bitmap file info header
 byte[] bmiInfoHeader = reader.ReadBytes(4 + 4 + 4 + 2 + 2 + 4 + 4 + 4 + 4 + 4 + 4);
 byte[] pixelData = reader.ReadBytes((int)(stream.Length - stream.Position));
 atmoLiveViewCtrl.setPixelData(bmiInfoHeader, pixelData);
Ich war vorher davon ausgegangen das Ursprungs Bild zu verkleinern aber das wäre ja quatsch gewesen deshalb war meine Annahme diese vorher auf die Platte zu schreiben schlichtweg falsch.
Nur die Farbfragmente sind wichtig.
Aber ob ich das Bild dann auch auf die Platte speichern muss wird sich erst noch zeigen.

gruss

Medium 30. Dez 2013 14:13

AW: Surface Stream
 
Fein, jetzt hab ich den Faden endgültig verloren :lol: Aber wenn's nun klappt, macht das ja nichts :)

EWeiss 30. Dez 2013 14:18

AW: Surface Stream
 
Zitat:

Zitat von Medium (Beitrag 1241467)
Fein, jetzt hab ich den Faden endgültig verloren :lol: Aber wenn's nun klappt, macht das ja nichts :)

Ach was soll's macht ja nichts.
Letztendlich bin ich über jede Hilfe Dankbar man kann nicht alles beherrschen (will aber so vieles tun).

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:33 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