Question

the R and B gets error when using this logic, i cant seem to find what im doing wrong, my workaround in the end were i flip the r and b is not good at all and im trying to find where the logic breakes.

the label1.Text = colorX; shows R=255, G=0, B=0 when it shold be R=0, G=0, B=255, where does this fail?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;


namespace Color_tool
{
public partial class Form1 : Form
{
    Regex rgbInputR;
    Regex rgbInputG;
    Regex rgbInputB;

    int r;
    int g;
    int b;


    string colorX;

    [DllImport("gdi32")]
    private static extern int GetPixel(IntPtr hdc, int x, int y);
    [DllImport("User32")]
    private static extern IntPtr GetWindowDC(IntPtr hwnd);

    private static readonly IntPtr DesktopDC = GetWindowDC(IntPtr.Zero);

    public static System.Drawing.Color GetPixelAtCursor()
    {
        System.Drawing.Point p = Cursor.Position;
        return System.Drawing.Color.FromArgb(GetPixel(DesktopDC, p.X, p.Y));
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        button1.BackColor = Color.Black;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        colorX = GetPixelAtCursor().ToString();
        Color backX = GetPixelAtCursor();
        this.BackColor = Color.FromArgb(r,g,b);
        label1.Text = colorX;
        RGB_value();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (timer1.Enabled == false)
            timer1.Enabled = true;
        else
            timer1.Enabled = false;
    }

    private void RGB_value()
    {
        rgbInputR = new Regex(@"(?<=R=)\d{0,3}");
        rgbInputG = new Regex(@"(?<=G=)\d{0,3}");
        rgbInputB = new Regex(@"(?<=B=)\d{0,3}");

        Match R, G, B;

        R = rgbInputR.Match(colorX);
        G = rgbInputG.Match(colorX);
        B = rgbInputB.Match(colorX);
        //had to flip the R and B ???
        b = int.Parse(R.Groups[0].Value);
        g = int.Parse(G.Groups[0].Value);
        r = int.Parse(B.Groups[0].Value);
    }
 }
}
Was it helpful?

Solution

I think you're going about this in an odd way for one; Color has R, G, and B properties you can use instead of string matching:

R = colorX.R;
G = colorX.G;
B = colorX.B;

Second, to address your question, GetPixel is probably getting BGR formatted pixels instead of RGB. BGR is commonly used in bitmaps and the HDC of the window you're talking to is most likely returning in this format.

Edit: from the MSDN docs:

When specifying an explicit RGB color, the COLORREF value has the following hexadecimal form. 0x00bbggrr

The Color.FromArgb() method expects 0xAARRGGBB. Your workaround is just fine, although a proper fix would be to flip the R and B components before you call the .FromArgb() method:

int color = GetPixel(...);
return Color.FromArgb(color & 0xFF, color >> 8 & 0xFF, color >> 16);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top