PixelARGB


#1

Someone has changed the PixelARGB constructor recently which stopped my working code from building.  I've fixed that now, but the bit I changed was always a bit of a performance hot-spot. 

What's the right (and fastest preferably!) way to take a Pixel from and Image, blend the existing pixel with another semi-transparent colour and then write it back to the Image? 

 


#2

Can you point to the specific constructor you were using and what you want to do? As far as I can remember, there was an easy fix to any function using the old constructors.


#3

There was.  Maybe this: https://www.juce.com/api/classColour.html#adf6de35bcbcae267c1f34791f52415a6

I think this is what I ended up with: 

                PixelARGB pxl(imageData.getPixelColour(x1, y1).getARGB());

                pxl.blend(pcolour);

                Colour newColour = Colour(pxl.getRed(), pxl.getGreen(), jmin((uint8) 150, pxl.getBlue()), pxl.getAlpha());

                imageData.setPixelColour(x1, y1, newColour);

But I seem to recall the profiler pointing it's wagging finger at this whole section.  Is there a better way?


#4

The fast way to do this is to blend directly to the internal bitmap data of the image. You can get a direct pointer to the image data via the Image::BitmapData class. If the Image's getFormat method returns Image::ARGB then you can safely cast the BitmapData's getLinePointer and getPixelPointer to a PixelARGB pointer.

 

For example,  to blend a colour onto to an ARGB image the following code would work (and run fast):

 


    Image rgbaImage = ImageCache::getFromMemory (original_png, original_pngSize);
    PixelARGB mixColour = Colour::fromFloatRGBA (1.0f, 0.0f, 0.0f, 0.5f).getPixelARGB ();

    // get the bitmap data
    Image::BitmapData rawData (rgbaImage, Image::BitmapData::readWrite);
    
    // make sure that you are allowed to cast the internal data to PixelARGB
    jassert (rgbaImage.getFormat () == Image::ARGB);

    for (int y = 0; y < rgbaImage.getHeight (); ++y)
    {
        PixelARGB* rawPtr = reinterpret_cast<PixelARGB*> (rawData.getLinePointer (y));
        for (int x = 0; x < rgbaImage.getWidth (); ++x)
            rawPtr [x].blend (mixColour);
    }

#5

Wicked.   Thanks Fabian - much appreciated!