Delphi 2010

I'm Transferring Image via custom TCP Socket control uses UTF-8

Client Side

var
TSS: TStringStream;
STR :String;
JPG:TJPEGImage;
BMP:TBitmap;
begin
Try
BMP.LoadFromFile('C:\1.bmp');

JPG.Assign(BMP);
JPG.CompressionQuality:=80;
JPG.Compress;

TSS:=TStringStream.Create;
JPG.SaveToStream(TSS);

STR:=TSS.DataString;

MyTCPSocket.SendString(STR);


finally
BMP.free;
JPG.free;
TSS.free;
end;
end;

Server Side

Var
TSS: TStringStream;

TSS:=TStringStream.Create;
TSS.WriteString(STR);
TSS.SaveToFile('C:\2.jpg');

This code working on the same pc great.

The problem when I send the image to other pc that uses different encoding it receive the image but I see many wrong characters in the data "?????"

I think when TStringStream writes the bytes to the file it fails to convert the unicode characters to bytes so it appears like "?"

Any idea is much appreciated

有帮助吗?

解决方案

You are trying to send binary data as if it were UTF-8 encoded text. It is not, so do not try to do that! Send the binary data in its original binary form, eg:

var
  MS: TMemoryStream;
  JPG: TJPEGImage;
  BMP: TBitmap;
begin
  MS := TMemoryStream.Create;
  try
    JPG := TJPEGImage.Create;
    try
      BMP := TBitmap.Create;
      try
        BMP.LoadFromFile('C:\1.bmp');
        JPG.Assign(BMP);
      finally
        BMP.Free;
      end;
      JPG.CompressionQuality := 80;
      JPG.Compress;
      JPG.SaveToStream(MS);
    finally
      JPG.Free;
    end;
    MS.Position := 0;
    MyTCPSocket.SendStream(MS);
  finally
    MS.free;
  end;
end;

var
  MS: TMemoryStream;
begin
  MS := TMemoryStream.Create;
  try
    MyTCPSocket.ReadStream(MS);
    MS.Position := 0;
    MS.SaveToFile('C:\2.jpg');
  finally
    MS.Free;
  end;
end;

If you must send binary data as text, you need to encode the data using a real binary-to-text encoding algorithm, such as base64 or yEnc, not UTF-8 (which is designed for only encoding Unicode text, not binary data), eg:

// TIdEncoderMIME and TIdDecoderMIME are part of Indy,
// which ships with Delphi, but you can use whatever
// you want...

uses
  ..., IdCoderMIME;

var
  S: String;
  MS: TMemoryStream;
  JPG: TJPEGImage;
  BMP: TBitmap;
begin
  MS := TMemoryStream.Create;
  try
    JPG := TJPEGImage.Create;
    try
      BMP := TBitmap.Create;
      try
        BMP.LoadFromFile('C:\1.bmp');
        JPG.Assign(BMP);
      finally
        BMP.Free;
      end;
      JPG.CompressionQuality := 80;
      JPG.Compress;
      JPG.SaveToStream(MS);
    finally
      JPG.Free;
    end;
    MS.Position := 0;
    S := TIdEncoderMIME.EncodeStream(MS);
  finally
    MS.free;
  end;
  MyTCPSocket.SendString(S);
end;

uses
  ..., IdCoderMIME;

var
  S: string;
  MS: TMemoryStream;
begin
  S := MyTCPSocket.ReadString;
  MS := TMemoryStream.Create;
  try
    TIdDecoderMIME.DecodeStream(S, MS);
    MS.Position := 0;
    MS.SaveToFile('C:\2.jpg');
  finally
    MS.Free;
  end;
end;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top