将BitMap转换为字符串而不换行?

use*_*348 2 delphi encode bitmap delphi-xe7

在某处我找到了将BitMap转换为字符串的代码:

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;
Run Code Online (Sandbox Code Playgroud)

但是,这会给回一块包裹的线条.是否可以获得一条没有换行符的单行?

Dav*_*nan 8

XE7 引入了System.NetEncoding包含 base64 编码器的单元。这旨在用于而不是来自 的编码器Soap.EncdDecd

构造函数TBase64Encoding具有重载,允许您指定每行字符(和换行符文本)。不幸的是,Embarcadero 还没有提供文档,所以我们需要阅读源代码来确定到底要通过什么。这样做之后,很明显只有当每行的字符数严格为正时才插入换行符。所以创建一个这样的编码对象:

Encoding := TBase64Encoding.Create(0);
Run Code Online (Sandbox Code Playgroud)

一旦您有了合适的编码对象,就可以使用Encode将您的字节流编码为文本。并Decode扭转这个过程。

看起来像这样:

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;
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用EncodeBytesToStringDecodeStringToBytes。可能看起来像这样:

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;
Run Code Online (Sandbox Code Playgroud)

如果我们可以使用 zlib 提供的压缩和解压缩流之类的东西,那将是非常好的。我们可以创建一个编码流,将位图保存到其中,然后读出 base64 文本。在另一个方向,我们将 base64 文本输入到解码流中,然后从中加载位图。这真的应该是NetEncoding单元的一部分,但是作为类助手添加它很简单。


Rem*_*eau 5

Soap.EncdDecd.EncodeStream()是硬编码的,每75个字符输出一次换行符.更改它的唯一方法是复制Soap.EncdDecd.pas,编辑它,然后将副本添加到项目中(如果您的项目启用了运行时包,则此方法不起作用).

您可以使用Indy的TIdEncoderMIME课程作为替代.它不输出换行符:

uses
  ..., IdCoderMIME;

function Base64FromBitmap(Bitmap: TBitmap): string;
var
  Input: TMemoryStream;
begin
  Input := TMemoryStream.Create;
  try
    Bitmap.SaveToStream(Input);
    Input.Position := 0;
    Result := TIdEncoderMIME.EncodeStream(Input);
  finally
    Input.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)