制作步骤:
[1] 设置三个快捷键,分别是 xdotool, 两种 --countdown 和 --area 两种选项。之所以需要 xdotool 当代理人是因为无法直接用 scrot -s/gnome-screenshot -a, shutter 没这个问题。/home/xiaobai/note/sh/my_gnome_area.sh 是我的代码文件路径。
【2】
my_gnome_area.sh script 代码 (无 comments 纯净版):
for cmd in "mktemp" "shutter" "feh" "wmctrl" "notify-send" "ts" "eog" "gimp" "convert" "tesseract" "gedit" "firefox" "curl" "xargs" "konsole" "vimx" "yad"; do command -v $cmd >/dev/null 2>&1 || { LANG=POSIX; xmessage "Require $cmd but it's not installed. Aborting." >&2; exit 1; }; :; done mkdir -p -- "$HOME/Pictures/print_screen_note/" tmpj="$(mktemp /tmp/`date +"%s_%Y-%m-%d"`_XXXXXXXXXX.png)" tmpocr="$(mktemp -u /tmp/`date +"%s_%Y-%m-%d"`_ocr_XXXXX)" tmpocr_p="$tmpocr"+'.png' if [[ "$@" == "--area" ]]; then gnome-screenshot -a -f "$tmpj" 2>&1 >/dev/null | ts >>/tmp/gnome_area_PrtSc_error.log elif [[ "$@" == "--countdown" ]]; then shutter -s -d 5 -c -e -o "$tmpj" 2>&1 >/dev/null | ts >>/tmp/shutter_PrtSc_error.log else echo "Invalid argument." | ts >>/tmp/PrtSc_error.log exit 1 fi function ocr () { tmpj="$1" tmpocr="$2" tmpocr_p="$3" atom="$(tesseract --list-langs 2>&1)"; atom=(`echo "${atom#*:}"`); atom=(`echo "$(printf 'FALSE\n%s\n' "${atom[@]}")"`); atom[0]='True' ans=(`yad --center --height=200 --width=300 --separator='|' --on-top --list --title '' --text='Select Languages:' --radiolist --column '✓' --column 'Languages' "${atom[@]}" 2>/dev/null`) && ans="$(echo "${ans:5:-1}")" && convert "$tmpj[x2000]" -unsharp 15.6x7.8+2.69+0 "$tmpocr_p" | yad --on-top --title '' --text='Converting ...' --progress --pulsate --auto-close 2>/dev/null && tesseract "$tmpocr_p" "$tmpocr" -l "$ans" 2>>/tmp/tesseract.log | yad --percentage=50 --on-top --title '' --text='Tesseracting ...' --progress --pulsate --auto-close 2>/dev/null && if [[ "$ans" == 'eng' ]]; then konsole -e "vimx -c 'setlocal spell spelllang=en_us' -n $tmpocr.txt" 2>/dev/null; else gedit "$tmpocr.txt"; fi rm "$tmpocr_p" } export -f ocr feh -x \ -A "cp %F ~/Pictures/print_screen_note/%N" \ --action1 "notify-send ' ' -u critical 'd: title, up/down: zoom, w: win_to_img, </>: rotate, *: orig, Enter/0: save to ~/Pictures/print_screen_note/, 1: Help, m/right_clic: context menu, 2: Always on top, 3: Remove always on top, 4: shutter, 5: eog, 6: gimp, 7: OCR, 8: Note directory(Left/Right to navigate), 9: Google. Alt+F7(Might cause mouse pointer lag) to move windows like Left_mouse_click+Super keys. After position changed, Esc to cancel, Enter to confirm.'" \ --action2 "wmctrl -a \"feh [1 of 1] - $tmpj\" -b add,above" \ --action3 "wmctrl -a \"feh [1 of 1] - $tmpj\" -b remove,above" \ --action4 "shutter $tmpj &" \ --action5 "eog $tmpj &" \ --action6 "gimp $tmpj &" \ --action7 "ocr $tmpj $tmpocr $tmpocr_p &" \ --action8 "feh -x ~/Pictures/print_screen_note/ &" \ --action9 "(curl -sf --output /dev/null -w '%{redirect_url}' -F 'image_url=' -F 'image_content=' -F 'filename=' -F 'h1=en' -F 'bih=' -F 'biw=' -F "encoded_image=@$tmpj" 'https://www.google.com/searchbyimage/upload' | xargs -rL1 firefox -new-tab)&" \ "$tmpj" 2>&1 >/dev/null | ts >>/tmp/PrtSc_error.log
【3】
虽然我上面的代码开头有检查需要用的 utilities/工具然后给出错误信息,但还是要说,最好先手动试这些 commands 能跑,往后就可以 comment out 那个 checking:
[1] mktemp
- coreutils package
[2] shutter
[3] feh
- 这个 我记得是自己 compile 才能完全 borderless 的。新的 Fedora 不懂有没有 fix。
[4] wmctrl
[5] notify-send
- libnotify package, 如果 install 找不到 package,可以用 dnf whatprovides /usr/bin/notify-send 寻找真正的 package 名字来安装。
[6] ts
- moreutils package
[7] eog
[8] gimp
[9] convert
- ImageMagick package
[10] tesseract
- 用这个 command 确保有三种语言, 英文/繁体/简体:
[xiaobai@xiaobai sh]$ tesseract --list-langs
List of available languages (3):
eng
chi_tra
chi_sim
[xiaobai@xiaobai sh]$
如果没有繁体/简体(通常都是没有的 la),就安装语言包, 例如 dnf 安装:
- dnf install tesseract-langpack-chi_sim tesseract-langpack-chi_tra
- 不过那个代码是 dynamic list down 语言来 create dialog 的, 所以其实你可以有很多语言。
[11] gedit
[12] firefox
[13] curl
[14] xargs
- findutils package
[15] konsole
- 虽然 heavy, 我坚持安装 kde terminal 在 gnome 主要是因为只有 konsole 能支持全局 highlight 搜索, 其它 terminal 最多只能同时 highlight 一个。由于本人很依赖全局 highlight(grep 做不到的,跑完 command 又要重新跑多一次 grep 咩,又或者还要 copy 去 gedit 全局搜索 ? 天黑 lor), 所以真的很惊讶到现在 2016 年 gnome-terminal 还是没有这个功能。就算 terminology 很 cool 都然并卵。
[16] vimx
- vim-X11 package
[17] yad
[18] gnome-screenshot
[19] xmessage, X 都有吧,所以我才用它当检查 commands 不在的默认 dialog。
- [更正] Fedora 24 需要安装 org-x11-apps 才有 xmessage。也要安装 xdotool 才能给 shortcut key 那边用。
【4】
还有一些零碎的要点:
[1] 我用的是没有 wallpaper 的黑屏幕。Fedora 21 Gnome 3。
[2] 用 [Super+mouse] 有时会拉上去 top panel, 只要用 [Super+mouse] 拉下来即可。
[3] 需要 Notifications settings 那里 Enable "Show Pop Up Banners" 才能看到 Help menu dialog, 不过正常应该已经 Enable 的。
[4] 我用的 gnome extension 包括 Disable window is ready notification, 以及让 notification 出现在上面而不是下面的 Panel OSD。
[5] 在 feh 按 [a] 会出现 --action
[6] [上/下键] 缩大小, 是和 [w] fit window 一起用的组合。
[7] scrot 选 area 的线条有时会闪出很多条线,用 gnome-screenshot 比较好。
[8] [Super+mouse], Super 键按一次其实已经是 drag 着了,不需要一直按,虽说我还是习惯一直按方便改位置。
【5】
my_gnome_area.sh script 代码 (comments 版):
#keep in mind, use >> instead of > to log <<"TODO" [1] Add open /tmp/ dir support, in case accidentally close [2] Make #[1] and note dir open as this customized --action feh #The quick workaround is screenshot again on note window, not a MUST have feature though [3] not sure if better default to "alwasy on top" when feh display TODO #User should ensure tesseract installed "tesseract-langpack-chi_sim" "tesseract-langpack-chi_tra" #search and replace all for "firefox" and "drive-linux-x64" if you are prefer difference web browser or gdrive-linux-386 ...etc #use yad instead of zenity to support --on-top for cmd in "mktemp" "shutter" "feh" "wmctrl" "notify-send" "ts" "eog" "gimp" "convert" "tesseract" "gedit" "firefox" "curl" "xargs" "konsole" "vimx" "yad"; do #moreutils for `ts` AND diff err filename help to distinguish the occurrence, which unreliable to prefix some title before stderr append to err file tricks #| ts is stdout only, |& is 2>&1 stdout+stderr, [optional 1]>/dev/null |& is stderr only #When `ls -R /tmp/* 2>&1 2>/dev/null | grep i` the 2nd 2>/dev/null actually bring <<"PIPE" #imagine: #will stderr "my_gnome_area.sh: line 4: imagine:: command not found" if not put '#' infront "imagine:" original: #nobody --> /dev/null fd #1 symlink --> stdout fd #2 symlink --> stderr fd 2>&1 means point to #1's fd #nobody --> /dev/null fd #1 symlink --> stdout fd #2 symlink -----^ #nobody --> stderr fd then 1>/dev/null means #1 symlink --> /dev/null fd #2 symlink --> stdout fd(so only #2 will pipe and become next command's #1) #nobody --> stderr fd So, `>/dev/null |&` same like `>/dev/null 2>&1 |` and means stdout fd is empty to pipe (e.g. `ls -R /tmp/* >/dev/null 2>&1 | grep i` will give empty, but `ls -R /tmp/* 2>&1 >/dev/null | grep i` will got #2 as explained above) Noted oso 2>/dev/null will only tied fd without execute remove yet, so if 2>/dev/null 2>&1 will still able to pipe All due to no such thing stdin_pre_out and stdin_pre_err, instead only have one door for stdin per process/pipe which accept stdout only from prev pipe, stderr nid bundle with stdout or use other trick to pass to next pipe. PIPE command -v $cmd >/dev/null 2>&1 || { LANG=POSIX; xmessage "Require $cmd but it's not installed. Aborting." >&2; exit 1; }; :; done mkdir -p -- "$HOME/Pictures/print_screen_note/" tmpj="$(mktemp /tmp/`date +"%s_%Y-%m-%d"`_XXXXXXXXXX.png)" #Use .jpg will blur, see below comments [#keyword 'blur'] tmpocr="$(mktemp -u /tmp/`date +"%s_%Y-%m-%d"`_ocr_XXXXX)" #-u means --dry-run, not -d tmpocr_p="$tmpocr"+'.png' if [[ "$@" == "--area" ]]; then gnome-screenshot -a -f "$tmpj" 2>&1 >/dev/null | ts >>/tmp/gnome_area_PrtSc_error.log #bug: blur quality rf: https://bugs.launchpad.net/ubuntu/+source/gtk+3.0/+bug/1512290 #for gnome-screenshot, blur img due to it's jpg, if use png will good quality #scrot -s "$tmpj" 2>&1 >/dev/null | ts >>/tmp/scrot_area_PrtSc_error.log #scrot -s -e 'mv $f'" $tmpj" 2>&1 >/dev/null | ts >>/tmp/scrot_area_PrtSc_error.log #originally the img is blur, then i figure out direct_shortcut/cmd no problem, only script(not exactly true, see later comment #1), then use strace and found the filename diff, so i realize is bcoz "$tmpj" is set here and i play around `scrot -s /tmp/xxx` inside konsole and got error "giblib error: Saving to file /tmp/xxx failed". Then i realize script without predefined_filename have good quality [#1]. So the problem actually is predefined_filename even though still can output blur img to next instruction/feh. #So why 'mv $f'" $tmpj" got mix single/double quotes ? Bcoz $f not suppose to be expand by bash, instead if should keep literaly '$f' and pass to scrot to interprete/process. And so we write '$f' for unexpand by bash, and "$tmpj" for expand by bash. #[REAL REASON] the above mentioned 'without predefined_filename have good quality' is misleading, bcoz the real reason is bcoz i use .jpg when `mktemp`, so either scrot or gnome-screenshot will both blur bcoz it assume i want JPEG which poor quality. But, if no predefined_filename means assume PNG by default, even after `mv` to .jpg, it's actually a PNG image(can check by `exiftool`) with wrong extension(`eog` will not show mismatch extension but `display` did). elif [[ "$@" == "--countdown" ]]; then shutter -s -d 5 -c -e -o "$tmpj" 2>&1 >/dev/null | ts >>/tmp/shutter_PrtSc_error.log #shutter no nid agent custome shortcut key to works #-c include cursor, -e dont show shutter viewer after captured #gnome-screenshot -d 5 -f "$tmpj" 2>&1 >/dev/null | ts >>/tmp/gnome_area_error.log #unable include context menu with area #use xclock to show time if used else echo "Invalid argument." | ts >>/tmp/PrtSc_error.log exit 1 fi <<"GDRIVE" #deprecated since Google not strict on encoded anymore #oso remove on the top's checking #Full request(refer it if not working): curl -s -F "image_url=" -F "image_content=" -F "filename=" -F "h1=en" -F "bih=" -F "biw=" -F "encoded_image=@1460127392_2016-04-08_i092fx0gu2.png" https://www.google.co.in/searchbyimage/upload #base64 url: echo "data:image/jpeg;base64,$(base64 -w 0 $tmpj)" function gdrive () { img_id="$(drive-linux-x64 upload --share -f $1 | head -n1 | cut -f2 -d ' ')"; firefox -new-tab 'https://www.google.com/searchbyimage?site=search&sa=X&image_url=https://drive.google.com/uc?id='"$img_id" #Unless u can firefox open new tab return 200 google ok, otherwise sleep only lor, so you nid visits gdrive to delete manually if shutdown before wake up something #so, give up to 30 seconds for google get the uploaded large file sleep 30; drive-linux-x64 delete -i "$img_id" } export -f gdrive #use 'gdrive "$tmpj" &' to call GDRIVE #Bcoz common use of "Always on top" on feh, better if can focus zenity, but it's still mark as [todo] target at 3.2(mine is 3.14.0), rf: https://wiki.gnome.org/Projects/Zenity #zenity's -radiolist nid --hide-header if used, yad no such arg #yad's has new args: --center(progress better on upper left(curr default) instead of middle), --separator='|'(set it even though currently is default for safety to parse "$ans") and --on-top over zenity #depends on current mouse focus, zenity/yad/konsole will on relevant monitor display when pop up #yad -pulsate not working but zenity works fine, but still --on-top more important than this progress bar animation, so still use yad #keep in mind if konsole support language other than english then vimx's "setlocal spell spelllang=en_us" might nid consider to redesign to support misc lang, not MUST though function ocr () { tmpj="$1" tmpocr="$2" tmpocr_p="$3" #[WRONG bcoz i'm accidentally put double (()) in 1st statements, actually no nid atom[-1]=${atom[-1]%?}; to remove trailing ')' ] #atom="($(tesseract --list-langs 2>&1))"; atom=(`echo "${atom#*:}"`); atom[-1]=${atom[-1]%?}; atom=(`echo "$(printf 'FALSE\n%s\n' "${atom[@]}")"`); atom[0]='True' atom="$(tesseract --list-langs 2>&1)"; atom=(`echo "${atom#*:}"`); atom=(`echo "$(printf 'FALSE\n%s\n' "${atom[@]}")"`); atom[0]='True' ans=(`yad --center --height=200 --width=300 --separator='|' --on-top --list --title '' --text='Select Languages:' --radiolist --column '✓' --column 'Languages' "${atom[@]}" 2>/dev/null`) && ans="$(echo "${ans:5:-1}")" && convert "$tmpj[x2000]" -unsharp 15.6x7.8+2.69+0 "$tmpocr_p" | yad --on-top --title '' --text='Converting ...' --progress --pulsate --auto-close 2>/dev/null && tesseract "$tmpocr_p" "$tmpocr" -l "$ans" 2>>/tmp/tesseract.log | yad --percentage=50 --on-top --title '' --text='Tesseracting ...' --progress --pulsate --auto-close 2>/dev/null && if [[ "$ans" == 'eng' ]]; then konsole -e "vimx -c 'setlocal spell spelllang=en_us' -n $tmpocr.txt" 2>/dev/null; else gedit "$tmpocr.txt"; fi rm "$tmpocr_p" } export -f ocr <<"SEARCH_BY_IMG" - https://developer.chrome.com/extensions/settings_override - https://chromium.googlesource.com/chromium/src.git/+/46.0.2478.0/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc - http://extra.dyndns-web.com/105/10500021_1_JPG.TXT - https://www.chromium.org/administrators/policy-list-3 - https://chrome.googleblog.com/2013/10/search-by-image-and-new-chrome-for.html SEARCH_BY_IMG feh -x \ -A "cp %F ~/Pictures/print_screen_note/%N" ${IFS# [1] no nid cp bcoz after mv still can navigate/zoom...etc. [UPDATE] use cp bcoz what if trigger eog after Enter ? [2] -A means --action0 too} \ --action1 "notify-send ' ' -u critical 'd: title, up/down: zoom, w: win_to_img, </>: rotate, *: orig, Enter/0: save to ~/Pictures/print_screen_note/, 1: Help, m/right_clic: context menu, 2: Always on top, 3: Remove always on top, 4: shutter, 5: eog, 6: gimp, 7: OCR, 8: Note directory(Left/Right to navigate), 9: Google. Alt+F7(Might cause mouse pointer lag) to move windows like Left_mouse_click+Super keys. After position changed, Esc to cancel, Enter to confirm.'" ${IFS# alternative is xmessage ''} \ --action2 "wmctrl -a \"feh [1 of 1] - $tmpj\" -b add,above" ${IFS# [1] use wmctrl -l too see the title or feh without -x to double check [2] toggle,above not working} \ --action3 "wmctrl -a \"feh [1 of 1] - $tmpj\" -b remove,above" \ --action4 "shutter $tmpj &" ${IFS# [1] 'sometime' no nid & like other gui [2] not sure why got use mktemp-like 10 chars create new /tmp/ file [3] feature: can set arrow} \ --action5 "eog $tmpj &" ${IFS# [1] nid & to continue play feh base image without have to close gui or xkill base img, but no nid disown [2] can drag and drop to fb comment} \ --action6 "gimp $tmpj &" ${IFS# f free select, ctrl+shift+v from clipboard, ctrl+e export} \ --action7 "ocr $tmpj $tmpocr $tmpocr_p &" ${IFS# see #OCR comment} \ --action8 "feh -x ~/Pictures/print_screen_note/ &" ${IFS# only refresh latest pictures on next --action8} \ --action9 "(curl -sf --output /dev/null -w '%{redirect_url}' -F 'image_url=' -F 'image_content=' -F 'filename=' -F 'h1=en' -F 'bih=' -F 'biw=' -F "encoded_image=@$tmpj" 'https://www.google.com/searchbyimage/upload' | xargs -rL1 firefox -new-tab)&" ${IFS# see #gdrive comemnt} \ "$tmpj" 2>&1 >/dev/null | ts >>/tmp/PrtSc_error.log <<"OCR" [1] quality 100% bigger size but same output. [2] -alpha reset or activate or deactivate same and copy is bad. [3] -colorspace gray is lose even though have some win. [4] recommended 0x0.75+0.75+0.008 if larger than 500 pixels is bad, [5] no nid care about random files for ocr, support multi convert in the same time is overkill. [6] use "Always on Top" for other windows is normal to build your screen layout :) [7] use ()& to bundle whole commands to bg, not just put at the end. [8] For unknown reason tesseract normal log oso stderr, so nid /tmp/tesseract.log to avoid ocr success still update PrtSc_error.log. [9] got `convert -monitor` but how to pass its updating % to zenity on the fly [10] zenity 2>/dev/null to discard "Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged." [11] gedit better chinese chars look, and no point check spelling [12] can better if able make konsole pop up in medium win size rf1: http://www.imagemagick.org/Usage/resize/#resize_unsharp, rf2: http://stackoverflow.com/questions/9480013/image-processing-to-improve-tesseract-ocr-accuracy (radius = 6.8, amount = 2.69, threshold = 0, which 6.8+1 and *2, threshold 0/255 still 0), rf3: http://www.imagemagick.org/Usage/blur/#unsharp, rf4: http://www.imagemagick.org/discourse-server/viewtopic.php?t=23747, rf5: http://www.imagemagick.org/discourse-server/viewtopic.php?t=22998 OCR
【6】[更正] 不同于 Fedora 21, 新的 Fedora 24 的 notify-send 需要题目至少要有 ' ' 才能看到完整的内容。Credit。
有一些无法实现的,如 gimp free selection 变成相对应的 borderless。
无论如何,想象一下未来,随手一剪,就能把浏览器的穿一个洞。随手一剪,就能把 fb 的 album 拉出来变成 standalone 的 window。
[更新: kali]
本人用 debian based 的 kali 2016.2 后,发现一些不同的地方。
[1] 安装的命令: sudo apt-get install tesseract-ocr-chi-sim tesseract-ocr-chi-tra yad gimp moreutils notify-osd libnotify-bin wmctrl feh shutter xdotool vim-gtk3
[2] 其中, tesseract 改了一点名字,notify-osd 和 libnotify-bin 提供 notify-send。要注意的是,安装 vim-gtk3 后, 有了 gvim,然后做 `mv /usr/bin/gvim /usr/bin/vimx` 以及 `ln -s /usr/bin/vimx /usr/bin/gvim`,理由是我的 Fedora 24, vimx 本来就是 link 去 gvim,只不过必须要用 vimx 的名义才不会出现新的 GUI, 而是在 terminal 里头。(更新) 好像是 sudo apt-get install vim-gnome 才对,总之刚才被 vimrc 搞得团团转我现在很晕,不懂 default 是怎样的 (现在是 /usr/bin/vimx -> /etc/alternatives/gvim* --> ... ---> /usr/bin/vim.gtk3*)。
[3] xdotool 不稳定,把那个原本 <Super+S> 的 agent 按 Backspace disable 掉它。<Super+S> 需要 restart ganti 掉原本的 key 才稳定。
[4] export -f ocr 竟然不能 work !!! 应该是 kali 默认用速度快但功能老牙的 dash 弄到的。所以把 OCR 那部分拉出来放在 /usr/bin/ocr,首行加上 #!/bin/bash,然后 `sudo chmod +x` 它:
[再更新:]
我刚才终于有空研究了一下,发现是 feh 默认使用 sh, 或 kali 的 dash (用 type -a 的 error 是一样的,就是不能用 -a)。这里的 export -f ocr 运行在 bash 当然只对 bash 有效而不是 dash,所以不能把问题归咎于 bash 不支持 export。 改成 --action7 "/bin/bash -c \"ocr $tmpj $tmpocr $tmpocr_p & \"" ${IFS# see #OCR comment} \ 后,问题即可解决。
[更新: Ubuntu 17.04]
[1] 默认是 <Alt> 键+ left-click 来搬图片 window。 必须打开 dconf-editor, 然后去 org → gnome → desktop → wm → preferences → mouse-button-modifier 把 <Alt> 改成 <Super>。
[2] 还是必须用 /usr/bin/ocr 解决类似 kali 的 `export -f ocr` 不 work 问题。
[Skyshot]
我独自开发的革命性 screenshot app, Skyshot 在 Google Play 上架啦。
免费+无广告,欢迎亲们下载哟 爱你们
https://play.google.com/store/apps/details?id=com.blogspot.diannaoxiaobai.skyshot
[更新]
后来我自创的 print screen 风格已很完善了,此文没更新我使用 ev_test 来达成浏览 /tmp/ 文件。