I have an issue with TStringStream
encoding on different OS region languages.
I am trying to transfer image data. I was having a problem with it before, and it was solved in another question.
But now I have an encoding issue on TStringStream
itself. If the Operating System region language is set to English, I get corrupted data from TStringStream
.
When I change the language to Arabic, the data comes out correctly.
I currently use Indy to encode the binary data, but before starting the encoding, the data from StringStream.DataString
is already corrupted if the region encoding is not set to Arabic. I tried to add TEncoding.UTF8
to TStringStream.Create()
, but the data still comes out incorrectly from StringStream.DataString
.
function Encode64(const S: string; const ByteEncoding: IIdTextEncoding = nil): string;
begin
Result := TIdEncoderMIME.EncodeString(S, ByteEncoding);
end;
function Decode64(const S: string; const ByteEncoding: IIdTextEncoding = nil): string;
begin
Result := TIdDecoderMIME.DecodeString(S, ByteEncoding);
end;
StringStream := TStringStream.Create('');
try
Jpg.Performance := jpBestSpeed;
Jpg.ProgressiveEncoding := True;
Jpg.ProgressiveDisplay := True;
jpg.Assign(Image2.Picture.Bitmap);
jpg.CompressionQuality := 25;
jpg.Compress;
jpg.SaveToStream(StringStream);
StringImageData := StringStream.DataString; // the data here is corrupted when Os region is not set to arabic
strcams := '<[S:' + IntToStr(Length(StringImageData)) + 'B]>' + StringImageData;
if length(strcams) < byt then begin
Sendimgdata('IMGDATA123', Encode64(strcams, IndyTextEncoding_UTF8) + sep);
end;
...
You cannot save a JPG to a TStringStream
to begin with. You need to encode the binary data without converting it to a string first, which will corrupt the data. Use a TMemoryStream
instead for the binary data:
MemoryStream := TMemoryStream.Create;
...
jpg.SaveToStream(MemoryStream);
MemoryStream.Position := 0;
StringImageData := TIdEncoderMIME.EncodeStream(MemoryStream);
...
If you want to encode after you insert the text with length, you have to work with TMemoryStream
too:
procedure StringToStream(aStream: TStream; const aString: AnsiString);
begin
aStream.Write(PAnsiChar(AString)^, Length(AString));
end;
...
JpegStream := TMemoryStream.Create;
jpg.SaveToStream(JpegStream);
CompleteStream := TMemoryStream.Create;
StringToStream(CompleteStream, '<[S:' + IntToStr(JpegStream.Size)+'B]>');
CompleteStream.CopyFrom(JpegStream, 0);
StringImageData := TIdEncoderMIME.EncodeStream(CompleteStream);