hi, i want to get image of simple captcha to solve by ocr, but i can't found any way.
if download image by DownloadURL, i get new image and it's incorrect. i can't use screenshot because Visible of browser is False. i try to use OnResourceLoadComplete event but not successful because no access to memory stream. please help me if any way exists
Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
Get captcha image
-
- Posts: 3
- Joined: Thu Mar 18, 2021 10:30 am
Re: Get captcha image
Hi yaser6403,
You need register your custom TCefv8HandlerOwn on GlobalCEFApp_OnWebKitInitializedEvent, which contain javascript code to grab your captcha image:
On TCefv8HandlerOwn.Execute, you need handle the message send by browser and handle.
On Browser_OnProcessMessageReceived event, you need handle the base64 of image, like this:
BR
You need register your custom TCefv8HandlerOwn on GlobalCEFApp_OnWebKitInitializedEvent, which contain javascript code to grab your captcha image:
Code: Select all
procedure GlobalCEFApp_OnWebKitInitializedEvent;
var
TempHandler : ICefv8Handler;
JS: TScriptList;
begin
JS:= TScriptList.Create;
try
JS.Add('var myextension;');
JS.Add('if (!myextension)');
JS.Add(' myextension = {};');
JS.Add('(function() {');
JS.Add(' myextension.getImage = function(img) {');
JS.Add(' var canvas = document.createElement("canvas");');
JS.Add(' canvas.width = img.width;');
JS.Add(' canvas.height = img.height;');
JS.Add(' var pixels = "";');
JS.Add(' if (img.naturalWidth && img.naturalHeight) {');
JS.Add(' var ctx = canvas.getContext("2d");');
JS.Add(' ctx.drawImage(img, 0, 0);');
JS.Add(' pixels = canvas.toDataURL("image/png");');
JS.Add(' }');
JS.Add(' native function SetImage();');
JS.Add(' return SetImage(img.width,img.height,pixels,"'+CHROMIUM_JS_SET_IMAGE_MSGNAME+'");');
JS.Add(' }');
JS.Add('})();');
TempHandler := TMyImageHandler.Create;
CefRegisterExtension('myextension', JS.Text, TempHandler)
finally
TempHandler:= nil;
JS.Free;
end;
end;
Code: Select all
TMyImageHandler = class(TCefv8HandlerOwn)
protected
function Execute(const name: ustring; const obj: ICefv8Value; const arguments: TCefv8ValueArray; var retval: ICefv8Value; var exception: ustring): Boolean; override;
end;
Code: Select all
function TMyImageHandler.Execute(const name: ustring; const obj: ICefv8Value; const arguments: TCefv8ValueArray; var retval: ICefv8Value;
var exception: ustring): Boolean;
var
TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
Pixels: string;
p: Integer;
EventMessageName: string;
begin
Result := False;
try
if (name = 'SetImage') then
begin
Pixels:= arguments[2].GetStringValue;
p:= Pos(',',Pixels);
if p > 0 then
System.Delete(Pixels,1,p);
EventMessageName:= arguments[3].GetStringValue;
TempMessage := TCefProcessMessageRef.New(EventMessageName);
TempMessage.ArgumentList.SetString(0, Pixels);
TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
Result := True;
end;
finally
TempMessage := nil;
end;
end;
Code: Select all
if (message.Name = CHROMIUM_JS_SET_IMAGE_MSGNAME) then
begin
Pixels:= message.ArgumentList.GetString(0);
if Pixels <> '' then
begin
Stream:= TMemoryStream.Create;
MyBase64Decode(Pixels,Stream);
Png:= TPngImage.Create;
Stream.Position:= 0;
Png.LoadFromStream(Stream);
DoImage(Png);
end else
begin
DoImage(nil);
end;
end;
Re: Get captcha image
Watch the Demo with DownloadImage, specify the link and that's it, if the image is already downloaded, then through DownloadImage you will get it from the cache, which means it will not be new.
(the main thing is that the link of the ball is the same)
(the main thing is that the link of the ball is the same)