Fast read pixel of the image file

This forum is for eXpress++ general support.
Message
Author
User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Fast read pixel of the image file

#1 Post by Eugene Lutsenko »

Roger wrote a function for reading a pixel of an image file: GetPixel(). It works very well, that is,It is doing all that is necessary and right. But, unfortunately, its speed is not very high. Reading all pixels large image file is pretty slow. Is there no possibility of greatly speed up this function, or find (design) different?

Code: Select all

GDIFUNCTION GetPixel( nHDC, x, y)
GDIFUNCTION SetPixel( nHDC, x, y, n )
DLLFUNCTION GetWindowDC( hwnd ) USING STDCALL FROM USER32.DLL

User avatar
rdonnay
Site Admin
Posts: 4734
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Fast read pixel of the image file

#2 Post by rdonnay »

Eugene -

Sorry, but I made it as fast as I could.
That's why I wrote GDIFUNCTION so it would keep the GDI32.DLL loaded.

There may be a faster way to do this without the GDI system, but I don't know for sure.

It will take some more Google searching to see if there is a better Windows API call.

Roger
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Fast read pixel of the image file

#3 Post by Eugene Lutsenko »

Roger!

What might be an apology? I am very and very grateful. In all of my development since 2012 is part of your work. On the basis of your development system created Eidos: http://lc.kubagro.ru/aidos/_Aidos-X.htm.

I do not want to be like the ungrateful who read my work I impose a claim that they do something wrong written. I told them in such cases, answers: "Take yourself and write as you like. Who's stopping you?"

User avatar
rdonnay
Site Admin
Posts: 4734
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Fast read pixel of the image file

#4 Post by rdonnay »

I did a search on GetPixel() and there were many complaints about how it is so slow.
However, there were no solutions given to solve the problem.

I sent a request to Alaska Software asking if they have a Gra() function that is faster.
There is nothing in their documentation but maybe they have a hidden function.
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Fast read pixel of the image file

#5 Post by Eugene Lutsenko »

Thank you, Roger! So I'm not one noticed. And of course such a function should be in a standard set of graphics functions of the programming language. I was very surprised that it is not. And, too, I had an idea that it is simply not described in the documentation.

It is here: http://www.cyberforum.ru/win-api/thread244142.html

Write a program (bot for online games), all his work is to obtain the color of the pixel in the desired position and performance of certain actions depending on the resulting color. It was XP, everything worked fine, but decided to try seven and faced with inexplicable thing - bot tupit unrealistic. For example at the beginning of the game he is looking for a window in the browser (in the sense of its coordinates) and then in the window is the desired button on its color:
C ++
void find_button (POINT & but, HDC dc) {
    HWND desktop = GetDesktopWindow ();
    RECT rect;
    GetWindowRect (desktop, & rect); // get the screen resolution
    const COLORREF buttonc = (10,142,681 & 0x00FCFCFC); // button color slightly sluggish, just in case
    but.x = rect.right-30;
    but.y = rect.bottom / 2-100;
    while ((GetPixel (dc, but.x, but.y) & 0x00FCFCFC) == 0x00FCFCFC)
        but.x -; // find the game window
    but.x- = 112;
    bool f = false;
    while (! f) {// find the button
        clf = ((GetPixel (dc, but.x, but.y)) & 0x00FCFCFC);
        for (int i = 1; i <= 10; i ++) {
            if (clf! = buttonc)
                break;
            else if (i == 10) // if 10 pixels of the same color in a row, it looks like a button
                f = true;
 
        }
        but.y ++;
    }
    SetCursorPos (but.x, but.y + 20);
    but.y + = 23;
}
bydlokod slightly since He wrote "just to work")), but not the point. In general, for all these XP actions occur instantaneously (for a human eye), and seven it takes 5-6 seconds. In my opinion unreal time. Tried in the Task Manager to change process priority - it has not helped. Further, all of the work robot is reduced to reading colors in certain areas and respond to the events (the color has changed - it means that something has happened)), but of course, with such a pace that does not works. Here I sit and think - why on Win7 so slow conventional API?

User avatar
rdonnay
Site Admin
Posts: 4734
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Fast read pixel of the image file

#6 Post by rdonnay »

Eugene -

Here is Alaska's reply to my request:
I understand that you're currently using the GetPixel() API directly in your code via DLLCall()? If so, which device context are you using with this API - a screen DC or a memory DC? Could you give us a quick run-down of your current approach?

Unfortunately, there's no internal interface that I can think of. Especially because your API call directly accesses the corresponding OS resource. I don't think anything we could provide could beat that when doing pixel-wise access, even if the OS subsystem being used is faster.
I am going to look into the possibility of using a Memory DC instead of a Screen DC. As of now, I don't know how to do that.
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Fast read pixel of the image file

#7 Post by Eugene Lutsenko »

In their response, I realized that they do not have such a function in the language. Although they do not directly told. This leaves the impression that maybe they still have such a function. But they say that if it was, then it would hardly worked faster than the OS functions. But then why XP is working properly, and W7 is very slow? It turns out the problem is the OS?

User avatar
Auge_Ohr
Posts: 1414
Joined: Wed Feb 24, 2010 3:44 pm

Re: Fast read pixel of the image file

#8 Post by Auge_Ohr »

Eugene Lutsenko wrote:And of course such a function should be in a standard set of graphics functions of the programming language.
Xbase++ is for Database and not for "Games" which need "Pixel".
for "Games" you can use special Grafic-Engine which can manipulate "Pixel" ... but you can´t use it with Xbase++
Eugene Lutsenko wrote:In their response, I realized that they do not have such a function in the language. Although they do not directly told. This leaves the impression that maybe they still have such a function. But they say that if it was, then it would hardly worked faster than the OS functions.
AFAIK ... there is no such Function in GDI32.DLL
Eugene Lutsenko wrote: But then why XP is working properly, and W7 is very slow? It turns out the problem is the OS?
since Vista we have DWM ( Desktop Windows Manager ) which is "painting" your Windows

---

if you want "more" you have to learn about BITMAP Structure.
a Bitmap have bmWidth and bmHeight Member and look like this

Code: Select all

    Scan 0 
    Scan 1 
    . 
    . 
    . 
    Scan n-2 
    Scan n-1 
to read a hole "Scan" line is much faster.
you know how much to read ( bmWidth * (Scan n-1) ) but where to "Start" ( Offset ) ?

DIBSECTION structure does contain BITMAPINFOHEADER / BITMAPINFO Structure and Member "dsOffset" ... this was the easy Part ...

i know about API Function in Gdi32.dll like SetDIBits / GetDIBits but i never have used it yet.

---

BITMAP Structure
https://msdn.microsoft.com/en-us/librar ... 85%29.aspx

BITMAPINFOHEADER Structure
https://msdn.microsoft.com/de-de/librar ... 85%29.aspx

BITMAPINFO Structure
https://msdn.microsoft.com/de-de/librar ... 85%29.aspx

DIBSECTION structure
https://msdn.microsoft.com/en-us/librar ... 85%29.aspx

CreateDIBSection function
https://msdn.microsoft.com/de-de/librar ... 85%29.aspx
greetings by OHR
Jimmy

User avatar
rdonnay
Site Admin
Posts: 4734
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Fast read pixel of the image file

#9 Post by rdonnay »

I am experimenting with some code I found that uses Memory DC instead of Screen DC.

There is a lot more involved here but I will give it a try.
The eXpress train is coming - and it has more cars.

User avatar
rdonnay
Site Admin
Posts: 4734
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Fast read pixel of the image file

#10 Post by rdonnay »

Eugene -

Here is an updated program that reads the pixels 46 times faster than before.

I am using 4 different Windows API functions to accomplish this:

CreateCompatibleDC()
CreateCompatibleBitmap()
SelectObject()
BitBlt()

When I click on "Load Array" it takes over 5 seconds to load the 256 x 256 array.
When I click on "Load Array 2" it takes .12 seconds to load the 256 x 256 array.

A 46 times improvement on GetPixel() should help you a lot.

Now I am trying to figure out how to improve SetPixel() performance.

Here is some of the new code:

Code: Select all

FUNCTION LoadArray2( hDC1, aPixel )

LOCAL hMemoryDC
LOCAL i, j, oScrn, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
LOCAL nSeconds := Seconds()

hMemoryDC := CreateMemoryDC( hDC1, nXSize, nYSize)

FOR i := 1 TO nXSize
  FOR j := 1 TO nYSize
    aPixel[i,j] := GetPixel(hMemoryDC,i-1,j-1)
  NEXT
NEXT

MsgBox(Alltrim(Str(Seconds()-nSeconds)) + ' Seconds to load Array')

DC_ClearEvents()

RETURN aPixel

* ------------

FUNCTION CreateMemoryDC( hDC, nXSize, nYSize )

LOCAL hMemoryDC, hBMP

hMemoryDC := CreateCompatibleDC(hDC)    // create compatible memory DC
hBMP      := CreateCompatibleBitmap(hDC,nXSize,nYSize) // create DDB
SelectObject(hMemoryDC,hBMP)                    // put hBMP into memory DC
BitBlt( hMemoryDC,0,0,nXSize,nYSize,hDC,0,0,SRCCOPY ) // copy desktop DC into memory DC

RETURN hMemoryDC

* --------------

DLLFUNCTION CreateCompatibleDC( nHDC ) USING STDCALL FROM GDI32.DLL
DLLFUNCTION CreateCompatibleBitmap( nHDC, dw, dh ) USING STDCALL FROM GDI32.DLL
DLLFUNCTION SelectObject(hMemoryDC,hBMP) USING STDCALL FROM GDI32.DLL
DLLFUNCTION BitBlt( hDC,nXDest,nYDest,nXSize,nYSize,hDCSrc,nXSrc,nYSrc,dwROP ) ;
   USING STDCALL FROM GDI32.DLL
Attachments
pixel.zip
(1.92 KiB) Downloaded 750 times
The eXpress train is coming - and it has more cars.

Post Reply