I have this url encrypted in base64 that is a animated QRCode.
How i can load it in a TWebBrowser
(or TImage
)? Thanks in advance.
Edit:
Here was my attempt, but without success:
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.
data:
is not a URL type you can request with TIdHTTP
(or any other HTTP library), nor do you need to since all of the data is encoded directly in the URL itself. So simply extract the base64 portion and decode it using any base64 decoder of your choosing.
Since your code is already using Indy anyway, you could use its TIdDecoderMIME
class in the IdCoderMIME
unit to decode the base64 data to a binary stream, such as with the TIdDecoderMIME.DecodeStream()
class procedure. Then you can load that stream into an appropriate TGraphic
descendant (TGIFImage
, TBitmap
, etc), and then finally you can load that graphic into your TImage
.
For example:
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;