Forum Libraries, Components, and Plugins

Adding transparency to a SKBitmap image results in black background

I'm currently facing a problem adding transparency to a bitmap in a Xamarin.Forms Image view.

  1. The image is retrieved from the gallery, and converted to PNG format.
  2. Pixels are iterated and with some of them, their alpha value is set to 0 (fully transparent).
  3. Bitmap is converted to SKBitmapImageSource and shown in an Image view.

Result (top), and original (bottom), taken on Android:

The goal is to extract handwriting from a picture of it, by removing the background. But I can't get it to work. It keeps showing with a black background instead of transparent. Loading a transparent PNG file from internet works, so that tells me it is caused by something in the process of conversion or image processing.

The methods are as follows, I also attached an example project:

Decoding the image and showing it in the view:

void ShowImage()
    {
        SKBitmap source = SKBitmap.Decode(AppResources.Handwriting); // JPG file format

        SKBitmap converted = ConvertToPng(source);

        // Add transparency
        SKBitmap result = AddTransparency(converted, 0.3f);

        // Show in view
        ImageView.Source = SKBitmapImageSource.FromStream(SKImage.FromBitmap((SKBitmap)result).Encode().AsStream);
    }

Converting the image (JPG) to PNG to support transparency:

    private static SKBitmap ConvertToPng(SKBitmap source)
    {
        SKData data = SKImage.FromBitmap(source).Encode(SKEncodedImageFormat.Png, 100);
        SKBitmap converted = SKBitmap.Decode(data);
        return converted;
    }

Adding transparency to the background:

    SKBitmap AddTransparency(SKBitmap bitmapSource, float treshold)
    {
        var bitmapTarget = bitmapSource.Copy();

        // Calculate the treshold as a number between 0 and 255
        int value = (int)(255 * treshold);

        // loop trough every pixel
        int width = bitmapTarget.Width;
        int height = bitmapTarget.Height;

        for (int row = 0; row < height; row++)
        {
            for (int col = 0; col < width; col++)
            {
                var color = bitmapTarget.GetPixel(col, row);

                if (color.Red > value && color.Green > value && color.Blue > value)
                {
                    bitmapTarget.SetPixel(col, row, color.WithAlpha(0x00));
                }
            }
        }

        return bitmapTarget;
    }

Answers

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    I test your code, I fond this issue is related to this line

    SKData data = SKImage.FromBitmap(source).Encode(SKEncodedImageFormat.Png, 100);

    It can be convert the jpg to png successfully, but if I used this converted png file, it background is still black. But if I use window Paint tool, convert it to PNG, then I set it directly, it worked.

    Here is Nttet.png, that I used window Paint tool.

    Here is code that set it with following code.

      SKBitmap source = SKBitmap.Decode(AppResources.Nttet);
      SKBitmap result = AddTransparency(source, 0.3f);
      // Show in view
      ImageView.Source = SKBitmapImageSource.FromStream(SKImage.FromBitmap((SKBitmap)result).Encode().AsStream);
    

    I set a red background color for the ContentPage, Here is running screenshot.

  • bibskinbibskin Member

    Thanks for your reply. My goal is to remove the background of any JPG file at runtime within the app, without any external tools. The photo in the resources is just an example.

Sign In or Register to comment.