Results 1 to 3 of 3

Thread: CL_PixelBuffer::get_pixel()

  1. #1
    Lesser Knight
    Join Date
    Sep 2010
    Location
    Germany
    Posts
    36

    Question CL_PixelBuffer::get_pixel()

    Hello everyone,

    I just made a test application for reading pixels out of a CL_PixelBuffer.
    But it doesn't return what i expect...
    Tried everything out now and read all topics and the documentation about the PixBuf.
    What am I doing wrong?

    Code:
    int CProgram::start( const std::vector<CL_String> &args )
    {
    	CL_PixelBuffer buffer( "image.png" );
    	CL_PixelBuffer rgba = buffer.to_format(cl_rgba8);
    
    	for( int x = 0; x < rgba.get_width(); x++ )
    	{
    		for( int y = 0; y < rgba.get_height(); y++ )
    		{
    			rgba.lock( cl_access_read_only );
    			CL_Colorf color = rgba.get_pixel( x, y );
    			rgba.unlock();
    		
    
    			if( color == CL_Colorf( .0f, .0f, .0f ) )
    				MessageBox( NULL, L"Schwarzen Pixel gefunden!", L"Pixel gefunden!", MB_OK );
    		}
    	}
    
    	return( 0 );
    }
    The program should be able to tell the user when it has found a black pixel.

    Thanks

  2. #2
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Don't use the get_pixel() function. I'm not sure who added it but afair it only works with a few selected pixel formats. It is also horribly slow. Your code should look something like this:

    Code:
    int CProgram::start( const std::vector<CL_String> &args )
    {
    	CL_PixelBuffer buffer( "image.png" );
    	CL_PixelBuffer rgba = buffer.to_format(cl_rgba8);
    	rgba.lock( cl_access_read_only );
    	unsigned int *data = reinterpret_cast<unsigned int*>(rgba.get_data());
    	unsigned int width = rgba.get_width();
    	unsigned int height = rgba.get_height();
    
    	for( unsigned int y = 0; y < height; y++ )
    	{
    		unsigned int *line = data+y*width;
    		for( unsigned int x = 0; x < width; x++ )
    		{
    			unsigned int pixel = line[x];
    			unsigned int red = (pixel >> 24) & 0xff;
    			unsigned int green = (pixel >> 16) & 0xff;
    			unsigned int blue = (pixel >> 8) & 0xff;
    
    			if (red == 0 && green == 0 && blue == 0)
    				MessageBox( NULL, L"Schwarzen Pixel gefunden!", L"Pixel gefunden!", MB_OK );
    		}
    	}
    
    	rgba.unlock();
    
    	return 0;
    }
    The code differs from yours in the following ways:

    • It only locks the buffer once. Since there may be millions of pixels in your image its a bad idea to lock it every pixel.
    • An image is stored row by row in memory and accessing it column first is very inefficient. I therefore swapped the for loops so Y is the outer loop.
    • Since each pixel is stored as numbers 0-255 for each color component, it is a lot faster to do the compare in integers instead of floating point.
    • I avoid doing function calls in the inner loop. Theoretically a good compiler can figure out this optimization itself, but at least for debug builds the compiler deliberately doesn't and maybe your compiler isn't as good as one could hope.


    I hope this helps.

  3. #3
    Lesser Knight
    Join Date
    Sep 2010
    Location
    Germany
    Posts
    36

    Default

    Now it works just fine
    Thanks for the fast and good help.
    And the program is pretty fast now!

Similar Threads

  1. CL_PixelBuffer Problem.
    By Tuisto in forum Official ClanLib SDK Forums
    Replies: 4
    Last Post: 01-20-2011, 06:42 PM
  2. operate CL_PixelBuffer as CL_Surface
    By DavinciZhe in forum Official ClanLib SDK Forums
    Replies: 1
    Last Post: 11-12-2009, 06:05 PM
  3. CL_PixelBuffer::get_pixel() weird results...
    By Otto (Strange) Halmén in forum Official ClanLib SDK Forums
    Replies: 4
    Last Post: 12-06-2006, 07:36 AM

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •