dropperFor those Corona developers seeking a way to get the color of a specific pixel on the screen, you’re in luck! Starting with Daily Build #2106, our engineers have implemented the display.colorSample() function for this purpose. This function is an advanced graphics feature which can only be used by Pro/Enterprise subscribers.

Syntax

Using this function is simple: just provide a pixel location (in content space) and include a reference to a listener function which will receive the color values. Here’s the basic syntax:

display.colorSample( x, y, onColorSample )

Then, in the listener function, gather the values from the function’s event table. For example:

function onColorSample( event )
   print( "Sampling pixel at position (" .. event.x .. "," .. event.y .. ")" )
   print( "R = " .. event.r )
   print( "G = " .. event.g )
   print( "B = " .. event.b )
   print( "A = " .. event.a )
end

As you can see, the event table sent to the listener function contains an r, g, b, and a value for your usage, along with the sampled pixel’s x and y coordinates.

Sample Project

Let’s illustrate how the function works in a quick sample project:
major-magnet

local img = display.newImageRect( "major-magnet.png", 200, 200 )
img.x = display.contentCenterX
img.y = display.contentCenterY

local function onColorSample( event )
   print( "Sampling pixel at position (" .. event.x .. "," .. event.y .. ")" )
   print( "R = " .. event.r )
   print( "G = " .. event.g )
   print( "B = " .. event.b )
   print( "A = " .. event.a )
end

display.colorSample( display.contentCenterX, display.contentCenterY, onColorSample )
display.colorSample( display.contentCenterX-25, display.contentCenterY, onColorSample )
display.colorSample( display.contentCenterX, display.contentCenterY+25, onColorSample )
display.colorSample( display.contentCenterX+25, display.contentCenterY, onColorSample )

Performance Limitations

At this time, the display.colorSample() function shares similar performance limitations as display.capture(), and like that function, it shouldn’t be used in tight loops, Runtime “enterFrame” listeners, or the “moved” phase of a touch handler. However, it gives you easy access to a pixel’s color values in just a few lines of code.

Please give it a spin and provide your feedback and comments below!

  1. display.capture() is so damn buggy and fickle, cant think of when this function would be used (although im sure someone will find a use) it would have been better seeing you fix some of the bugs with display.capture instead!

    • Please try display.capture() with the most recent daily build and report any problem you might still be experiencing. It’s been greatly improved recently and we would really like to know if there are any outstanding issues. Thanks!

  2. Would it work on an image or the rendered screen (display/stage)?
    Would it scale or do we need to get a calculated pixel? What happens in retina mode and non-retina?

    What about setPixel? place a new rect of 1×1 to set a pixel?

    tx,

    • It only work by sampling the screen directly. There’s no option to provide an image to read from.

      The parameters are expected to be in content coordinates, so you don’t have to worry about scaling.

      setPixel: Yeah, a 1×1 rect would be the simplest way to go about it.

  3. As it stands I really have an hard time coming up with something useful for it (: Surely it’s great that it’s there, rather than not, but for example if I wanted to use a mask system to check for black or white pixel to activate collisions (think about Worms, for example), I can’t, because the mask would have to be visible on screen for it to work (plus it wouldn’t read it fast enough for it to work). Also, if I wanted to use it to gather information about certain pixels and then colorize them, I can’t because there’s not a similar function to change the color of them (plus again, it wouldn’t be performant).
    I can’t imagine it being any useful as is, but I’m sure that for some it might come in handy.
    I really appreciate the effort though, and how CoronaLabs is actively trying to address even the little features asked in these years (:

  4. That is good direction for sure.
    But can you tell us what exact technical problems are standing on the way to be able get color of certain pixel of any texture in texture memory? Without time delay.
    Thanks.

      • I already said somewhere, but I’ll repeat. It would be awesome to have means of manipulating an image (bitmap) BEFORE it goes into GPU. So a plugin, where images are stored in binary form (C arrays, faster than lua tables) and we can read and change their data. Then use such inmemory image with display.newImage, graphics.newImageSheet and etc. One way of implementing this is to define filename schema. For example
        display.newImage(‘ram/inmemory.png’), where ‘ram’ (or ‘ram://’) is a special string, representing that it should load image from memory. And each inmemory image would have a name ‘inmemory.png’ or ‘whatever.jpg’ which are assigned to them by means of such plugin.
        Well, it would be not entirely a plugin, because loading from memory is going to be implemented in the core, but all image manipulation code is good to have outside the core.
        Think about OpenCV, PythonImageLibrary, GD library, Adobe Generic Image Library, FreeImage and others.
        That would be super useful.

        P.S. And I want global dynamic lighting! Bumpmapping filter is too limited.

  5. Can it be used to read the image of camera? I’m trying to read a simple barcode: I need a fast way to recognize between at least 9 different shapes. Could use the color of a subset of total pixel of the camera preview?

  6. Awwww man this is taking me back!! I used to use this feature on my AtariST in GFA BASIC!!! I loved it!!! Glad Corona got it!! I used it to make tile maps from images!!!!! Very cool! Might blend it for use with MTE!!! w00t!!

  7. The sample here is not working. You have to wait few millisecond before sampling the screen otherwise the picture is not displayed. I added a performwithdelay with 100 as the delay and its fine.

  8. Is there a way to clear what has been sampled out of simulator memory? Not sure how the API works, but basically i’m sampling each pixel in an image and then storing the rob results into an array. However, no matter where I put timer delays or however long i set a delay before continuing to read more pixels, the moment the simulator reaches about 64,000+ pixel reads it crashes my mac. Any ideas?

  9. Hi, is it possible that this function is broke on the iphone 3 simulator on mac??
    it works fine on all simulators, only when i start the iphone 3 simulator the function
    display.colorSample( event.x, event.y, onColorSample )
    only give me ‘black’ r,g,b = 0 back….
    is this a back in the simulator and does it work on a real iphone 3 device?

    thanks
    chris

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>