There is a task to read the pixel color from the BMP file, which is placed in image1 . It is necessary to use for reading the TMemoryStream file, since there is no possibility to use image1.Canvas.Pixels[x,y] - the β€œpipette” is disabled when the DirectX application is running, but it is also started from BMP and taken as a screenshot.

Addition!!!

It turned out that - taking the color Bitmap.Pixels began to work once every other time. What could be the problem? In general: I compile the application, run it from the ΠΈΠΌΠ΅Π½Π° Π°Π΄ΠΌΠΈΠ½Π° - PostMessage does not work, the color returns zeros. I close the application. I start it on a new one - and that works. And so all the time. Previously, the same behavior was noticed in the TICQ module - I didn’t want to log in once every time I started it. What could it be? As you can see, I do not edit the code between runs , and I do not even compile . Just restart and either everything works or everything does not work. I have a Delphi XE3 and Win10 .

So. The code sections do not always work ( I run on ΠΈΠΌΠ΅Π½ΠΈ Π°Π΄ΠΌΠΈΠ½Π° ), but sometimes they work when the application is repeatedly restarted :

 procedure TForm1.F10Timer(Sender: TObject); var wnd: HWND; begin wnd:=FindWindow(0, 'Lineage II'); //Π½Π°Ρ…ΠΎΠ΄ΠΈΠΌ ΠΎΠΊΠ½ΠΎ if (wnd<>0) then //Ссли Π½Π°ΠΉΠ΄Π΅Π½ΠΎ Ρ‚ΠΎ выполняСм ΠΊΠΎΠ΄ (Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ всСгда) begin PostMessage(wnd,WM_KEYDOWN, VK_f10,0); //Π½Π°ΠΆΠΈΠΌΠ°Π΅ΠΌ F10 label14.Caption:='F10'; //для сСбя пишСм Π½Π° Ρ„ΠΎΡ€ΠΌΠ΅ Ρ‡Ρ‚ΠΎ клавиша Π½Π°ΠΆΠ°Ρ‚Π° end; end; 

There are many such procedures, they are identical, and all together or work or not. They actually send keystrokes to the game window (yes, I am writing a bot).

Next is the definition of color. It only works if sending keystrokes works (I mean this bug, which I described above):

 procedure TForm2.Button5Click(Sender: TObject); var GetSc:Dx.TImageCatcher; begin GetSc:=Dx.TImageCatcher.Create; //создаю экзСмпляр класса (Dx.pas) GetSc.TargetHandle:=FindWindow(0, 'Lineage II'); //ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹ GetSc.CatchType:=ctDirectX; //установил способ съСмки GetSc.ActivateTarget; //Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΡƒΡŽ ΠΎΠΊΠ½ΠΎ ΠΈΠ³Ρ€Ρ‹ GetSc.GetScreenShot; //это Π±ΠΈΡ‚ΠΌΠ°ΠΏ, сюда Π³Ρ€ΡƒΠ·ΠΈΠΌ снимок image1.Picture.Bitmap:=GetSc.Bitmap; //ΠΈΠ· Π±ΠΈΡ‚ΠΌΠ°ΠΏΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ снимок Π² image1 image1.canvas.CopyRect(image1.ClientRect,image1.Canvas,rect(27,58,181,95)); //ΠΎΡΡ‚Π°Π²Π»ΡΡŽ Π² image1 Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‰ΡƒΡŽ мСня ΠΎΠ±Π»Π°ΡΡ‚ΡŒ (шкала CP, HP, MP) image1.Picture.bitmap.width:=155; //ровняСм Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ image1.Picture.bitmap.Height:=38; //ровняСм Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ image1.Picture.Bitmap.Dormant; //ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΠΌ image1 ΠΏΠΎ совСту ΠΈΠ· ΠΊΠ°ΠΌΠΌΠ΅Π½Ρ‚ΠΎΠ² labelededit1.Text:=inttohex(image1.Picture.Bitmap.Canvas.Pixels[135,19],6); //ΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ Ρ†Π²Π΅Ρ‚ end; 

In fact, here is the whole example, everything else is similar. There is an opinion that either the compiler is sinning or WinAPI, I can not understand. This all sometimes works great, if you start working, and the result here is it:

Window link: https://drive.google.com/open?id=0B3g0HJYW_bzHcnNHWEtTMDVxdXc

Lineage II in the list of windows. Window "Lineage II" class "L2UnrealWWindowsViewportWindow". We see no children.

Link: https://drive.google.com/file/d/0B3g0HJYW_bzHNU1LX3lqWDlfZ2M/view?usp=sharing

  • Addition: when DirectX running, taking a pixel color from a point on the screen or from image1 using the above method returns the color code 000000 to hex . - Arthur Alekseenko
  • Does the very image appear in the image? You did not show the code that captures the image in the image. Try to make image1.Picture.Bitmap.Dormant - this converts the bitmap to DIB, and then get access through image1.Picture.Bitmap.Canvas.Pixels . Working with binary bitmap content is a thankless task. The location of the bytes of a particular pixel depends on the bitmap bit depth and other factors. - kami
  • So with the help of a method from another unit I load it into an image : image1.Picture.Graphic:=GetSc.Bitmap; The image is displayed normally. GetSc.Bitmap is a method from a unit with which I use DirectX pull an image out Z-Π±ΡƒΡ„Π΅Ρ€Π° game's Z-Π±ΡƒΡ„Π΅Ρ€Π° . Now I will try your advice and accomplish your goal! Thank! - Arthur Alekseenko
  • When the game is not running - works with a bang. When it is launched, the screen does, I execute Dormant , but instead of color in the end, 000000 . I already broke my whole head, I can’t even imagine what to do with it and why. - Arthur Alekseenko
  • Here is the screenshot of drive.google.com/file/d/0B3g0HJYW_bzHcnNHWEtTMDVxdXc ... ... Where the HP bar is HP I'm trying to get the color of the dot. These two images fly into image1 and image2 from DirectX . As seen in LabeledEdit "Color HP" - instead of color zeros. I close the game and try to screen any other window - the color is correct. - Arthur Alekseenko

1 answer 1

Try this:

 GetSc := Dx.TImageCatcher.Create; //создаю экзСмпляр класса (Dx.pas) try GetSc.TargetHandle := FindWindow(0, 'Lineage II'); //ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹ GetSc.CatchType := ctDirectX; //установил способ съСмки GetSc.ActivateTarget; //Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΡƒΡŽ ΠΎΠΊΠ½ΠΎ ΠΈΠ³Ρ€Ρ‹ GetSc.GetScreenShot; //это Π±ΠΈΡ‚ΠΌΠ°ΠΏ, сюда Π³Ρ€ΡƒΠ·ΠΈΠΌ снимок image1.Picture.Bitmap := GetSc.Bitmap; //ΠΈΠ· Π±ΠΈΡ‚ΠΌΠ°ΠΏΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ снимок Π² image1 finally GetSc.Free; end; image1.ScanLine(0); // дальшС ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π½Π° массив пиксСлСй, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌ ΠΎΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ScanLine ΠΈΠ»ΠΈ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅ image1.canvas.CopyRect(image1.ClientRect,image1.Canvas, rect(27,58,181,95)); //ΠΎΡΡ‚Π°Π²Π»ΡΡŽ Π² image1 Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‰ΡƒΡŽ мСня ΠΎΠ±Π»Π°ΡΡ‚ΡŒ (шкала CP, HP, MP) image1.Picture.bitmap.width:=155; //ровняСм Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ image1.Picture.bitmap.Height:=38; //ровняСм Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ labelededit1.Text:=inttohex(image1.Picture.Bitmap.Canvas.Pixels[135,19], 6); //ΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ Ρ†Π²Π΅Ρ‚ 
  • Thanks for your help! I added your edits, but unfortunately it had no effect on the situation. Today from the time of the 20th I made it all work = (PS: I mean, I restarted the application 20 times until it worked - Arthur Alekseenko
  • Now I put 10 Seattle, there is an opinion that my version of XE3 is sinning - Arthur Alekseenko
  • Alas and oh! Installed a new Delphi, deleted the compiled file, re-compiled it at 10 Seattle and ... nothing. Again ignore - Arthur Alekseenko
  • And if you do GetSc.Bitmap.SaveToFile('ScreenShot.bmp'); after GetSc.GetScreenShot; Will the file always look adequate? - kot-da-vinci
  • I would say, there is nowhere more adequate. Saves very well. Therefore, I came to the point that you need to try to take the color in hex from the file. - Arthur Alekseenko