Page 1 of 1

Screen Surveyor 1.2 (Windows)

Posted: Sun Apr 03, 2016 9:36 am
by RichardL
Good morning,

Screen Surveyor
==============
From time to time I need to check the dimensions of screen features and check their RGB values. For example, how big is the working area of that window or gadget? Are those two areas the same colour? Is that line vertical / horizontal? What size font is that?

I decided that guesswork was no longer good enough and started to create this little tool to measure pixel separations and colours. You might find it useful.

To use the F1 (anchor datum) and F2 (write RGB value to clipboard) ScreenSurveyor must have the focus.

While writing ScreenSurveyor I initially used <<ResizeImage(T3,120,120,#PB_Image_Raw)>> to produce the magnified display of the mouse region, but because I could not convince myself it was completely free from introducing artefacts, I wrote my own version. Which gave the same results, so it must be my graphics card! Anyway, the version here uses my up-scaler because I went to the trouble of writing it so might as well inflict on all you good folk!

Please let me know how you get on with Screen Surveyor and of any bugs you find or little tweaks you would like (no promises!)

RichardL

PS: If there are any updates I will post them here.

Code: Select all

; Screen Surveyor R1.2 - A utility for measuring screen layouts and checking colours

; (C) Richard Leman 2016. Use, plunder or ignore at your own risk!

; Magnify 1 - 6 with spin gadget
; Set delta origin with hot key F1
; Delta X,Y for showing sizes
; Bump mouse position with cursor keys for accurate movements
; Tidy captions and results
; Colour blob for confirming centre point colour
; Copy colour RGB(n,n,n) to scratchpad with F2
; Calibrate and test targets

Version$ = "ScreenSurveyor 1.2"

; Tidy the calibrate and test target

Mag    = 2
OldMag = 2
OldX   = -1
OldY   = -1
DatX   = 0
DatY   = 0

; User interface
OpenWindow(1,800,100,290,250,Version$, #PB_Window_SystemMenu)
SetWindowColor(1,RGB(200,220,255))

TextGadget(#PB_Any,05,5,120,20,"Mag = 1",#PB_Text_Center)
CanV = CanvasGadget(#PB_Any,5,30,120,120)
ShowCoOrd = StringGadget(#PB_Any, 5,165,120,20,"",#PB_Text_Center|#PB_String_ReadOnly)
ShowDelta = StringGadget(#PB_Any, 5,185,120,20,"",#PB_Text_Center|#PB_String_ReadOnly)

GadMag = SpinGadget(#PB_Any,165,05,120,20,1,6,#PB_Spin_ReadOnly)
MagV   = CanvasGadget(#PB_Any,165,30,120,120) : SetGadgetState(GadMag,Mag) : SetGadgetText(GadMag,"Mag = "+Str(Mag)+"     ")
GadCol = CanvasGadget(#PB_Any,165,165,120,20,#PB_Canvas_Border)
ShowColour = StringGadget(#PB_Any,165,185,120,20,"",#PB_Text_Center|#PB_String_ReadOnly)
TestRange  = CanvasGadget(#PB_Any,5,210,280,35,#PB_Canvas_Border)

; Hints
GadgetToolTip(ShowCoOrd,"X,Y co-ordinates of mouse pointer.")
GadgetToolTip(ShowDelta,"Dx and Dy distances from point set by pressing 'F1'.")
GadgetToolTip(ShowColour,"RGB value at centre of X1 display. Copy to clipboard with 'F2'.")
GadgetToolTip(TestRange,"R,G,B,Greyscale and White bands. R,G,B dots against White and Black backgrounds. ")

; Hot keys...
AddKeyboardShortcut(1,#PB_Shortcut_F1,100)     ; Set cursor position as delta datum
AddKeyboardShortcut(1,#PB_Shortcut_Left,101)   ; Move cursor with cursor keys... 
AddKeyboardShortcut(1,#PB_Shortcut_Up,102)
AddKeyboardShortcut(1,#PB_Shortcut_Right,103)
AddKeyboardShortcut(1,#PB_Shortcut_Down,104)
AddKeyboardShortcut(1,#PB_Shortcut_F2,105)

; Test range...
StartDrawing(CanvasOutput(TestRange))
  Box(0,0,280,35,#Black)
  For X = 0 To 255
    For Y = 0 To 3
      Plot(9+X,4 +Y,RGB(X,0,0))
      Plot(9+X,8 +Y,RGB(0,X,0))
      Plot(9+X,12+Y,RGB(0,0,X))
      Plot(9+X,16+Y,RGB(X,X,X))
      Plot(9+X,20+Y,#White)
    Next
  Next
  Box(9,24,128,4,#White)
  For X = 0 To 128 Step 128
    Plot(X+12,26,#Red) : Plot(16+X,26,#Green) : Plot(X+20,26,#Blue)  
  Next
  
StopDrawing()


pt.POINT
C.l= 0
; Event management
Repeat
  
  Event = WaitWindowEvent(10)
  Select Event
    Case #PB_Event_Gadget
      
      Select EventGadget() 
        Case GadMag
          Mag = GetGadgetState(GadMag)
          SetGadgetText(GadMag,"Mag = "+Str(Mag)+"     ")
          
      EndSelect
      
    Case #PB_Event_Menu            ; Hot keys
      Select EventMenu()
        Case 100 : DatX = pt\X : DatY = pt\Y           ; F1 to set datum for Dx / Dy
        Case 101 : pt\X - 1 : SetCursorPos_(pt\X,pt\Y) ; Move mouse one pixel LEFT
        Case 102 : pt\Y - 1 : SetCursorPos_(pt\X,pt\Y) ; ... UP
        Case 103 : pt\X + 1 : SetCursorPos_(pt\X,pt\Y) ; ... RIGHT
        Case 104 : pt\Y + 1 : SetCursorPos_(pt\X,pt\Y) ; ... DOWN
          ; F2 to copy current colour to clipboard in 'RGB()' format
        Case 105 : SetClipboardText("RGB("+Str(Red(C))+","+Str(Green(C))+","+Str(Blue(C))+")") : Beep_(2500,100)
      EndSelect
      
  EndSelect
   
  ; Get the cursor's screen position and apply offset = half size of bit we grab.
  GetCursorPos_(@pt)
  X = pt\X - 60
  Y = pt\Y - 60
 
  If (X <> OldX) Or (Y <> OldY) Or (Mag <> OldMag) ; Moved or changed MAG...
    
    hdc = StartDrawing(CanvasOutput(CanV))
      
      ; Copy section of desktop to canvas
      ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd183370(v=vs.85).aspx
      ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd144871(v=vs.85).aspx
      BitBlt_(hdc, 0, 0, 120, 120, GetDC_(#Null), X, Y, #SRCCOPY)
      
      ; Draw 'cross hairs'
      LineXY(0,60,58,60,#Green) : LineXY(62,60,120,60,#Green)
      LineXY(60,0,60,58,#Green) : LineXY(60,62,60,120,#Green)
      
      ; Get the centre colou
      C.l = Point(60,60) 
      
      ; Get ImageID for the canvas
      T1 = GetGadgetAttribute(CanV,#PB_Canvas_Image)
      
    StopDrawing()  
    
    ; Create an image, copy the canvas gadget to it and get buffer info
    T2 = CreateImage(#PB_Any,120,120,32)
    StartDrawing(ImageOutput(T2))
      DrawImage(T1,0,0)
      *S       = DrawingBuffer()
      SPitch   = DrawingBufferPitch()
      SDepth   = ImageDepth(T2)/8
      
      SY       = 60-(60/Mag)
      SX       = 60-(60/Mag)
      *S + (SY * SPitch) + (SX * SDepth) ; Address of corner of source square
      
    StopDrawing()
    
    ; Create a destination image and get it's buffer info
    T3 = CreateImage(#PB_Any,120,120,32)
    StartDrawing(ImageOutput(T3))
      *D       = DrawingBuffer()
      DPitch   = DrawingBufferPitch()
      DDepth   = ImageDepth(T3)/8
    StopDrawing()
    
    ; Copy central square from source image to destination image.
    For Y2 = 1 To 120/Mag               ; For each source row to be copied...
      For n = 1 To Mag                  ; Copy each source row 'Mag' times
        *Z = *D
        *Y = *S                         ; Copy source pointer
        For X2 = 1 To 120/Mag           ; For each pixel in the row section,
          T = PeekL(*Y)                 ; get a source pixel,
          For m = 1 To Mag              ; output it 'Mag' times
            PokeL(*Z,T)
            *Z + DDepth
          Next
          *Y + SDepth
        Next
        *D + DPitch                     ; Start of next destination row
      Next
      *S + SPitch                       ; Start of next source row
    Next
    
  ; Write magnified image to Canvas
    StartDrawing(CanvasOutput(MagV))
      DrawImage(ImageID(T3),0,0)  
    StopDrawing()
    
    ; Free up temporary images
    FreeImage(T2)
    FreeImage(T3)
    
    ; Show the colour under the cursor
    StartDrawing(CanvasOutput(GadCol))
      Box(0,0,120,30,C)
    StopDrawing()
    
    ; Update data display
    SetGadgetText(ShowCoOrd,"X,Y : "  + Str(pt\X)+", "+Str(pt\Y))                        ; Cross hair co-ords
    SetGadgetText(ShowDelta,"Dx:" + Str(pt\X - DatX)+"   Dy:"+Str(pt\Y - DatY))          ; Delta X/Y 
    SetGadgetText(ShowColour,"RGB( " + Str(Red(C))+", "+Str(Green(C))+", "+Str(Blue(C))+" )") ; Centre point colour
   
  OldX = X
  OldY = Y
  OldMag = Mag
    
  EndIf
  
Until Event = #PB_Event_CloseWindow