/// <summary> /// Detects the color order of a stored byte array. Byte order may change between platforms, you should call this once before writting a PNG or if you have any issues with colors changing. /// </summary> public static void DetectWBByteOrder() { // We should only ever run the detection once (assuming it succeeded at least). if (WBBODetectionRun == true) { return; } // Create a 3x1 WriteableBitmap to write RGB colors to. var TestWB = new WriteableBitmap(3, 1); //// Create the red 1 pixel rectangle. //var redRectangle = new Rectangle(); //redRectangle.Width = 1; //redRectangle.Height = 1; //redRectangle.Fill = new SolidColorBrush( Colors.Red ); //// Create the green 1 pixel rectangle. //var greenRectangle = new Rectangle(); //greenRectangle.Width = 1; //greenRectangle.Height = 1; //greenRectangle.Fill = new SolidColorBrush( Colors.Green ); //// Create the blue 1 pixel rectangle. //var blueRectangle = new Rectangle(); //blueRectangle.Width = 1; //blueRectangle.Height = 1; //blueRectangle.Fill = new SolidColorBrush( Colors.Blue ); // Render the three 1 px rectangles. TestWB.SetPixel(0, 0, Colors.Red); TestWB.SetPixel(1, 0, Colors.Green); TestWB.SetPixel(2, 0, Colors.Blue); // Invalidate the bitmap to make it actually render. TestWB.Invalidate(); // Go get the 4 byte arrays of each red/green/blue pixels that we just rendered. var redColor = TestWB.GetPixel(0, 0); var greenColor = TestWB.GetPixel(1, 0); var blueColor = TestWB.GetPixel(2, 0); byte[] redBytes = { redColor.A, redColor.R, redColor.G, redColor.B }; byte[] greenBytes = { greenColor.A, greenColor.R, greenColor.G, greenColor.B }; byte[] blueBytes = { blueColor.A, blueColor.R, blueColor.G, blueColor.B }; // Just in case something goes terrible wrong, set all the color values to invalid settings. int trans = 4; int red = 4; int green = 4; int blue = 4; // Find the alpha channel, this wil be the only byte that is the same in all three pixels. if (redBytes[0] == greenBytes[0] && blueBytes[0] == greenBytes[0]) { trans = 0; } if (redBytes[1] == greenBytes[1] && blueBytes[1] == greenBytes[1]) { trans = 1; } if (redBytes[2] == greenBytes[2] && blueBytes[2] == greenBytes[2]) { trans = 2; } if (redBytes[3] == greenBytes[3] && blueBytes[3] == greenBytes[3]) { trans = 3; } // if we didn't detect the alpha channel, just give up :( if (trans != 4) { // now set all the alpha channel's to zero to get them out of the way. redBytes[trans] = 0; greenBytes[trans] = 0; blueBytes[trans] = 0; // Find the red channel. if (redBytes[0] == 255) { red = 0; } else if (redBytes[1] == 255) { red = 1; } else if (redBytes[2] == 255) { red = 2; } else if (redBytes[3] == 255) { red = 3; } // Find the green channel, note that Colors.Green is not dark green, but light green so use 128 instead of 255 to detect it. if (greenBytes[0] == 128) { green = 0; } else if (greenBytes[1] == 128) { green = 1; } else if (greenBytes[2] == 128) { green = 2; } else if (greenBytes[3] == 128) { green = 3; } // Find the blue channel. if (blueBytes[0] == 255) { blue = 0; } else if (blueBytes[1] == 255) { blue = 1; } else if (blueBytes[2] == 255) { blue = 2; } else if (blueBytes[3] == 255) { blue = 3; } } // Now set the byte order, if any of the values are still set to 4, something went wrong and return the default values. if (red == 4 || green == 4 || blue == 4 || trans == 4) { WBByteOrder = new int[] { 2, 1, 0, 3 }; } else { WBBODetectionRun = true; WBByteOrder = new int[] { red, green, blue, trans }; } }