Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to take screenshots for UI element?
#1
Hi Dear Gintaras, I have two questions about using LA and I would like to ask you for a recommendation.Thank you very much.
1.how to take screenshots for UI elements automatically without manually drawing rectangle in element ?
2.Does LA support xpath with UI? I often got fail to locate desired UI elements by using elm since there was so many same kind exists.I was wondering if LA can locate the UI element by using xpath? Thank you so much for bringing us such a powerful and amazing gift. 

PS:do you have a donation account or same kind to receive donations to maintain the software and further development? If so please tell me the account to receive donation.
#2
1. The "Find UI element" tool does not support it.

2. In the "Find UI element" tool use "Add to path" or "navig".

3. Currently no, but in the future will accept donations.
#3
Not the answer, but may be useful for those looking for "capture UI element screenshot" code. This script finds an UI element, captures its screenshot, saves in a file and opens the file.

Code:
Copy      Help
// script ""
var w = wnd.find(0, "*Mozilla Firefox");
w.Activate();
var e = w.Elm["web:LINK", "Edit"].Find(0);
using var bitmap = CaptureScreen.Image(e.Rect);
var file = folders.ThisAppTemp + "UI element screenshot.png";
bitmap.Save(file);
run.it(file);
#4
Thank you so very much and it really works!

Wow,Amazing!That is exactly what I was looking for!I have tested your code for several times and it working so well. BTW,Do you know how to display the screenshot without run.it() command?Just display or preview it on LA dashboard? Thanks
#5
Code:
Copy      Help
// script ""
var w = wnd.find(0, "*Mozilla Firefox");
w.Activate();
500.ms();
var e = w.Elm["web:LINK", "Edit"].Find(0);
using var bitmap = CaptureScreen.Image(e.Rect);
var ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
print.it($"<><image \"image:{Convert.ToBase64String(ms.ToArray())}\">");
ScriptEditor.ShowMainWindow(true);
#6
Thanks a bunch!It worked really great!
#7
Hi dear Gintaras,

I am sorry to bother you again, I was stumped by another UI element screenshot issue. I am extracting all the logos from a website Brand, Below is my code: 
Code:
Copy      Help
var w = wnd.find(1, "Global 500 2023 | Brand Value Ranking League Table | Brandirectory - Google Chrome", "Chrome_WidgetWin_1");

for (int i = 2; i < 20; i++) {
    var e = w.Elm["web:DOCUMENT", "Global 500 2023 | Brand Value Ranking League Table | Brandirectory", navig: $"fi3 ch5 fi3 ch{i} ch3"].Find(1);
    e.ScrollTo();
    using var bitmap = CaptureScreen.Image(e.Rect);
    var ms = new MemoryStream();
    bitmap.Save(folders.Desktop + $"logo/{e.Name.Split("/")[0]}.png");
    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    print.it($"<><image \"image:{Convert.ToBase64String(ms.ToArray())}\">");
    ScriptEditor.ShowMainWindow(true);
}

I just set the row number per page to "All"  to get rid of using too many for loops, that way I could use e.ScrollTo() instead of click turn page button. The problem is the screenshots which was taken are missing edge sometimes. I would like to ask your advise to get rid of this problem. Thank you so much!


[Image: Jz5zt3f]

I have sort of solved this problem by insert  var e2 and e2.ScrollTo(); .2.s();​​​​​​​ ,I would like to know if there is any efficient solution? 
Code:
Copy      Help
var w = wnd.find(1, "Global 500 2023 | Brand Value Ranking League Table | Brandirectory - Google Chrome", "Chrome_WidgetWin_1");

for (int i = 2; i < 50; i++) {
    var e = w.Elm["web:DOCUMENT", "Global 500 2023 | Brand Value Ranking League Table | Brandirectory", navig: $"fi3 ch5 fi3 ch{i} ch3"].Find(1);
    var e2 = w.Elm["web:DOCUMENT", "Global 500 2023 | Brand Value Ranking League Table | Brandirectory", navig: $"fi3 ch5 fi3 ch{i+5} ch3"].Find(1);
    e2.ScrollTo(); .2.s();
    
    using var bitmap = CaptureScreen.Image(e.Rect);
    var ms = new MemoryStream();
    bitmap.Save(folders.Desktop + $"logo/{e.Name.Split("/")[0]}.png");
    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    print.it($"<><image \"image:{Convert.ToBase64String(ms.ToArray())}\">");
    ScriptEditor.ShowMainWindow(true);
}
#8
Code:
Copy      Help
// script "Capture brand logos.cs"
//https://brandirectory.com/rankings/global/table

print.clear();
filesystem.createDirectory(@"C:\Test\logo");

var w = wnd.find(0, "Global 500 2023 | Brand Value Ranking League Table | Brandirectory - Google Chrome", "Chrome_WidgetWin_1");
w.Activate();
keys.send("Ctrl+Home");
500.ms();

using var ci = new CaptureScreenImage();
for (int i = 2; i < 500; i++) {
    gRetry:
    var e = w.Elm["web:DOCUMENT", navig: $"fi3 ch5 fi3 ch{i} ch3 fi3"].Find(1);
    ci.Capture(e.Rect);
    
    var a = ci.ToArray2D();
    if (a[ci.Height - 1, 0] == 0xFF000000) { //if the bottom-left pixel is black
        //print.it(i);
        //scroll to the next element, because Chrome does not scroll to this element if it is partially visible

        e = w.Elm["web:DOCUMENT", navig: $"fi3 ch5 fi3 ch{i + 1} ch3 fi3"].Find(1);
        e.ScrollTo();
        50.ms();
        goto gRetry;
    }

    
    using var bitmap = ci.ToBitmap();
    var ms = new MemoryStream();
    bitmap.Save($@"C:\Test\logo/{e.Name.Split("/")[0]}.png");
    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    print.it($"<><image \"image:{Convert.ToBase64String(ms.ToArray())}\">");
}

ScriptEditor.ShowMainWindow(true);

//Several times noticed 1 or several white or almost white images captured.

//Once Chrome UI elements stopped working. Restart Chrome.
#9
You are superman Gintaras, It worked charming! I really appreciate your help!

That works charming!  How to determine how many times of loop should be taken if the element number is unknown? Something like While condition or int i < e.Length()  or something else? May I ask your advice?
#10
Code:
Copy      Help
// script ""
var w = wnd.find(1, "Global 500 2023 | Brand Value Ranking League Table | Brandirectory - Google Chrome", "Chrome_WidgetWin_1");
var table = w.Elm["web:TABLE"].Find(1);
int n = table.ChildCount - 1;
print.it(n);
#11
Great!That works great!Thanks a lot.
#12
I wanted to test a different way, and this is the result. Can get images of any size. Also it seems this is more reliable, never fails.

Code:
Copy      Help
// script "Copy brand logos.cs"
/// https://brandirectory.com/rankings/global/table
/// Copies images from UI elements in Chrome, makes equal size, saves, and displays in the Output panel.

print.clear();
var download = @"C:\Test\logo";
//filesystem.delete(download);
filesystem.createDirectory(download);
int width = 0, height = 30; //edit these if need. If both 0, does not resize. If one 0, preserves aspect ratio. After editing may need to restart LA to reset the Output panel's image cache.

var w = wnd.find(0, "Global 500 2023 | Brand Value Ranking League Table | Brandirectory - Google Chrome", "Chrome_WidgetWin_1");
w.Activate();

HashSet<string> hs = new(StringComparer.OrdinalIgnoreCase);
foreach (var e in w.Elm["web:LINK", "* Brand Logo"].FindAll()) {
    e.Focus(); //focus, scroll
    keys.send("Apps"); //show context menu
    var w2 = wnd.find(5, "", "Chrome_WidgetWin_?", w, contains: "e 'MENUPOPUP'"); //context menu window
    var e2 = w2.Elm["MENUITEM", "Copy image"].Find(3); //context menu item
    clipboard.clear();
    e2.Invoke(); //copy the image to the clipboard and close the context menu
    var b = wait.forCondition(5, () => clipboardData.getImage(png: true)); //get the image from the clipboard
    if (width > 0 || height > 0) b = b.Resize(width, height, BRFilter.Lanczos3, true);
    var name = e.Navigate("pa2 ne").Name; //next cell in this row
    var filename = pathname.correctName(name); while (!hs.Add(filename)) filename += "+"; //create a correct and unique filename
    var path = $@"{download}\{filename}.png";
    b.Save(path);
    b.Dispose();
    print.it($"<>{name}<image \"{path}\">");
}

ScriptEditor.ShowMainWindow(true);
#13
Hi Gintaras, 

This code runs very smoothly, but to be honest, I can't quite understand this code yet. I tried to read the logic behind each line of code. But all I can say is that it's like magic, really like magic.

I'm very interested in C# and I hope I can learn it well while I'm familiar with LA. It's a really rewarding thing to do. Thank you for such a wonderful gift!

var w2 = wnd.find(5, "", "Chrome_WidgetWin_1", w, contains: "e 'MENUPOPUP'");  

I have to change Chrome_WidgetWin_1 to Chrome_WidgetWin_2 to make it work.
#14
for (var e = w.Elm["web:LINK", "* Brand Logo"].Find(); e != null; e = e.Navigate("pa3 ne ch3 fi2")) {
    e.Focus();
     keys.send("Apps");

Hi Gintaras, I really can't figure out how this line of code can implement the entire for loop,could you please tell me how this code works? Also, I don't see you using e.scroll to(), but the code still focuses on the element, what's the reason for that? 

Thank you for the explanation!
#15
for(...) gets elm of the first image link, and while not null, gets elm of next image link.
e.Focus() makes the image link focused. Chrome scrolls to the focused element.
keys.send("Apps"); show context menu for the focused element, like right-click. Then Invoke will close it, probably too soon for it become visible.
#16
It was so interesting! Thank you!
#17
Hi Gintaras,

For the for loop(…) you have mentioned in last reply can I understand it this way? Just find the first element and then locate similar elements in order based on their relative positions? As long as they are in the same structure, we can use this loop to find them regardless how far apart theirs are on the page?

Thanks!
#18
Yes. But it is not the best way in this case. Now changed the code.


Forum Jump:


Users browsing this thread: 1 Guest(s)