Recent

Author Topic: Get Pixel Color Under Mouse Cursor(SOLVED)  (Read 18765 times)

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Get Pixel Color Under Mouse Cursor(SOLVED)
« on: December 22, 2013, 08:18:51 am »
Below is the complete source  to get pixel color from mouse coordinates On linux and Mac.

Best of all it works system wide,  its not limited to your application window in otherwords.

All Credits go to Tazz  because without his knowledge I don't feel I would have ever accomplished
such a task.


And who said linux can't do what windows can :)



Code: [Select]

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,LCLIntf,
  lcltype, ExtCtrls, StdCtrls, MouseAndKeyInput;

type

  { TForm1 }

  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Shape1: TShape;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

function ScreenColor(aX, aY: integer):TColor;
var
  ScreenDC: HDC;
  SaveBitmap: TBitmap;
begin
  SaveBitmap := TBitmap.Create;
  try
    SaveBitmap.SetSize(Screen.Width, Screen.Height);
    ScreenDC := GetDC(0);
    try
      SaveBitmap.LoadFromDevice(ScreenDC);
    finally
      ReleaseDC(0, ScreenDC);
    end;
    Result := SaveBitmap.Canvas.Pixels[aX, aY];

  finally
    SaveBitmap.Free;
  end;
end;

 function ColorToHex(Color: TColor): string;
begin
  if Color <> $0 then
    Result := IntToHex(GetRValue(Color), 2) + IntToHex(GetGValue(Color), 2) +
      IntToHex(GetBValue(Color), 2)
  else
    Result := '000000';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Application.ProcessMessages;
  Label1.caption := IntToStr(Mouse.CursorPos.X);
  Label2.caption := IntToStr(Mouse.CursorPos.Y);

  Shape1.Brush.Color := ScreenColor(Mouse.CursorPos.X,Mouse.CursorPos.Y);
  label3.caption := ColorToHex(shape1.Brush.Color);


end;



end.


« Last Edit: December 22, 2013, 09:09:14 pm by wjackson153 »
Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4


exdatis

  • Hero Member
  • *****
  • Posts: 668
    • exdatis

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Re: Get Pixel Color Under Mouse Cursor
« Reply #3 on: December 22, 2013, 05:20:42 pm »
So they only way to get a pixel under a mouse   is first to convert your desktop into a image  ???

Am I understanding this correctly?

Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Get Pixel Color Under Mouse Cursor
« Reply #4 on: December 22, 2013, 05:27:42 pm »
depends, is the pixel inside your application boundaries? If yes is it part of a TWinControl descendant? If yes do you use QT wideset? If no then try myColor := Myobject.Canvas.pixels[X,Y]; Where X & Y are relative to the controls client area ee 0,0 is at the top left of the control not the top left of the screen. In all other cases create a bitmap from the desktop and retrieve the pixel from there.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Re: Get Pixel Color Under Mouse Cursor
« Reply #5 on: December 22, 2013, 05:47:59 pm »
That is my problem the pixel is out side of my application.

Im currently using Arch Linux,  as stated in earlier post,  being how this is linux enviroment
there is no documentation on how to achieve what im needing to do.

And as stated also in earlier post  using grabc  , freezes my app untill the left mouse click
is sent to the process.

This works fine from a terminal window    grabc Xdotool click 1
problem is  when passed as a parameter through tprocess it appears that only grabc is accepted
and xdotool is ignored.

I just need a simple example to get the pixel, so where my app knows what pixel was chosen according to my mouse x,y coordinates,   I know how to do everything,  move mouse to said x,y coordinates, capturing x,y current position etc.   What im failing at is grabing the pixel at said coordinates
Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Get Pixel Color Under Mouse Cursor
« Reply #6 on: December 22, 2013, 06:02:31 pm »
well if you search the forums for screen shot you will find a number of threads that tackle the problem  for Example http://forum.lazarus.freepascal.org/index.php/topic,19478.msg111064.html#msg111064 which can be changed to
Code: [Select]
function ScreenColor(aX, aY: integer):TColor;
var
  ScreenDC: HDC;
  SaveBitmap: TBitmap;
begin
  SaveBitmap := TBitmap.Create;
  try
    SaveBitmap.SetSize(Screen.Width, Screen.Height);
    ScreenDC := GetDC(0);
    try
      SaveBitmap.LoadFromDevice(ScreenDC);
    finally
      ReleaseDC(0, ScreenDC);
    end;
    Result := SaveBitmap.Canvas.Pixels[aX, aY];
  finally
    SaveBitmap.Free;
  end;
end;
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Re: Get Pixel Color Under Mouse Cursor
« Reply #7 on: December 22, 2013, 06:20:23 pm »

Thanks for the example tazz   but im not sure that this works for linux   ?


Your example gives me multiple errors that I do not comprehend.

unit1.pas(222,22) Error: Identifier not found "GetDC"
unit1.pas(226,16) Error: Identifier not found "ReleaseDC"
unit1.pas(228,12) Error: Identifier not found "Result"
unit1.pas(228,42) Error: Identifier not found "aX"
unit1.pas(228,46) Error: Identifier not found "aY"
unit1.pas(234,4) Fatal: Syntax error, "." expected but ";" found
Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Get Pixel Color Under Mouse Cursor
« Reply #8 on: December 22, 2013, 06:23:24 pm »
add LCLIntf in to your uses clause and people have testify that the code works for windows, linux and if I remember correctly MacOS too. Personally I have tested it on windows only.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Re: Get Pixel Color Under Mouse Cursor
« Reply #9 on: December 22, 2013, 07:02:31 pm »
Ok  now its compiling but nothing is appearing to happen

cant find the image it saved anywhere on my comp,  nor a is it on the forms canvas

Also   in the following

Code: [Select]

begin
  Application.ProcessMessages;
   SaveBitmap := TBitmap.Create;
  try
    SaveBitmap.SetSize(200, 200);
    ScreenDC := GetDC(0);

    try
      SaveBitmap.LoadFromDevice(ScreenDC);
    finally
      ReleaseDC(0, ScreenDC);
    end;
    Result := SaveBitmap.Canvas.Pixels[mouse.CursorPos.X, mouse.cursorPos.y];
  finally
    SaveBitmap.Free;
    showMessage('Done');

  end;             



Result := SaveBitmap.Canvas.Pixels[mouse.CursorPos.X, mouse.cursorPos.y];

Im not entirely sure as to what Result should be defined as ?  LongInt,  Integer, Real  etc
Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Get Pixel Color Under Mouse Cursor
« Reply #10 on: December 22, 2013, 07:13:25 pm »
1) I gave you a complete function that you could use to read the color on a X,Y screen position including the result type you are asking.
2) the function is changed to return a color not to save a bitmap if you want a bitmap saved use the original procedure from the thread I linked in my last message.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Re: Get Pixel Color Under Mouse Cursor
« Reply #11 on: December 22, 2013, 07:38:46 pm »
here is my complete code





Code: [Select]

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,LCLIntf;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

function ScreenColor(aX, aY: integer):TColor;
var
  ScreenDC: HDC;
  SaveBitmap: TBitmap;
begin
  SaveBitmap := TBitmap.Create;
  try
    SaveBitmap.SetSize(Screen.Width, Screen.Height);
    ScreenDC := GetDC(0);
    try
      SaveBitmap.LoadFromDevice(ScreenDC);
    finally
      ReleaseDC(0, ScreenDC);
    end;
    Result := SaveBitmap.Canvas.Pixels[aX, aY];
  finally
    SaveBitmap.Free;
  end;
end;

end.




Im trying to use your example  but its the following errors.

unit1.pas(38,16) Error: Identifier not found "HDC"
unit1.pas(38,16) Error: Error in type definition
unit1.pas(46,41) Error: Incompatible type for arg no. 1: Got "<erroneous type>", expected "HDC"
rasterimage.inc(342,24) Hint: Found declaration: TRasterImage.LoadFromDevice(HDC);
unit1.pas(48,28) Error: Incompatible type for arg no. 2: Got "<erroneous type>", expected "HDC"
winapi.inc(798,10) Hint: Found declaration: ReleaseDC(HWND,HDC):LongInt;
unit1.pas(58) Fatal: There were 4 errors compiling module, stopping


Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Get Pixel Color Under Mouse Cursor
« Reply #12 on: December 22, 2013, 07:45:41 pm »
add lcltype to the uses clause.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wjackson153

  • Sr. Member
  • ****
  • Posts: 267
Re: Get Pixel Color Under Mouse Cursor
« Reply #13 on: December 22, 2013, 08:03:58 pm »
Ok , now were getting somewhere :)


But this does not appear to be working with ,  however I get no errors

Im trying to call the function as you posted,  but using real time x,y coordinates

Application.ProcessMessages;
  Label1.caption := IntToStr(Mouse.CursorPos.X);
  Label2.caption := IntToStr(Mouse.CursorPos.Y);

  Shape1.Color := ScreenColor(Mouse.CursorPos.X,Mouse.CursorPos.Y);   // no color changes  am i missing something ?
                       
Lazarus 1.1 r39490 CT FPC 2.7.1 i386-linux KDE
Linux Mint 14 KDE 4

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Get Pixel Color Under Mouse Cursor
« Reply #14 on: December 22, 2013, 08:09:45 pm »
Why don't you zip up a small test application that shows your problem so any one that wants to test it can do so? As it is now there is not enough info to even begin speculating what might be wrong. The code you have shown should work correctly.
« Last Edit: December 22, 2013, 08:24:14 pm by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018