Search code examples
c#uwpwriteablebitmap

How to adjust the brightness of an Image efficiently


Does anyone know of a more efficient way of adjusting the brightness of an image at runtime in UWP?

I found this question which works fine but runs terribly slow. However, I can't find any documentation online suggesting there is an alternative method.

Here is my problematic code.

// TODO Make Image Brightness Slider quicker and more intuitive. 
private WriteableBitmap ChangeBrightness(WriteableBitmap source, int increment)
{
    var dest = new WriteableBitmap(source.PixelWidth, source.PixelHeight);

    byte[] color = new byte[4];

    using (var srcBuffer = source.PixelBuffer.AsStream())
    using (var dstBuffer = dest.PixelBuffer.AsStream())
    {
        while (srcBuffer.Read(color, 0, 4) > 0)
        {
            for (int i = 0; i < 3; i++)
            {
                var value = (float)color[i];
                var alpha = color[3] / (float)255;
                value /= alpha;
                value += increment;
                value *= alpha;

                if (value > 255)
                {
                    value = 255;
                }

                color[i] = (byte)value;
            }

            dstBuffer.Write(color, 0, 4);
        }
    }

    return dest;
}

Solution

  • This might work. I didn't test it:

        private async Task<WriteableBitmap> ChangeBrightness(WriteableBitmap source, float increment)
        {
            var canvasBitmap = CanvasBitmap.CreateFromBytes(CanvasDevice.GetSharedDevice(), source.PixelBuffer,
                source.PixelWidth, source.PixelHeight, DirectXPixelFormat.B8G8R8A8UIntNormalized);
    
            var brightnessFx = new BrightnessEffect
            {
                Source = canvasBitmap,
                BlackPoint = new Vector2(0, increment)
            };
    
            var crt = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), source.PixelWidth, source.PixelHeight, 96);
    
            using (var ds = crt.CreateDrawingSession())
            {
                ds.DrawImage(brightnessFx);
            }
    
            crt.GetPixelBytes(source.PixelBuffer);
    
            return source;
        }
    

    You have to reference win2d nuget