【问题标题】:How load a base64 encrypted url in a TWebBrowser or TImage?如何在 TWebBrowser 或 TImage 中加载 base64 加密的 url?
【发布时间】:2019-11-05 20:44:20
【问题描述】:

我有this url 在base64 中加密,这是一个动画二维码。

如何将其加载到TWebBrowser(或TImage)中?提前致谢。


编辑:

这是我的尝试,但没有成功:

uses
 IdHTTP, IdSSLOpenSSL, GIFImg, ClipBrd;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetStrFromClipbrd: string;
begin
  if Clipboard.HasFormat(CF_TEXT) then
    Result := Clipboard.AsText
  else
  begin
    ShowMessage('There is no text in the Clipboard!');
    Result := '';
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  MS: TMemoryStream;
  IdHTTP1: TIdHTTP;
  GIF: TGIFImage;
begin
  MS := TMemoryStream.Create;
  try
    IdHTTP1 := TIdHTTP.Create;
    try
      GIF := TGIFImage.Create;
      try
        IdHTTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
        IdHTTP1.HandleRedirects := True;
        IdHTTP1.Get(GetStrFromClipbrd, MS);
        MS.Seek(0, soFromBeginning);
        GIF.LoadFromStream(MS);
        Image1.Picture.Assign(GIF);
        (Image1.Picture.Graphic as TGIFImage).Animate := True;
        //(Image1.Picture.Graphic as TGIFImage).AnimationSpeed := 500;
      finally
        FreeAndNil(GIF);
      end;
    finally
      FreeAndNil(IdHTTP1);
    end;
  finally
    FreeAndNil(MS);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.DoubleBuffered := True;
end;

end.

【问题讨论】:

  • 这不是用 Delphi base64 函数加密的,我也可以有解密代码。
  • Base64 是一种标准的数据编码方式,而不是加密方式。任何正确实现的 Base64 解码器都应该能够解码数据。看看,我认为,从 TNetEncoding 开始......
  • @RobLambden,非常感谢。 System.NetEncoding 工作正常。 PS: 测试以 GIF 图像形式保存到磁盘。
  • @RemyLebeau,也谢谢你,+1 by:"data: is not a URL type you can request with TIdHTTP, nor do you need to anyway. All of the image data is encoded directly in the URL string itself."。但是编码的 url 是一个动画图像,那么我想那是一个 GIF,而不是你建议的 BMP。
  • @BrowJr 您显示的data: 网址显示的是image/bmp,而不是image/gif,尽管它实际上包含一个GIF 图像。无论您从哪里获得的 URL 都是错误的。

标签: delphi base64 twebbrowser delphi-10.3-rio timage


【解决方案1】:

data: 不是您可以使用TIdHTTP(或任何其他 HTTP 库)请求的 URL 类型,您也不需要这样做,因为所有数据都直接编码在 URL 本身中。因此,只需提取 base64 部分并使用您选择的任何 base64 解码器对其进行解码。

由于您的代码已经在使用 Indy,您可以使用 IdCoderMIME 单元中的 TIdDecoderMIME 类将 base64 数据解码为二进制流,例如使用 TIdDecoderMIME.DecodeStream() 类过程。然后您可以将该流加载到适当的TGraphic 后代(TGIFImageTBitmap 等),最后您可以将该图形加载到您的TImage

例如:

uses
  IdGlobal, IdGlobalProtocols, IdCoderMIME, IdHTTP, IdSSLOpenSSL,
  Graphics, GIFImg, JPEG, ClipBrd;

function GetStrFromClipbrd: string;
const
  CTextFormat = {$IFDEF UNICODE}CF_UNICODETEXT{$ELSE}CF_TEXT{$ENDIF};
begin
  if Clipboard.HasFormat(CTextFormat) then
    Result := Clipboard.AsText
  else
    Result := '';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Graphic: TGraphic;
  MS: TMemoryStream;
  IdHTTP1: TIdHTTP;
  URL, ContentType: string;
begin
  URL := GetStrFromClipbrd;
  if URL = '' then
  begin
    ShowMessage('There is no text in the Clipboard!');
    Exit;
  end;

  Graphic := nil;
  try
    MS := TMemoryStream.Create;
    try
      if TextStartsWith(URL, 'data:') then
      begin
        Fetch(URL, ':');
        ContentType := Fetch(URL, ',');
        if not TextEndsWith(ContentType, ';base64') then
        begin
          ShowMessage('Data is not encoded in base64!');
          Exit;
        end;
        SetLength(ContentType, Length(ContentType)-7);
        TIdDecoderMIME.DecodeStream(URL, MS);
        if ContentType = '' then
          ContentType := 'text/plain;charset=US-ASCII';
      end else
      begin
        IdHTTP1 := TIdHTTP.Create;
        try
          IdHTTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
          IdHTTP1.HandleRedirects := True;
          IdHTTP1.Get(URL, MS);
          ContentType := IdHTTP1.Response.ContentType;
        finally
          IdHTTP1.Free;
        end;
      end;

      MS.Position := 0;

      case PosInStrArray(ExtractHeaderItem(ContentType),
        ['image/gif', 'image/jpeg', 'image/bmp'{, ...}],
        False) of
          0: Graphic := TGIFImage.Create;
          1: Graphic := TJPEGImage.Create;
          2: Graphic := TBitmap.Create;
          // ...
      else
        ShowMessage('Unsupported image type!');
        Exit;
      end;

      { the 'data:' URL you provided is malformed, is says the image type
        is 'image/bmp' even though it is actually a GIF and thus should
        say 'image/gif'.  To avoid problems with the above code determining
        the wrong TGraphic class to use in that case, you can instead look
        at the first few bytes of the decoded data to determinate its actual
        image type, eg...

        const
          Signature_GIF87a: array[0..5] of Byte = ($47,$49,$46,$38,$37,$61);
          Signature_GIF89a: array[0..5] of Byte = ($47,$49,$46,$38,$39,$61);
          Signature_JPEG:   array[0..2] of Byte = ($FF,$D8,$FF);
          Signature_BMP:    array[0..1] of Byte = ($42,$4D);
          ...

        if (MS.Size >= 6) and
           (CompareMem(MS.Memory, @Signature_GIF87a, 6) or
            CompareMem(MS.Memory, @Signature_GIF89a, 6)) then
        begin
          Graphic := TGIFImage.Create;
        end
        else if (MS.Size >= 3) and
                 CompareMem(MS.Memory, @Signature_JPEG, 3) then
        begin
          Graphic := TJPEGImage.Create;
        end
        else if (MS.Size >= 2) and
                 CompareMem(MS.Memory, @Signature_BMP, 2) then
        begin
          Graphic := TBitmap.Create;
        end
        ...
        else
          ShowMessage('Unsupported image type!');
          Exit;
        end;
      }

      Graphic.LoadFromStream(MS);
    finally
      MS.Free;
    end;

    Image1.Picture.Assign(Graphic);
  finally
    Graphic.Free;
  end;

  if Image.Picture.Graphic is TGIFImage then
  begin
    TGIFImage(Image.Picture.Graphic).Animate := True;
    //TGIFImage(Image.Picture.Graphic).AnimationSpeed := 500;
  end;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多