Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8719581
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T06:50:01+00:00 2026-06-13T06:50:01+00:00

I’m in the process of building an automated game bot in Python on OS

  • 0

I’m in the process of building an automated game bot in Python on OS X 10.8.2 and in the process of researching Python GUI automation I discovered autopy. The mouse manipulation API is great, but it seems that the screen capture methods rely on deprecated OpenGL methods…

Are there any efficient ways of getting the color value of a pixel in OS X? The only way I can think of now is to use os.system("screencapture foo.png") but the process seems to have unneeded overhead as I’ll be polling very quickly.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T06:50:02+00:00Added an answer on June 13, 2026 at 6:50 am

    A small improvement, but using the TIFF compression option for screencapture is a bit quicker:

    $ time screencapture -t png /tmp/test.png
    real        0m0.235s
    user        0m0.191s
    sys         0m0.016s
    $ time screencapture -t tiff /tmp/test.tiff
    real        0m0.079s
    user        0m0.028s
    sys         0m0.026s
    

    This does have a lot of overhead, as you say (the subprocess creation, writing/reading from disc, compressing/decompressing).

    Instead, you could use PyObjC to capture the screen using CGWindowListCreateImage. I found it took about 70ms (~14fps) to capture a 1680×1050 pixel screen, and have the values accessible in memory

    A few random notes:

    • Importing the Quartz.CoreGraphics module is the slowest part, about 1 second. Same is true for importing most of the PyObjC modules. Unlikely to matter in this case, but for short-lived processes you might be better writing the tool in ObjC
    • Specifying a smaller region is a bit quicker, but not hugely (~40ms for a 100x100px block, ~70ms for 1680×1050). Most of the time seems to be spent in just the CGDataProviderCopyData call – I wonder if there’s a way to access the data directly, since we dont need to modify it?
    • The ScreenPixel.pixel function is pretty quick, but accessing large numbers of pixels is still slow (since 0.01ms * 1650*1050 is about 17 seconds) – if you need to access lots of pixels, probably quicker to struct.unpack_from them all in one go.

    Here’s the code:

    import time
    import struct
    
    import Quartz.CoreGraphics as CG
    
    
    class ScreenPixel(object):
        """Captures the screen using CoreGraphics, and provides access to
        the pixel values.
        """
    
        def capture(self, region = None):
            """region should be a CGRect, something like:
    
            >>> import Quartz.CoreGraphics as CG
            >>> region = CG.CGRectMake(0, 0, 100, 100)
            >>> sp = ScreenPixel()
            >>> sp.capture(region=region)
    
            The default region is CG.CGRectInfinite (captures the full screen)
            """
    
            if region is None:
                region = CG.CGRectInfinite
            else:
                # TODO: Odd widths cause the image to warp. This is likely
                # caused by offset calculation in ScreenPixel.pixel, and
                # could could modified to allow odd-widths
                if region.size.width % 2 > 0:
                    emsg = "Capture region width should be even (was %s)" % (
                        region.size.width)
                    raise ValueError(emsg)
    
            # Create screenshot as CGImage
            image = CG.CGWindowListCreateImage(
                region,
                CG.kCGWindowListOptionOnScreenOnly,
                CG.kCGNullWindowID,
                CG.kCGWindowImageDefault)
    
            # Intermediate step, get pixel data as CGDataProvider
            prov = CG.CGImageGetDataProvider(image)
    
            # Copy data out of CGDataProvider, becomes string of bytes
            self._data = CG.CGDataProviderCopyData(prov)
    
            # Get width/height of image
            self.width = CG.CGImageGetWidth(image)
            self.height = CG.CGImageGetHeight(image)
    
        def pixel(self, x, y):
            """Get pixel value at given (x,y) screen coordinates
    
            Must call capture first.
            """
    
            # Pixel data is unsigned char (8bit unsigned integer),
            # and there are for (blue,green,red,alpha)
            data_format = "BBBB"
    
            # Calculate offset, based on
            # http://www.markj.net/iphone-uiimage-pixel-color/
            offset = 4 * ((self.width*int(round(y))) + int(round(x)))
    
            # Unpack data from string into Python'y integers
            b, g, r, a = struct.unpack_from(data_format, self._data, offset=offset)
    
            # Return BGRA as RGBA
            return (r, g, b, a)
    
    
    if __name__ == '__main__':
        # Timer helper-function
        import contextlib
    
        @contextlib.contextmanager
        def timer(msg):
            start = time.time()
            yield
            end = time.time()
            print "%s: %.02fms" % (msg, (end-start)*1000)
    
    
        # Example usage
        sp = ScreenPixel()
    
        with timer("Capture"):
            # Take screenshot (takes about 70ms for me)
            sp.capture()
    
        with timer("Query"):
            # Get pixel value (takes about 0.01ms)
            print sp.width, sp.height
            print sp.pixel(0, 0)
    
    
        # To verify screen-cap code is correct, save all pixels to PNG,
        # using http://the.taoofmac.com/space/projects/PNGCanvas
    
        from pngcanvas import PNGCanvas
        c = PNGCanvas(sp.width, sp.height)
        for x in range(sp.width):
            for y in range(sp.height):
                c.point(x, y, color = sp.pixel(x, y))
    
        with open("test.png", "wb") as f:
            f.write(c.dump())
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
We're building an app, our first using Rails 3, and we're having to build
I have thousands of HTML files to process using Groovy/Java and I need to
I'm making a simple page using Google Maps API 3. My first. One marker
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.