Author Topic: Get Pixel Color  (Read 701 times)

Exergist

  • Moderator
  • Full Member
  • *****
  • Posts: 171
  • Can you dig it?
Get Pixel Color
« on: August 16, 2017, 11:08:13 am »
I've seen a few questions/requests on the forum about getting pixel information with VoiceAttack. Gary has explained that this is not possible with VA's native functionality. However with the magic of C# and VA's support for inline functions we can come up with a command that captures the RGB (and HEX) color values for the pixel under the mouse cursor.

VA Command Code:
Code: [Select]
// Obtain mouse cursor's X coordinate
Set integer [mouseX] value to the converted value of {MOUSESCREENX}
// Obtain mouse cursor's Y coordinate
Set integer [mouseY] value to the converted value of {MOUSESCREENY}
// Output cursor coordinates
Write '[Black] Cursor Coordinates = ({INT:mouseX} , {INT:mouseY})' to log
// C# function to obtain RGB values from screen pixel at cursor's X and Y coordinates
Inline C# Function: Get Pixel Color, wait until execution finishes
// Output individual RGB values
Write '[Red] Red Value = {INT:RedValue}' to log
Write '[Green] Green Value = {INT:GreenValue}' to log
Write '[Blue] Blue Value = {INT:BlueValue}' to log
Write '[Gray] Hex Value = {TXT:HexValue}' to log

Inline Function Code:
Reference Assemblies: Microsoft.CSharp.dll;System.dll;System.Core.dll;System.Data.dll;System.Data.DataSetExtensions.dll;System.Deployment.dll;System.Drawing.dll;System.Net.Http.dll; System.Windows.Forms.dll;System.Xml.dll;System.Xml.Linq.dll
Code: [Select]
// Primary Source = https://stackoverflow.com/questions/753132/how-do-i-get-the-colour-of-a-pixel-at-x-y-using-c
// HEX Conversion Source = https://stackoverflow.com/questions/13354892/converting-from-rgb-ints-to-hex

using System;
using System.Drawing;
using System.Runtime.InteropServices;

public class VAInline
{
    public void main()
    {       
        // Retrieve (X,Y) coordinates from VA variables
        int Xpos = (int)VA.GetInt("mouseX");
        int Ypos = (int)VA.GetInt("mouseY");

        // Get pixel color data from (X,Y) coordinates
        Color myColor = GetPixelColor(Xpos, Ypos);

        // Store RGB color values
        int r = myColor.R;
        int g = myColor.G;
        int b = myColor.B;

        // Store HEX color value
        string hex = myColor.R.ToString("X2") + myColor.G.ToString("X2") + myColor.B.ToString("X2");
       
        // Send RGB data back to VA variables
        VA.SetInt("RedValue", r);
        VA.SetInt("GreenValue", g);
        VA.SetInt("BlueValue", b);
        VA.SetText("HexValue", hex);
    }

    [DllImport("user32.dll")]
    static extern IntPtr GetDC(IntPtr hwnd);

    [DllImport("user32.dll")]
    static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

    [DllImport("gdi32.dll")]
    static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

    static public System.Drawing.Color GetPixelColor(int x, int y)
    {
        IntPtr hdc = GetDC(IntPtr.Zero);
        uint pixel = GetPixel(hdc, x, y);
        ReleaseDC(IntPtr.Zero, hdc);
        Color color = Color.FromArgb((int)(pixel & 0x000000FF),
             (int)(pixel & 0x0000FF00) >> 8,
             (int)(pixel & 0x00FF0000) >> 16);
        return color;
    }
}

To validate the command, let's turn to this RGB example at ColorPicker.com. Moving the cursor inside the small blue box (like as the red arrow indicates below) representing the color RGB = (85, 176, 240) and activating the command does indeed show that VA can now (indirectly) detect and capture the pixel color. Note that the screen coordinates in the below example show positive and negative values since this was captured on a multi-monitor setup.



I've included all of the above command and function code in the attached profile. For this example I've chosen to simply output the RGB (and HEX!) data, but I'm sure there are all kinds of interesting things folks can do with this data in VA. For instance this doesn't have to be applied to a single pixel - you could use a loop to check an array of pixels surrounding an onscreen point (or cursor position). Feel free to designate the screen (X,Y) coordinates however you see fit. Enjoy! :)

Edit: added code and output for HEX color value corresponding to the RGB
« Last Edit: September 28, 2017, 06:58:46 am by Exergist »