Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

delphi - Convert BitMap to string without line breaks?

Somewhere I found this code to convert a BitMap to a string:

function Base64FromBitmap(Bitmap: TBitmap): string;
var
  Input: TBytesStream;
  Output: TStringStream;
begin
  Input := TBytesStream.Create;
  try
    Bitmap.SaveToStream(Input);
    Input.Position := 0;
    Output := TStringStream.Create('', TEncoding.ASCII);
    try
      Soap.EncdDecd.EncodeStream(Input, Output);
      Result := Output.DataString;
    finally
      Output.Free;
    end;
  finally
    Input.Free;
  end;
end;

However, this gives back a block of wrapped lines. Is it possible to get one single line without line breaks?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

XE7 introduces the System.NetEncoding unit which contains a base64 encoder. This is intended to be used rather than the encoder from Soap.EncdDecd.

The constructor of TBase64Encoding has overloads that allow you to specify characters per line (and line break text). Unfortunately Embarcadero haven't deigned to provide documentation yet so we need to read the source to work out what exactly to pass. Having done that, it becomes clear that line breaks are inserted only if the number of characters per line is strictly positive. So create an encoding object like this:

Encoding := TBase64Encoding.Create(0);

Once you have a suitable encoding object use Encode to encode your stream of bytes to text. And Decode to reverse the process.

That could look like this:

function Base64FromBitmap(Bitmap: TBitmap): string;
var
  Input: TBytesStream;
  Output: TStringStream;
  Encoding: TBase64Encoding;
begin
  Input := TBytesStream.Create;
  try
    Bitmap.SaveToStream(Input);
    Input.Position := 0;
    Output := TStringStream.Create('', TEncoding.ASCII);
    try
      Encoding := TBase64Encoding.Create(0);
      try
        Encoding.Encode(Input, Output);
        Result := Output.DataString;
      finally
        Encoding.Free;
      end;
    finally
      Output.Free;
    end;
  finally
    Input.Free;
  end;
end;

procedure BitmapFromBase64(Base64: string; Bitmap: TBitmap);
var
  Input: TStringStream;
  Output: TBytesStream;
  Encoding: TBase64Encoding;
begin
  Input := TStringStream.Create(Base64, TEncoding.ASCII);
  try
    Output := TBytesStream.Create;
    try
      Encoding := TBase64Encoding.Create(0);
      try
        Encoding.Decode(Input, Output);
        Output.Position := 0;
        Bitmap.LoadFromStream(Output);
      finally
        Encoding.Free;
      end;
    finally
      Output.Free;
    end;
  finally
    Input.Free;
  end;
end;

Alternatively you can use EncodeBytesToString and DecodeStringToBytes. Which might look like this:

function Base64FromBitmap(Bitmap: TBitmap): string;
var
  Stream: TBytesStream;
  Encoding: TBase64Encoding;
begin
  Stream := TBytesStream.Create;
  try
    Bitmap.SaveToStream(Stream);
    Encoding := TBase64Encoding.Create(0);
    try
      Result := Encoding.EncodeBytesToString(Copy(Stream.Bytes, 0, Stream.Size));
    finally
      Encoding.Free;
    end;
  finally
    Stream.Free;
  end;
end;

procedure BitmapFromBase64(Base64: string; Bitmap: TBitmap);
var
  Stream: TBytesStream;
  Bytes: TBytes;
  Encoding: TBase64Encoding;
begin
  Stream := TBytesStream.Create;
  try
    Encoding := TBase64Encoding.Create(0);
    try
      Bytes := Encoding.DecodeStringToBytes(Base64);
      Stream.WriteData(Bytes, Length(Bytes));
      Stream.Position := 0;
      Bitmap.LoadFromStream(Stream);
    finally
      Encoding.Free;
    end;
  finally
    Stream.Free;
  end;
end;

What would be really good would be if we could have something like the compression and decompression streams that are available with zlib. We could create an encoding stream, save the bitmap to it, and read out the base64 text. In the other direction we'd feed base64 text into a decoding stream, and then load the bitmap from it. This should really be part of the NetEncoding unit, but it would be simple enough to add as a class helper.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...