28

I have an image on screen, and I want to measure its width. Of course I can use a ruler, but that's whimsical and slow. Is there something where I can click a shortcut key, drag out an area, and it will tell me the height and width of that area?

Something similar to Page Ruler for Google Chrome.

Currently, I am using Shift + PrtScn and dragging out the area, save the image, and then go into Properties to find out its height and width.

10

Using shutter

First install Shutter if you don't have it installed.

sudo apt-get install shutter

Open up preferences under Edit -> Preferences and select the behaviour tab.
Check 'Start shutter at login' and 'Hide window on first launch'. See screenshot below:

enter image description here

Usage

  1. Make sure the shutter panel icon is visible and select your window or whatever you want to measure.
  2. Click on the shutter icon and select 'selection'.

enter image description here

  1. Select your starting point and drag to your end point. The whole window will darken except your selection. You can move the borders around to get more 'to the point' results.
  2. Shutter will provide a dialog window with the X and Y coordinates and the size (which is what you want) of the selection. See screenshot below in the top-left corner of an example.

enter image description here

  1. A zoomed out screenshot showing it to be 727px by 367px:

enter image description here

  1. Finally just press Esc to dismiss the selection and hide shutter.
  2. Continue with whatever you were doing.
  • Very neat! I like the crosshair feature here! Very full featured - can take Window, selection, have delay etc. – dayuloli Feb 16 '15 at 2:58
42

How it works

The script below measures the size of an area, between two locations of the mouse pointer.

It works as followes:

  1. Place the mouse pointer in the first position (without clicking)

    enter image description here

  2. Press the key combination of your choice (see further below)

  3. Place the mouse in the second position (again without clicking)

    enter image description here

  4. Press your key combination again. A notification will tell you the exact size (px) of the area.

    enter image description here

Options

You can choose (by uncommenting one of the lines) how you'd like to be notified; either by a notification:

enter image description here

Or a Zenity info window:

enter image description here

(The examples are from different areas)

How to use

  1. The script uses xdotool:

    sudo apt-get install xdotool
    
  2. Copy the script below into an empty file, uncomment either one of the lines:

    command = ['notify-send', 'Area size', str(w)+' x '+str(h)]
    

    (to be notified by the notify-send option)

    or:

    command = ['zenity', '--info', '--title', 'Area Size', '--text', str(w) + ' x ' + str(h)]
    

    for the Zenity option.

  3. Save the script in ~/bin (you will probably have to create the directory) as measure_area (no extension) and make it executable.

  4. Add a key combination of your choice to run the script: Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    measure_area
    

Notes

  • You will have to log out / in first
  • It does not make a difference what you take as first/second position; the script measures absolute values.

The script

#!/usr/bin/env python3
import subprocess
import os
import math

home = os.environ["HOME"]
area = home+"/"+".measure_area.txt"

def get_pos():
    pos_data = subprocess.check_output(["xdotool", "getmouselocation"]).decode("utf-8")
    return [m[2:] for m in pos_data.split()[:2]]

def confirm():
    get = subprocess.check_output(["xrandr", "--verbose"]).decode("utf-8").split()
    for s in [get[i-1] for i in range(len(get)) if get[i] == "connected"]:
        br_data = float(get[get.index("Brightness:")+1])
        brightness = lambda br: ["xrandr", "--output", s, "--brightness", br]
        flash = ["sleep", "0.1"]
        for cmd in [brightness(str(br_data-0.1)), flash, brightness(str(br_data))]:
            subprocess.call(cmd)

if not os.path.exists(area):
    with open(area, "wt") as measure:
        measure.write(str(get_pos()))
    confirm()
else:
    second = get_pos()
    with open(area) as first_m:
        try:
            first = eval(first_m.read())
            w = int(math.fabs(int(second[0]) - int(first[0])))
            h = int(math.fabs(int(second[1]) - int(first[1])))
            #--- uncomment either one of the lines below:
            # command = ['notify-send', 'Area size', str(w)+' x '+str(h)]
            command = ['zenity', '--info', '--title', 'Area Size', '--text', str(w) + ' x ' + str(h)]
            #---
            confirm()
        except SyntaxError:
            text = "Please try again, there was an error in the data"
            command = ['zenity', '--info', '--title', 'Please try again', '--text', text]
        subprocess.Popen(command)
    os.remove(area)

Explanation

When the script is called the first time, it gets the current mouse position with the xdotool command:

xdotool getmouselocation

It then saves the position into an (invisible) file .measure_area.txt, waiting for the second call.
On the second call, it reads the file, removes it and compares the stored x/y coordinates to the latest ones, and calculates the size of the area between them.

Edit

Updated the script with a number of improvements:

  • Optimized subprocess.Popen()/subprocess.check_output() commands (thanks to @muru, @Trengot)
  • Added a repair procedure in case something went wrong with the first-data file (e.g. if user first tried to run the script without having xdotool installed)
  • Added a small confirming screen dim-flash when the key combination is pressed for the first coordinates. It seems a bit more user-friendly to give the user some kind of confirmation of the action.
  • 1
    Awesome! Tried it out just now, works perfectly! Thank you! You deserve a medal really! – dayuloli Feb 10 '15 at 10:51
  • 2
    @dayuloli Thanks for the question! I love doing stuff like this. – Jacob Vlijm Feb 10 '15 at 10:52
  • Nice! +1. Curious: Why Popen(['/bin/bash',... instead of Popen(['zenity', '--info', ...? – muru Feb 10 '15 at 10:59
  • 1
    Fiddling with quotes? O.o command = ['zenity', '--info', '--title', 'Area Size', '--text', str(w) + ' x ' + str(h)]; subprocess.Popen(command) requires a lot less messing around with ' and ", I think. – muru Feb 10 '15 at 11:21
  • 1
    Could the same change be made for xdotools? Something like check_output(['xdotools', 'getmouseposition'])? – Holloway Feb 10 '15 at 13:55
2

Using slop

Another simple way of determining the area of a selection is by using slop (Select Operation), a command-line utility "that queries for a selection from the user and prints the region to stdout."

slop is a comparitively new tool and has not been packaged for Debian/Ubuntu, yet. As it stands you will have to compile it from source:

sudo apt-get install build-essential cmake libxext-dev
git clone https://github.com/naelstrof/slop.git
cd slop
cmake ./
make && sudo make install

The installation is the most difficult part. slop itself is actually very easy to work with. For instance, the following one-liner will prompt you to select a screen area and will both display the result as a notification and write it to the clipboard:

eval $(slop -t 0 -b 1) && notify-send  "Selection info" "Area: ${W} x ${Y}px \n Position: X = ${X}px, Y = ${Y}px" && echo ${W}x${H} | xsel -bi

Screenshot:

enter image description here

A quick breakdown of the commands used:

  • slop -t 0 -b 1 - prompt the user to select a screen area; do not select full windows (-t 0), set selection border to 1px (-b 1)
  • eval $(...) - read output of slop into variables
  • notify-send ... - send GUI notification with information on selected area
  • echo ${W}x${H} | xsel -bi - copy dimensions to clipboard (requires xselsudo apt-get install xsel)

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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