Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

"Snipping Tool" - Take quick screenshots using "Gdip.ahk" library


  • Please log in to reply
5 replies to this topic
drozdman
  • Members
  • 17 posts
  • Last active: Dec 05 2015 06:05 AM
  • Joined: 15 Oct 2012

I don't know, if it hasn't already been done, but...

 

I needed something quick to take temporary screenshots of selected areas. I often need to compare something and taking a quick screenshot is very useful for this purpose. Windows "Snipping Tool" is OK, but it doesn't run in multiple instances and it's somewhat bothersome to use.
So I made this script:

Download

• include Gdip.ahk library from http://www.autohotke...ary-145-by-tic/
• To capture a screenshot drag mouse while holding right shift key
• Each screenshot opens its own window from which it can be saved
Windows + G - take a screenshot from a window (enter the window name in the input box)
Escape - exit

 

It doesn't draw a frame while selecting like the Windows "Snipping Tool" does, though.

 

===========================

Edit: After the tip from Blackholyman, I updated the script. Now it draws the frame.

/*  
• include Gdip.ahk library from http://www.autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/
• To capture a screenshot drag mouse while holding right shift key
• Each screenshot opens its own window from which it can be saved
• Windows + G - take a screenshot from a window (enter window name in the input box)
• Escape - exit
*/

#SingleInstance force
SoundPlay *48
Menu, Tray, Icon, pnidui.dll, 12  


;Work_Dir  := "C:\a\"
Work_Dir = %temp%
SetWorkingDir, %Work_Dir%   
    IfNotExist Screenshots
    FileCreateDir, Screenshots

folder_path := A_WorkingDir . "\Screenshots\"
index :=2




OnMessage(0x14, "WM_ERASEBKGND")
Gui, -Caption +ToolWindow
Gui, +LastFound
WinSet, TransColor, Black
; Create the pen here so we don't need to create/delete it every time.
RedPen := DllCall("CreatePen", "int", PS_SOLID:=0, "int", 5, "uint", 0xff)
return






RShift & LButton::
    CoordMode, Mouse, Screen
    MouseGetPos, begin_x, begin_y
    MouseGetPos, xorigin, yorigin
    SetTimer, rectangle, 10
    KeyWait, LButton
    SetTimer, rectangle, Off
    Gui, Cancel
    MouseGetPos, end_x, end_y

    if (end_x > begin_x AND end_y > begin_y){
    ;file%index% := folder_path "screenshot x" begin_x ",y" begin_y " width"  Abs(end_x-begin_x) ", height" Abs(end_y-begin_y) ".png"
    ;screen := begin_x . "|" . begin_y . "|" . Abs(end_x-begin_x) . "|" Abs(end_y-begin_y) ;  X|Y|W|H        
    Capture_x:=begin_x
    Capture_y:=begin_y
    }else  if (end_x < begin_x AND end_y < begin_y){
    Capture_x:=end_x
    Capture_y:=end_y
    }else  if (end_x < begin_x AND end_y > begin_y){
    Capture_x:=end_x
    Capture_y:=begin_y
    }else  if (end_x > begin_x AND end_y < begin_y){
    Capture_x:=begin_x
    Capture_y:=end_y
    }
    
    
    Capture_width:=Abs(end_x-begin_x)
    Capture_height:= Abs(end_y-begin_y)


    screen := Capture_x . "|" . Capture_y . "|" . Capture_width . "|" Capture_height  ;  X|Y|W|H    
    
    ; file%index% := folder_path "screenshot x" Capture_x ",y" Capture_y " width"  Capture_width ", height" Capture_height ".png"    
    file%index% := folder_path  "screenshot " A_Now_Format(A_Now)  ", width" Capture_width " height" Capture_height  ".png"

    x:=file%index%
    Screenshot(x,screen)
    sleep 1000
    Gosub, makeGUI
return


 
rectangle:
    CoordMode, Mouse, Screen
    MouseGetPos, x2, y2
    
    ; Has the mouse moved?
    if (x1 y1) = (x2 y2)
        return
    
    ; Allow dragging to the left of the click point.
    if (x2 < xorigin) {
        x1 := x2
        x2 := xorigin
    } else
        x1 := xorigin
    
    ; Allow dragging above the click point.
    if (y2 < yorigin) {
        y1 := y2
        y2 := yorigin
    } else
        y1 := yorigin
    
    Gui, Show, % "NA X" x1 " Y" y1 " W" x2-x1 " H" y2-y1
    Gui, +LastFound
    DllCall("RedrawWindow", "uint", WinExist(), "uint", 0, "uint", 0, "uint", 5)
return
 



makeGUI:
;Gui,%index% : +LastFound +Resize  +Minsize400x330 ; +AlwaysOnTop
Gui,%index%: Color, 6B8590
Gui,%index%: Margin,0,0
Gui,%index%: Add, Picture, x10 y4 w16 h16 gSave Icon259 AltSubmit, shell32.dll ;

file_GUI:= file%index%
;MsgBox, , , % "makeGUI: " index " - " file1
Gui,%index%: Add, Picture, x0 y24  ,  %file_GUI%
Gui,%index%: Show,, Screenshots - Drozd
index+=1
return

 
 
Save:
;File_num:= "C:\a\My File" A_Gui ".png"
File_num:= file%A_Gui%
FileSelectFile, FileName , S, %File_num% , Save As, Image Files (*.png)  ;C:\a\My File.png
file:=file%A_Gui%
FileCopy, %file%, %FileName%
return


#g:: Gosub, FromWindow

FromWindow:
InputBox, window , Window Title, Enter Window Title, , 300, 100,,,,,ahk_class OperaWindowClass

dat:= A_Now_Format(A_Now)
;file := folder_path  "screenshot ”" window "” " A_Now_Format(A_Now) ".png"
file%index%:= folder_path  "screenshot ”" window "” " A_Now_Format(A_Now) ".png"
ID:= WinExist(window)
y:=file%index%
ClipFromWindow(y,ID)
Gosub, makeGUI
index+=1
return


ClipFromWindow(outfile, ID) {
    pToken := Gdip_Startup()
    pBitmap:=Gdip_BitmapFromHWND(ID)
    Gdip_SaveBitmapToFile(pBitmap, outfile, 100)
    
    
    Gdip_DisposeImage(pBitmap)
    Gdip_Shutdown(pToken)
}


Screenshot(outfile, screen) {
    pToken := Gdip_Startup()
    raster := 0x40000000 + 0x00CC0020

    pBitmap := Gdip_BitmapFromScreen(screen,raster)

    Gdip_SaveBitmapToFile(pBitmap, outfile, 100)
    Gdip_DisposeImage(pBitmap)
    Gdip_Shutdown(pToken)
}



A_Now_Format(raw){
   RegExMatch(raw,"^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})", d)
   date:=d1 "-" d2 "-" d3  " " d4 "-" d5 "-" d6
   return date
}

WM_ERASEBKGND(wParam, lParam)
{
    global x1, y1, x2, y2, RedPen
    Critical 50
    if A_Gui = 1
    {
        ; Retrieve stock brush.
        blackBrush := DllCall("GetStockObject", "int", BLACK_BRUSH:=0x4)
        ; Select pen and brush.
        oldPen := DllCall("SelectObject", "uint", wParam, "uint", RedPen)
        oldBrush := DllCall("SelectObject", "uint", wParam, "uint", blackBrush)
        ; Draw rectangle.
        DllCall("Rectangle", "uint", wParam, "int", 0, "int", 0, "int", x2-x1, "int", y2-y1)
        ; Reselect original pen and brush (recommended by MS).
        DllCall("SelectObject", "uint", wParam, "uint", oldPen)
        DllCall("SelectObject", "uint", wParam, "uint", oldBrush)
        return 1
    }
}




#Include Gdip.ahk


Esc::
FileDelete,  %folder_path%*.png
;FileRecycle,  %folder_path%*.png
;FileRemoveDir,%folder_path%, 1
ExitApp
return







Jackie Sztuk _Blackholyman
  • Spam Officer
  • 3757 posts
  • Last active: Apr 03 2016 08:47 PM
  • Joined: 28 Feb 2012

One way to draw a frame


I would not recommend drawing directly to the screen, since to "move" or "erase" what you draw, you need to redraw the window under it. There are a number of ways to show a frame on the screen; I favour the following method:
OnMessage(0x14, "WM_ERASEBKGND")
Gui, -Caption +ToolWindow
Gui, +LastFound
WinSet, TransColor, Black
; Create the pen here so we don't need to create/delete it every time.
RedPen := DllCall("CreatePen", "int", PS_SOLID:=0, "int", 5, "uint", 0xff)
return
 
WM_ERASEBKGND(wParam, lParam)
{
    global x1, y1, x2, y2, RedPen
    Critical 50
    if A_Gui = 1
    {
        ; Retrieve stock brush.
        blackBrush := DllCall("GetStockObject", "int", BLACK_BRUSH:=0x4)
        ; Select pen and brush.
        oldPen := DllCall("SelectObject", "uint", wParam, "uint", RedPen)
        oldBrush := DllCall("SelectObject", "uint", wParam, "uint", blackBrush)
        ; Draw rectangle.
        DllCall("Rectangle", "uint", wParam, "int", 0, "int", 0, "int", x2-x1, "int", y2-y1)
        ; Reselect original pen and brush (recommended by MS).
        DllCall("SelectObject", "uint", wParam, "uint", oldPen)
        DllCall("SelectObject", "uint", wParam, "uint", oldBrush)
        return 1
    }
}
 
+LButton::
    MouseGetPos, xorigin, yorigin
    SetTimer, rectangle, 10
return
 
rectangle:
    MouseGetPos, x2, y2
    
    ; Has the mouse moved?
    if (x1 y1) = (x2 y2)
        return
    
    ; Allow dragging to the left of the click point.
    if (x2 < xorigin) {
        x1 := x2
        x2 := xorigin
    } else
        x1 := xorigin
    
    ; Allow dragging above the click point.
    if (y2 < yorigin) {
        y1 := y2
        y2 := yorigin
    } else
        y1 := yorigin
    
    Gui, Show, % "NA X" x1 " Y" y1 " W" x2-x1 " H" y2-y1
    Gui, +LastFound
    DllCall("RedrawWindow", "uint", WinExist(), "uint", 0, "uint", 0, "uint", 5)
return
 
+LButton Up::
    SetTimer, rectangle, Off
    Gui, Cancel
return
(Use Shift+LButton or edit before running.)
 
 
Seems to have a script like your's at the end from Wicked

Helping%20you%20learn%20autohotkey.jpg?d

[AHK] Version. 1.1+ [CLOUD] DropBox ; Copy [WEBSITE] Blog ; About

drozdman
  • Members
  • 17 posts
  • Last active: Dec 05 2015 06:05 AM
  • Joined: 15 Oct 2012

@Blackholyman

Thanks. This script is perfect. I only needed to add "CoordMode, Mouse, Screen", because the frame wasn't synchronized with the mouse.
I will update the script now, including drawing the frame.



drozdman
  • Members
  • 17 posts
  • Last active: Dec 05 2015 06:05 AM
  • Joined: 15 Oct 2012

I found a nice PNG compression tool here http://www.autohotke...ss-png-wrapper/.

High quality of screenshots is rarely necessary, so this can be very useful.

 

In the "Save" subroutine pngquanti.exe can be used 

Save:
File_num:= file%A_Gui% 
FileSelectFile, FileName , S, %File_num%.png , Save As, Image Files (*.png)  ;C:\a\My File.png
file:=file%A_Gui% 

;FileCopy, %file%, %FileName%

;======================== compress with pngquant
CompressPNG := "C:\Program Files\Misc\PNGquant\libs\pngquanti\pngquanti.exe" ; path to pngquant
RunWait , %CompressPNG% "%file%"

RegExMatch(file,"^(.*)\.png$", f)
file:= f1 . "-fs8.png"

FileCopy, %file%, %FileName%
;========================
return


medellinrob
  • New members
  • 1 posts
  • Last active: Mar 07 2019 08:29 PM
  • Joined: 08 Sep 2015

Hi!

I get an error in all lines that stat with GUI, most natably the first one of course:

Gui,%index%: Color, 6B8590

Yes I downloaded GDIP.ahk and put it in "My Documents".

I started it and still the same error.

 

I replaced all %index% with a number 2 and no more errors, but I don't get any image...

Anything else I might need to tweak/install/configure?

I



drozdman
  • Members
  • 17 posts
  • Last active: Dec 05 2015 06:05 AM
  • Joined: 15 Oct 2012

@medellinrob

Maybe you need to use a full path to the Gdip.ahk? I checked the script and it's working. 

Though on the second thought... If you use Windows 8 ... I tried it on Windows 8 and indeed it doesn't work. But not the indexed GUI, but probably Gdip.ahk. I'm not gonna look into why.. I don't use this junk Windows 8 anyway. Or the new Windows.