Sunday, January 21, 2018

#1 2012-04-12 03:08:13 pm

Flat5
Member
From:: newyorkcity
Registered: 2011-12-11
Posts: 13

any way to screencapture frontmost window?

hi,

i'd like a non-interactive screencapture of the frontmost window…


best case scenario would be something like:
do shell script "screencapture -fcx"
where 'f' means frontmost window capture but i don't think anything like this exists..


does anyone know of a way / or come up with a workaround to accomplish this?

thank you

Offline

 

#2 2012-04-12 10:56:16 pm

Aesthir
Member
Registered: 2010-11-25
Posts: 32

Re: any way to screencapture frontmost window?

I don't have much time right now so I won't type up the scripts, but I'll be back Saturday with some time to make a script or two if needed.

I can think of two ways just off the top of my head:
(1) Make the window full screen (in Lion) and then screen capture the screen… big_smile  I'm sure that's not what you were after, but it answers your question… lol
(2) GUI scripting using “System Events” to press keys, click around, etc…
    • in the keyboard pane of System Preferences, go to the Keyboard Shortcuts tab and in the list on the left, click screen shots, then see what hotkey is set for save picture of selected area as a file. If nothing is set, then proceed to set one.
    • in whatever application you want the window saved as a pic, get the bounds of the window, either with the application's own dictionary or with “System Events” (position and size — do the math)
    • when the window you want saved is visible, have “System Events” press whatever that hotkey is to capture a selection with keystroke blah… using {blah down, etc…}
    • have “System Events” send clicks, mouse down events, etc… at the top-left (position) and the bottom-right (position + size)

Whew! not the tidiest way I'm sure… I wrote it in case you feel like playing around writing this up and testing it while waiting for someone else's much simpler solution… tongue

— Aesthir

Offline

 

#3 2012-04-13 01:48:24 am

damiaan
Member
Registered: 2009-12-11
Posts: 8

Re: any way to screencapture frontmost window?

Hi Flat5
I quickly wrote a little script that uses the screencapture command from the terminal.

Applescript:

tell application "System Events" -- get frontmost process
   set frontmostProcess to first process where it is frontmost -- this will be the script process
   set visible of frontmostProcess to false -- hide the script process
   repeat while (frontmostProcess is frontmost) -- wait until the script is hided
       delay 0.2
   end repeat
   set secondFrontmost to name of first process where it is frontmost -- get name of frontmost process (ignoring the script process)
   set frontmost of frontmostProcess to true -- unhide the script process
end tell
tell application secondFrontmost to set winID to id of window 1 -- get WindowID of frontmost window of frontmost process
do shell script "screencapture -c -x -l " & winID -- -c is used to store it in the clipboard. -x is used to mute the sound. -l is used to refer to the prefered windowid.

The first thing I did was determine the frontmost process and, of course, this is the process of the script. So the Second thing I did was hiding that script process so that the "real" frontmost process appears. Then I stored the name of that process into the variable secondFrontmost. I then unhide the script process and stored the windowID of the frontmost window of the "real" frontmost process into winID. Then the only thing left is the do shell command

I hope this can help you
Damiaan

Last edited by damiaan (2012-04-13 02:03:54 am)

Offline

 

#4 2012-04-13 09:49:45 am

Flat5
Member
From:: newyorkcity
Registered: 2011-12-11
Posts: 13

Re: any way to screencapture frontmost window?

Aesthir wrote:

I don't have much time right now so I won't type up the scripts, but I'll be back Saturday with some time to make a script or two if needed.

I can think of two ways just off the top of my head:
(1) Make the window full screen (in Lion) and then screen capture the screen… big_smile  I'm sure that's not what you were after, but it answers your question… lol


the app i'm scripting can't go full screen.. but yeah, i don't think that's what i'm after anyway smile

(2) GUI scripting using “System Events” to press keys, click around, etc…
    • in the keyboard pane of System Preferences, go to the Keyboard Shortcuts tab and in the list on the left, click screen shots, then see what hotkey is set for save picture of selected area as a file. If nothing is set, then proceed to set one.
    • in whatever application you want the window saved as a pic, get the bounds of the window, either with the application's own dictionary or with “System Events” (position and size — do the math)
    • when the window you want saved is visible, have “System Events” press whatever that hotkey is to capture a selection with keystroke blah… using {blah down, etc…}
    • have “System Events” send clicks, mouse down events, etc… at the top-left (position) and the bottom-right (position + size)


as far as i can tell, all the keystroke options (shift-cmd-4 etc) are doable with the screencapture shell script… but you'll notice that of all the different variations on the keystroke screencapture, none of them will allow a screenshot to happen without mouse interaction except the full screenshot..

but yeah, i do plan on cropping etc once i figure out how to get the window captured (a window capture will still get the toolbars and such in there that i don't want).. at first, i was going to just capture the entire screen the crop out what i needed except the image events crop only seems to crop the middle of an image (where as i'd like to be able to describe the exact crop location (via maths & window position,size,etc).. but regardless, another problem with that is there are often floating toolbars/dialogs on top of the area i'd like to capture which would then be included in the full screen shot -- and there's no way to really get rid of them..




damiaan wrote:

Hi Flat5
I quickly wrote a little script that uses the screencapture command from the terminal.

*damiaan's script*

The first thing I did was determine the frontmost process and, of course, this is the process of the script. So the Second thing I did was hiding that script process so that the "real" frontmost process appears. Then I stored the name of that process into the variable secondFrontmost. I then unhide the script process and stored the windowID of the frontmost window of the "real" frontmost process into winID. Then the only thing left is the do shell command

I hope this can help you
Damiaan


uhh.. wow!.. i never knew of the -l with screencapture
(my only reference has been this:
https://developer.apple.com/library/mac … re.1.html)

i guess a lot of your script has to do with identifying the frontmost window etc.. in the script i'm working on, i already have the window which i'd like to capture identified so i don't think i need a lot of what you wrote there..

it's basically the screencapture -l that seems to be exactly what i'm after, except, i can't get the window id in the app i'm scripting sad

using safari for an example, this little script works absolutely great for what i want:

Applescript:

tell application "Safari"
   activate
   set winID to id of window 1
   do shell script "screencapture -c -x -o -l " & winID -- (added the -o for no shadow)
end tell

so i guess my question now becomes -- what can i use to identify the window with -l besides the windowID? (if i simply put do shell script "screencapture -c -x -o -l " & window 1 then it doesn't work..

Offline

 

#5 2012-04-13 01:23:37 pm

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3208

Re: any way to screencapture frontmost window?

In fact, I guess that you missed that the script is storing the screenshot in the clipboard.

To store it in a file you must pass the filepath .

I never did that but I guess that it must be :

do shell script "screencapture -x -l " & winID &" "& quoted form of pictureUnixPath

Yvan KOENIG (VALLAURIS, France) vendredi 13 avril 2012 21:23:29

Offline

 

#6 2012-04-13 01:44:21 pm

Flat5
Member
From:: newyorkcity
Registered: 2011-12-11
Posts: 13

Re: any way to screencapture frontmost window?

no.. i want it to go to the clipboard (hence the -c) so i can paste it in the 'get info' panel in order to give a newly saved file an image icon..

the problem is capturing the right window without user interaction..

Offline

 

#7 2012-04-14 08:07:17 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3208

Re: any way to screencapture frontmost window?

Your message let me think that you wanted to get the screenshot in a file because the code posted by Damiaan correctly put it in the clipboard, at least here under 10.7.3.

Applescript:


activate application "Safari"
tell application "Safari" to set winID to id of window 1 -- get WindowID of frontmost window of frontmost process

do shell script "screencapture -c -x -l " & winID -- -c is used to store it in the clipboard. -x is used to mute the sound. -l is used to refer to the prefered windowid.

Yvan KOENIG (VALLAURIS, France) samedi 14 avril 2012 16:05:34

Offline

 

#8 2012-04-14 10:42:34 am

Flat5
Member
From:: newyorkcity
Registered: 2011-12-11
Posts: 13

Re: any way to screencapture frontmost window?

hey Yvan..

the original post had a hypothetical -fcx  with -f being frontmost window (not real).. -c being clipboard..-x being no sound (ie- i wanted it in the clipboard all along)


the screencapture documentation i was looking at didn't have the -l listed as shown by damiaan (but upon typing screencapture -help in terminal, the -l does show up there..

regardless..  i can't get the proper screenshot in the first place so it doesn't matter at this point wether or not i'm saving it to a file or placing it in the clipboard..


the -l option appears to require a windowID but not all windows have an ID..the window i want to capture does not have a windowID assigned..

so the question now becomes:
Is there a way to assign an ID to a window? Or some other way to tell the screencapture command which window to capture (without user interaction)?

Offline

 

#9 2012-08-27 07:45:39 am

cirno
Member
Registered: 2005-05-30
Posts: 448

Re: any way to screencapture frontmost window?

Aesthir wrote:

using safari for an example, this little script works absolutely great for what i want:

Applescript:

tell application "Safari"
   activate
   set winID to id of window 1
   do shell script "screencapture -c -x -o -l " & winID -- (added the -o for no shadow)
end tell


If i try this, i get "error "Safari got an error: screencapture: illegal option -- l" number 1".

If i open man page for screencapture, it don't have -l option at all???

Offline

 

#10 2012-08-27 01:46:55 pm

McUsr
Member
From:: Southern Norway
Registered: 2010-04-07
Posts: 1776

Re: any way to screencapture frontmost window?

Hello.

you are on Snow Leopard or earlier cirno. Try increasing the number of seconds before it clicks, and focus the window in the mean time. I think that worked for me, when I tried it. smile

And even if you had the -l option, it wouldn't turn up in the manual page, it comes up with the command line help of screen capture.


Mercurial vcs is a joy to use for scripting.


Filed under: screen capture

Offline

 

#11 2015-03-17 09:41:29 am

McUsrII
Member
Registered: 2012-11-21
Posts: 3046
Website

Re: any way to screencapture frontmost window?

Hello.

This is my take on scripting ScreenCapture, it should make a ScreenCapture, with the saved snapshot  following the same  naming standard of a snapshot by  ScreenCapture, when you do it manually. It also  puts the resulting picture of the same type as manual Screen Capture , in the same folder, as it would have been with manual ScreenCapture. (cmd-opt 4, then space, then left mouse click).

Applescript:

use AppleScript version "2.3"
use scripting additions
# Copyright © 2015 McUsr and released under the BSD-3 license: (see [url]http://opensource.org/licenses/BSD-3-Clause)[/url]
# in addition, you can't publish the handlers on a webpage, where those handlers can be perceived to be
# the main content, nor use the handlers in a book.
-- [url]http://macscripter.net/viewtopic.php?pid=179402#p179402[/url]

script loc
   (*

Documentation:

This handler is for returning a localized string, on
some machine from some app, according to the current users
language and locale settings.


How to use this handler:

You have to open the resources folder of the app that you
inted to retrieve the localized string from, and other than
assure that you have got the correct "key" for your localized
string, you have to make a list with any spelled out language
names, and a related list with the language codes, this page may
help when contstructing the lists:

[url]http://www.loc.gov/standards/iso639-2/php/English_list.php[/url]


Returns:

The correct bundle according to the users language and locale
settings, from which we can get the correct localized string.

*)

   on getTheLProjBundle(pxPathToResourcesFolder, langList, lProjList)
       
       # [url]http://macscripter.net/viewtopic.php?pid=179383#p179383[/url]
       set sysLang to word 1 of (do shell script "defaults read -g AppleLanguages")
       # StefanK
       if (count langList) ≠ (count lProjList) then error "getTheLProjBundle: langList is not as long as lProjList"
       set pass to 1
       repeat
           
           if pass = 1 then
               -- check if the first language is amongst the "big" languages.
               if sysLang is in langList then
                   repeat with i from 1 to (count langList)
                       if sysLang is item i of langList then return item i of lProjList
                   end repeat
               else
                   set pass to 2
               end if
           else if pass = 2 then
               -- check if the current AppleLocales are among the very detailed localization bundles.
               try
                   set curLocale to do shell script "/usr/bin/defaults read -g AppleLocale"
               on error
                   set pass to 3
               end try
               if pass = 2 then -- still
                   try
                       tell application id "MACS"
                           set locBundleName to name of first folder of folder (POSIX file pxPathToResourcesFolder as text) whose name begins with curLocale
                       end tell
                       return locBundleName
                   on error
                       set pass to 3
                   end try
               end if
           else if pass = 3 then
               -- check and see if the language, has a related, *normal region specific bundle*
               try
                   set region to (do shell script "/usr/bin/grep \"" & sysLang & "_*\" /usr/share/locale/locale.alias |/usr/bin/head -1 |/usr/bin/sed -En 's/([[:alpha:]]+[[:blank:]]+)([^_]+)_([^.]+)(.*)/\\3/p' |/usr/bin/tr 'A-Z' 'a-z'")
               on error
                   set pass to 4
               end try
               if pass = 3 then -- still . . .
                   try
                       tell application id "MACS"
                           set locBundleName to name of first folder of folder (POSIX file pxPathToResourcesFolder as text) whose name begins with region
                       end tell
                       return locBundleName
                   on error
                       set pass to 4
                   end try
               end if
           else if pass = 4 then
               -- fall back
               -- Thanks to Shane Stanley
               tell application id "MACS"
                   set rcsFol to folder (POSIX file pxPathToResourcesFolder as text)
                   if exists folder "English.lproj" of rcsFol then
                       return "English.lproj"
                   else if exists folder "en.lproj" of rcsFol then
                       return "en.lproj"
                   else
                       error "getTheLProjBundle: No english localization bundle in this App!!"
                   end if
               end tell
           end if
       end repeat
   end getTheLProjBundle
end script

script dt
   on ISO8601LikeDateAndClock()
       -- Thanks to Dan Shockley for putting me in the right direction.
       
       -- ISoLike: because I use dashes to separate the date elements.
       -- like Apple do.
       -- Other than that, the format for the date is YYYYY-MM-DD
       -- The clock is whatever, including seconds, but the entities
       -- are separated with dots like: HH.MM.SS
       -- We deal with an am/pm clock or a 24 hour clock.
       -- the 24 hour clock gets a strict two-digit format.
       -- Am/pm are more "human". :)
       
       tell (current date)
           set D to its short date string
           
           set numyear to year of it as integer
           set numMonth to text -2 thru -1 of ("0" & (month of it as integer))
           set numDay to text -2 thru -1 of ("0" & (day of it as integer))
           set isolikeDate to (numyear & "-" & numMonth & "-" & numDay) as text
           
           -- It is probably an easier way to do this . . .
           set timeFormatProbe to its time string
           
           if "am" is in timeFormatProbe then
               set timeFormatType to "am"
           else if "pm" is in timeFormatProbe then
               set timeFormatType to "pm"
           else
               set timeFormatType to "" -- 24h clock
           end if
           
           if timeFormatType is not "" then -- not 24 hour clock!
               if pm is timeFormatType then
                   set theHours to (hours of it) - 12
               else
                   set theHours to (hours of it)
               end if
               set theMinutes to (minutes of it)
               set theSeconds to (seconds of it)
               set clocktime to theHours & "." & theMinutes & "." & theSeconds & space & timeFormatType
           else
               set theHours to text -2 thru -1 of ("0" & (hours of it))
               set theMinutes to text -2 thru -1 of ("0" & (minutes of it))
               set theSeconds to text -2 thru -1 of ("0" & (seconds of it))
               set clocktime to theHours & "." & theMinutes & "." & theSeconds
           end if
       end tell
       return {isolikeDate, clocktime}
   end ISO8601LikeDateAndClock
   
end script

on FileNameFormatString()
   set hfsAppName to "Macintosh HD:System:Library:CoreServices:SystemUIServer.app:"
   -- WARNING! the hfsname is hardcoded, run the line below, and change the contents of hfsAppName with it.
   -- return (path to application "SystemUIServer" as text)
   set langList to {"nl", "en", "fr", "de", "it", "jp", "es"}
   set lProjList to {"Dutch.lproj", "English.lproj", "French.lproj", "German.lproj", "Italian.lproj", "Japanese.lproj", "Spanish.lproj"}
   set rscPath to POSIX path of ((hfsAppName & "Contents:Resources") as alias)
   set correctLProj to loc's getTheLProjBundle(rscPath, langList, lProjList)
   set correctResource to path to resource correctLProj in bundle file hfsAppName
   set locString to localized string of "%@ %@ at %@" from table "ScreenCapture" in bundle correctResource
   return locString
end FileNameFormatString


on ScreenShotStemName()
   try
       set stemName to do shell script "defaults read com.apple.screencapture name"
   on error
       set stemName to "Screen Shot"
   end try
end ScreenShotStemName


on screenCaptureType()
   try
       set picType to do shell script "defaults read com.apple.screencapture type"
   on error
       set picType to "PNG"
       -- This is an inaccuracy, it should have been "JPEG", but it works as of 2015-03-17.
   end try
   return picType
end screenCaptureType


on getPictureLocation()
   try
       set pictFolder to do shell script "defaults read com.apple.screencapture location"
       tell application id "sevs"
           set pictFolder to POSIX path of item pictFolder
       end tell
   on error
       set pictFolder to POSIX path of (path to desktop folder)
   end try
end getPictureLocation


on stemFileNameForScreenShot(picType)
   -- You'll have to localize this one, so you'll have one that
   -- gives the filenames like the screen capture
   
   set formatStr to FileNameFormatString()
   set stemName to ScreenShotStemName()
   --    set picPath to getPictureLocation()
   set {picDate, picTime} to dt's ISO8601LikeDateAndClock()
   -- Assembly
   
   set ofs1 to offset of space in formatStr
   if ofs1 = 0 then error "The filename format string is probably localized for right to left reading: -->" & formatStr & "<--"
   set intermed to stemName & text ofs1 thru -1 of formatStr
   
   set ofs2 to offset of "%@" in intermed
   if ofs2 = 0 then error "The filename format string is probably localized for right to left reading: -->" & formatStr & "<--"
   set intermed to text 1 thru (ofs2 - 1) of intermed & picDate & text (ofs2 + 2) thru -1 of intermed
   set ofs3 to offset of "%@" in intermed
   set newFn to text 1 thru (ofs3 - 1) of intermed & picTime & "." & picType
   return newFn
end stemFileNameForScreenShot

set picType to screenCaptureType()
set picName to getPictureLocation() & "/" & stemFileNameForScreenShot(picType)

-- Details concerning the screen capture

try
   set dropShadow to (do shell script "defaults read com.apple.screencapture disable-shadow") as integer as boolean
on error
   set dropShadow to false
end try

if dropShadow then
   set shadowOpt to " -o "
else
   set shadowOpt to ""
end if

-- [url]http://macscripter.net/viewtopic.php?id=38482[/url]
tell application id "sevs" -- get frontmost process
   set frontmostProcess to name of first application process where it is frontmost -- this will be the script process
end tell


tell application frontmostProcess to set winID to id of window 1
do shell script "screencapture -x " & shadowOpt & "-T 0 -t " & picType & " -l " & winID & space & quoted form of picName
-- -c is used to store it in the clipboard. -x is used to mute the sound.
-- -T is delay, default is a delay of 0 seconds.
-- -l is used to refer to the prefered windowid.

Edit
Added a comment inside FileNameFormatString() that the path to SystemUIServer is hardcoded, and added an out-commented line that may be run to get the actual path to it.

Edit 2015-03-19
I have set the image type to be of PNG, and not JPG, when it isn't set in the defaults database.
I have also set the default value for disable drop shadows to false, as I am sure that the shadows are on by default.

Last edited by McUsrII (2015-03-18 08:07:08 pm)

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)