1
$\begingroup$

I know that by using CurrentScreenImage with some coordinates that I can capture regions of my screen. I would like to be able to capture a rectangular region of my screen by clicking and dragging a rectangle, using some dynamic functionality and MousePosition["ScreenAbsolute"], and passing the coordinates of this rectangle to CurrentScreenImage. But I run into a couple of snags.

  1. Dynamic[MousePosition["ScreenAbsolute"]] stops tracking the pointer as soon as it leaves the notebook window.
  2. Modifying some code from How to access off-cell mouse position inside an EventHandler?, I can at least click within a region of the notebook, drag outside of the notebook, and retain the tracking of the pointer while the click is still held. Also, it records successfully the mouse un-click, outside of the notebook. So maybe tracking the pointer outside the window isn't hopeless.
  3. But of course, I cannot figure out at all how to get the mouse position and first click recorded while the pointer is outside the notebook.

Here is the code I have so far:

DynamicModule[{pressed = True}, 
 Deploy@EventHandler[
   DynamicWrapper[
    Graphics[{Dynamic[If[pressed, Gray, Black]], Rectangle[]}, 
     ImageSize -> 100, AspectRatio -> 1], 
    If[pressed, 
     pt = f[MousePosition@
        "ScreenAbsolute"]]], {"MouseDown" :> ({topLeft, 
        pressed} = {MousePosition["ScreenAbsolute"], True}), 
    "MouseUp" :> ({bottomRight, 
        pressed} = {MousePosition["ScreenAbsolute"], False})}]]

Dynamic@pt
Dynamic[{topLeft, bottomRight}]

I will also mention that the reason I don't just manually take these screenshots and put them into Mathematica is that I have a very dynamic, real-time application in mind and I would like it to be as easy as click-dragging a box to put the image data into the notebook for immediate processing. (I guess it doesn't have to be a click per-se; it could also be a key command. But I need to be able to do it without the notebook being the focused window on the desktop.)

$\endgroup$

1 Answer 1

2
$\begingroup$

Here's one approach (code below):

enter image description here

This works by:

  1. Creating a semi-transparent full-screen window with things such as scrollbars etc. disabled
  2. Attaching (see AttachCell) a Graphics to the window, so that we can easily draw arbitrary things onto the canvas
  3. Using NotebookEventActions to listen for two mouse clicks
  4. Waiting for the second click and returning the result

(Please note that the current version has some limitations when it comes to multi-monitor setups and non-default screen scaling settings)

selectArea[] := Module[
  {
   pts = {{0, 0}, Dynamic@MousePosition["ScreenAbsolute"]},
   i = 0,
   nb, size
   },
  nb = CreateWindow[{},
    WindowOpacity -> 0.5,
    Saveable -> False, Editable -> False,
    WindowElements -> {},
    WindowToolbars -> {},
    ShowCellBracket -> False,
    CellInsertionPointCell -> Cell[],
    WindowSize -> Full,
    NotebookEventActions -> {"MouseClicked" :> (
        pts[[++i]] = MousePosition["ScreenAbsolute"];
        If[i == 2, DialogReturn@pts];
        )}
    ];
  size = AbsoluteCurrentValue[nb, WindowSize];
  AttachCell[
   nb, Graphics[
    Dynamic@If[
      i == 0,
      {},
      Scale[
       {
        Transparent,
        Rectangle[Scaled@{0, 0}, Scaled@{1, 1}],
        EdgeForm@{Red, Thick}, FaceForm@None, Rectangle @@ pts
        }, {1, -1}
       ]
      ],
    ImageSize -> size, ImageMargins -> {100, 100},
    PlotRange -> 
     Transpose@{{0, 0}, AbsoluteCurrentValue[nb, WindowSize]}
    ],
   {Left, Top},
   Automatic,
   {Left, Top}
   ];
  While[i < 2, [email protected]];
  1 + Round[pts ]
  ]

pts = selectArea[]
(* {{497, 311}, {905, 588}} *)
$\endgroup$
1
  • $\begingroup$ You possess powers beyond contemplation $\endgroup$
    – Diffycue
    Nov 30, 2023 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.