If not required to solve this in code, a quick solution is to use an image editing application:
- Ensure the background has an alpha channel.
- Use the magic wand tool to select each isolated background part.
- delete the selection.
To convert the background to transparency. I did this to your image with the magic wand tolerance set to 0 using paint.net in just a few seconds.
Otherwise use an opacity mask.
Though not meeting your assignment's criteria, another solution is to replace all background pixels at runtime. If you do this, save the result to disk so you only incur the cost once. This is essentially a DIY of the first solution I described. i.e.
// someBitmap is the bitmap you want to manipulate.
// Ensure we're reading from a bitmap in Bgra32 format.
var srcBitmap = someBitmap.Format == PixelFormats.Bgra32 ?
(BitmapSource)someBitmap : new FormatConvertedBitmap(someBitmap, PixelFormats.Bgra32, null, 0);
// Copy the pixels of the source image to a buffer we can use.
var width = srcBitmap.PixelWidth;
var height = srcBitmap.PixelHeight;
var stride = width * 4;
var byteCount = height * stride;
var srcData= new byte[byteCount];
srcBitmap.CopyPixels(srcData, stride, 0);
var destBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
var destData = new byte[byteCount];
// The channel offsets for PixelFormats.Bgra32.
const int BlueOffset = 0;
const int GreenOffset = 1;
const int RedOffset = 2;
const int AlphaOffset = 3;
// Copy the image, filtering out the background.
for (var y = 0; y < height; y++) { // Each column.
for (var x = 0; x < width; x++) { // Each row.
var i = (y * width + x) * 4; // The offset of this pixel in both srcBytes and destBytes.
var b = srcData[i + BlueOffset];
var g = srcData[i + GreenOffset];
var r = srcData[i + RedOffset];
var a = srcData[i + AlphaOffset];
// The "filter".
if (b == 0 && g == 0 && r == 0 && a == 255) {
// The pixel is solid black(the background color), set to transparent.
a = 0;
}
destData[i + BlueOffset] = b;
destData[i + GreenOffset] = g;
destData[i + RedOffset] = r;
destData[i + AlphaOffset] = a;
}
}
// Update the final image with the filtered buffer.
destBitmap.WritePixels(new Int32Rect(0, 0, width, height), destData, stride, 0);
// Finally, convert destBitmap to a BitmapImage and use that in place of someBitmap.
See this answer for converting destBitmap
to a BitmapImage
.