Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Bild als String übertragen? (https://www.delphipraxis.net/125811-bild-als-string-uebertragen.html)

LDericher 12. Dez 2008 10:37


Bild als String übertragen?
 
Hallo DP!

Ich stehe vor folgendem Problem:
Ich möchte eine Art Netzwerk-Fernsteuerung programmieren, also möchte Maus/Tastatur und so kontrollieren.
Funktioniert auch so weit. Gesendet wird über eine Ableitung der Klasse - heißt glaube ich TWinSocket.
Nun habe ich vor, mir Screenshots übertragen zu lassen, die ich im Bitmap-Format vorliegen habe. Ggf. kann ich die dann natürlich konvertieren, weiß auch wie.

Also: Ich kann Daten allerdings (bis jetzt?) nur als STRING senden und empfangen. Demnach: Ist es möglich - relativ schnell - ein Bild in einen "normalen" String umzuwandeln und umgekehrt, sodass ich meine Screenshots übertragen bekomme?

Gruß,
Euer LDer.

P.S.: Ich habe in dem Zusammenhang "MIME" gehört... Weiß aber noch nichts genaueres damit anzufangen.

turboPASCAL 12. Dez 2008 10:46

Re: Bild als String übertragen?
 
Du kannst das Bild, was ja wie du weisst aus Daten, also Bytes besteht in Chars oder besser in Hexadezimalwerte umwandels und somit als ein String übertragen.
ZB. mit Delphi-Referenz durchsuchenIntToHex().

Zitat:

Ist es möglich - relativ schnell - ein Bild in einen "normalen" String umzuwandeln und umgekehrt, sodass ich meine Screenshots übertragen bekomme?
Das kommt nun auf die Bildgrösse und die Rechnergeschw. sowie die Datenübertragungsgeschw. an.
Wenn ein Bild in einen String umgewandelt werden zB. wie oben beschrieben mit IntToHex entseht eine doppelte Datenmenge.

Besser ist es die oder das Bild direkt also ohne umwandlung in einen String zu Übertragen. Auch dies kann bei grossen Bildern eine Weile
Beanspruchen.

SirThornberry 12. Dez 2008 11:35

Re: Bild als String übertragen?
 
das wandeln kann man sich doch eigentilch sparen und direkt die Binärdatein senden (sind ja letzendlich auch nur chars)

LDericher 12. Dez 2008 12:48

Re: Bild als String übertragen?
 
Sorry wenn ich so blöd frage, aber wie komme ich an die Binärdaten? Les ich da irgendwie den Speicher mithilfe des Zeigers aus? Oder steh ich grad mal auf'm Sclauch?

Also es ist nicht auf der Festplatte gespeichert, nur im Arbeitsspeicher (als Zeigervariable vom Typ TBitmap)

Der LDer

SirThornberry 12. Dez 2008 13:13

Re: Bild als String übertragen?
 
In einem String stehen die Bytes eben so hintereinander wie in einem Array of Byte, Array of Integer etc. Es ist immer nur eine Frage wie man das was da im Speicher steht interpretiert. Wenn du einen String versendest wird ja auch nur Zeichen1 + zeichen2... versendet.

LDericher 12. Dez 2008 13:45

Re: Bild als String übertragen?
 
Bitte,

Meine Frage bezog sich auf das Bitmap!
Dass ich einen STRING als array of Char sehen kann, ist mir wohl bekannt ;)
Aber wie lese ich ein BITMAP binär aus?
Und sagt bitte setzt mir nicht solche Gurken vor wie String := String + Chr(Bitmap[Index])...

Der LDer

turboPASCAL 12. Dez 2008 13:55

Re: Bild als String übertragen?
 
Nochmal doof gefragt, Bitmap nach String oder andersrum ? :gruebel:

LDericher 12. Dez 2008 13:59

Re: Bild als String übertragen?
 
Erst so rum, dann anders rum.

Also wenn irgendwer ne vernünftige Idee hat, nen Bitmap - als Variable im Speicher - in einen regulären String umzuwandeln(/verschlüsseln/wie auch immer) - dann kann ich diese Methode ja auch "umkrempeln".

Mir geht es wie gesagt darum, einen Screenshot zu machen, den in ein TBitmap zu laden, in einen String umzuwandeln, zu versenden und wieder ein TBitmap draus zu basteln.

Hoffe ich werde jetzt verstanden.

Lg vom LDer.

Cyf 12. Dez 2008 14:03

Re: Bild als String übertragen?
 
Zitat:

Aber wie lese ich ein BITMAP binär aus?
Du liest die Bytes hintereiander in einen Buffer? (oder sendest direkt den vorhandenen)
Idealerweise nicht einzeln sondern mit einem Befehl, der dir möglichst den Zugriff auf den Speicherbereich gibt?
Am einfachsten wäre wohl ein SaveToStream, da du sicher auch noch die Formatdaten brauchst (Farbtiefe, etc.) und dann aus dem Stream senden.

[Edit]
Zitat:

in einen regulären String umzuwandeln
Das ist kein Unterschied, das eine sind (bei nicht Unicode) einzelne Bytes, das andere auch.
Beim string-Typ gibt es nur zusätzliche Angaben über Länge und Referenzzählung.

turboPASCAL 12. Dez 2008 14:18

Re: Bild als String übertragen?
 
Zitat:

SaveToStream
Verflix, zu lahm.

Ich würde auch einfach die Streamvariante nehmen sie wird ja selbst vom TBitmap unterstützt. ( <Image>.Picture.Bitmap.SaveToStream )

inherited 12. Dez 2008 14:24

Re: Bild als String übertragen?
 
Ich halte es für keine gute Idee das als Bitmap zu senden. Lieber vorher konvertieren in png o.ä.

LDericher 12. Dez 2008 14:41

Re: Bild als String übertragen?
 
schon gut...
kenne mich mit streams jetz aber net sooo doll aus, muss selten damit arbeiten - hat da jemand ne idee aus nem stream (hab nen TMemoryStream genommen) die Daten als string auszulesen? Sorry, habe gerade leider nich die Ruhe mir das komplett selbst zu erarbeiten -.-

LDer

LDericher 12. Dez 2008 14:47

Re: Bild als String übertragen?
 
Anders: Wie komme ich an die ersten x bytes in einem Stream?

mkinzler 12. Dez 2008 14:51

Re: Bild als String übertragen?
 
Indem du die Anzahl als Parameter im .Read() angibst

LDericher 12. Dez 2008 14:55

Re: Bild als String übertragen?
 
Delphi-Quellcode:
procedure BitmapGurke(Input:TBitmap);
var
  P:TMemoryStream;
  test:integer;
begin
P:=TMemoryStream.Create;
Input.SaveToStream(P);
test:=0;
P.Read(test, 4);
ShowMessage(inttostr(test));
P.Free;
end;
sollte eigentlich funktionieren, gibt aber immer 0 aus -.-

Klaus01 12. Dez 2008 14:58

Re: Bild als String übertragen?
 
Delphi-Quellcode:
procedure BitmapGurke(Input:TBitmap);
var
  P:TMemoryStream;
  test:integer;
begin
P:=TMemoryStream.Create;
Input.SaveToStream(P);
test:=0;
p.Position:=0;
P.Read(test, SizeOf(Integer));
ShowMessage(inttostr(test));
P.Free;
end;
Habe in Deinem Code mal herumeditiert.

Grüße
Klaus

mkinzler 12. Dez 2008 14:59

Re: Bild als String übertragen?
 
Versuch mal
Delphi-Quellcode:
P.Read(@test, 4);

LDericher 12. Dez 2008 15:01

Re: Bild als String übertragen?
 
:wall: :wall: :wall: :wall: :wall: :wall: :wall: :wall: :wall:
Ich hätte nuuuur die Stream.Position auf 0 setzen müssen -.-
es geht!
Ich krieg den Rest nun auch alleine hin!
Danke nochmal!

Euer eLDer!

LDericher 12. Dez 2008 16:56

Re: Bild als String übertragen?
 
Verdampft! :x

Ich krieg' noch zu viel bei dem Mist :D
Ich versuch es jetz wieder - über den Stream - in nen String zu packen - komm aber nicht gut dabei weg. Hat wer nen akuten Einfall?
(->Problem: Inhalt eines TMemoryStream in einen string laden)

Ich habe es auch schon mit TStringStream versucht - Geht nicht!

(->mache neues Thema auf hier!)

turboPASCAL 12. Dez 2008 18:36

Re: Bild als String übertragen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Och manno.... ;)

Delphi-Quellcode:
var
  strBitmap: string;

function BitmapToString(InputBmp: TBitmap; var outString: String): BOOL;
var
  ms: TMemoryStream;
begin
  Result := FALSE;
  outString := '';

  ms := TMemoryStream.Create;
  try
    ms.Position := 0;
    InputBmp.SaveToStream(ms);
    SetString(outString, PChar(ms.Memory), ms.Size);

    Result := TRUE;
  finally
    ms.Free;
  end;
end;

function BitmapFromString(OutputBmp: TBitmap; inString: String): BOOL;
var
  ms: TMemoryStream;
begin
  Result := FALSE;

  ms := TMemoryStream.Create;
  try
    ms.Position := 0;
    ms.WriteBuffer(inString[1], length(inString));
    ms.Position := 0;

    OutputBmp.LoadFromStream(ms);
    inString := '';

    Result := TRUE;
  finally
    ms.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  BitmapToString(Image1.Picture.Bitmap, strBitmap);

  BitmapFromString(Image2.Picture.Bitmap, strBitmap);
  Self.Invalidate;
end;

LDericher 12. Dez 2008 19:15

Re: Bild als String übertragen?
 
Delphi-Quellcode:

function BitmapToString(b: TBitmap): String;
var ms: TMemoryStream;
  a: Int64;
  i:integer;
  buffer: Array[0..1024] of Byte;
begin
  result := '';
  ms := TMemoryStream.Create;
  try
    b.SaveToStream(ms);
    ms.Position:=0;
    a := 1;
    while a <> 0 do
    begin
      a := ms.read(buffer[0], length(buffer));
      for i := 0 to a-1 do
      begin
        result := result + IntToHex(buffer[i], 2);
      end;
    end;
  finally
    ms.Free;
  end;
end;

function StringToBitmap(Input:string):TBitmap;
var
  P:TMemoryStream;
  I:integer;
  B:Byte;
begin
P:=TMemoryStream.Create;
I:=1;
while(I<=Length(Input))do
     begin
     B:=StrToInt('$'+copy(Input, I, 2));
     P.Write(B, 1);
     inc(I, 2);
     end;
P.Position:=0;
Result:=TBitmap.Create;
Result.LoadFromStream(P);
P.Free;
end;
Das geht genauso wie deins, Deddy ;)
Gelöst!

Thx vom LDer!

turboPASCAL 12. Dez 2008 19:27

Re: Bild als String übertragen?
 
Meines ist schon schneller, gelle. ;)

Luckie 12. Dez 2008 19:49

Re: Bild als String übertragen?
 
Also irgndwie macht ihr da Quatsch. Mit den Sockets kann man auch binäre Daten übertragen, da bin ich mir ziemlich sicher. Und wenn es schon als String sein muss, warum codiert ihr die Datei nicht in BaseXX oder so was?

inherited 12. Dez 2008 20:00

Re: Bild als String übertragen?
 
Tun wir doch? :gruebel:
Der Threadersteller hatte vorgegeben, dass es per String sein soll. Was weiß denn ich warum :stupid:

LDericher 13. Dez 2008 11:45

Re: Bild als String übertragen?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ich bin so weit durch damit:
Angelegt zwei Units, mit denen sich Grafiken in Strings verwandeln lassen.

LDer.

LDericher 13. Dez 2008 12:06

Re: Bild als String übertragen?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Nochmal verfeinert: Bei beiden Units habe ich nun BASE64-Strings aktiviert.
Also BitmapToBaseString/JPEGToBaseString liefern nun die kleinsten Daten.

Sunlight7 13. Dez 2008 14:58

Re: Bild als String übertragen?
 
Zitat:

Zitat von Luckie
Also irgndwie macht ihr da Quatsch. Mit den Sockets kann man auch binäre Daten übertragen, da bin ich mir ziemlich sicher.

Da hat er recht, einfach mal Delphi-Referenz durchsuchenSendBuf verwenden, erspart das unnötige hin und her rechnen ;)


Edit:
Delphi-Quellcode:
for i := 0 to a-1 do
   result := result + IntToHex(buffer[i], 2);
Aua, das tut dem Speichermanager richtig weh...

Delphi-Quellcode:
for i := 0 to a-1 do
   AppendStr(Result, IntToHex(buffer[i], 2));

sx2008 13. Dez 2008 17:19

Re: Bild als String übertragen?
 
Es gibt ja auch den TStringStream.
Damit wird's kurz & knackig:
Delphi-Quellcode:
function BitmapToString(Input: TBitmap): String;
var ms: TStringStream;
begin
  ms := TStringStream.Create('');
  try
    Input.SaveToStream(ms);
    Result := ms.DataSring;
  finally
    ms.Free;
  end;
end
Für die Umkehrfunktion bitte beachten, dass man dem StringStream im Konstruktor einen Inhalt mitgeben kann.

Cyf 13. Dez 2008 20:29

Re: Bild als String übertragen?
 
Was nichts daran ändert, dass es keinen Sinn macht hin und her zu rechnen.

Apollonius 13. Dez 2008 20:40

Re: Bild als String übertragen?
 
Zitat:

Zitat von Sunlight7
Delphi-Quellcode:
for i := 0 to a-1 do
   AppendStr(Result, IntToHex(buffer[i], 2));

Zitat:

Zitat von SysUtils.pas
Delphi-Quellcode:
procedure AppendStr(var Dest: string; const S: string);
begin
  Dest := Dest + S;
end;


Sunlight7 13. Dez 2008 22:35

Re: Bild als String übertragen?
 
Scheint wohl in neueren Delphis anders zu sein


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