如何在TWebBrowser或TImage中加载base64加密的url?

问题描述 投票:1回答:1

我已在base64中加密了this url,这是一个动画QRCode。

我如何将其加载到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 twebbrowser delphi-10.3-rio timage
1个回答
1
投票

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

由于代码无论如何已经在使用Indy,因此可以使用TIdDecoderMIME单元中的IdCoderMIME类将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;

      ContentType := ExtractHeaderItem(ContentType);

      case PosInStrArray(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;
      }

      MS.Position := 0;
      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;
© www.soinside.com 2019 - 2024. All rights reserved.