简体   繁体   中英

WriteableBitmap.Render changing color in the image

So I am trying to save a png of a UserControl to use as a tile. The code that i am using is

SquareTile sq = new SquareTile();
sq.Measure(new Size(336,336));
sq.Arrange(new Rect(0,0,336,336));
RenderExtensions.SaveToFile(sq);

And the RenderExtension Class looks like this

public static class RenderExtensions
{
    public static bool SaveToFile(this UIElement visualTreeElement)
    {
        WriteableBitmap wb = new WriteableBitmap(336, 336);
        wb.Render(visualTreeElement, null);
        wb.Invalidate();
        return wb.SaveToFile();
    }

    public static bool SaveToFile(this WriteableBitmap renderTargetBitmap)
    {
        try
        {
            string fname = "Shared/ShellContent/SquareTile.png";

            //StorageFile liveTileImageFile = localFolder.CreateFile("/Shared/ShellContent/SquareTile.png", CreationCollisionOption.ReplaceExisting);

            ExtendedImage ei = new ExtendedImage();
            byte[] result = new byte[renderTargetBitmap.Pixels.Length * sizeof(int)];
            Buffer.BlockCopy(renderTargetBitmap.Pixels, 0, result, 0, result.Length);
            ei.SetPixels(336,336,result);

            if (ei != null)
            {
                IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
                using (isf)
                {
                    if (!isf.DirectoryExists("Shared")) { isf.CreateDirectory("Shared"); }
                    if (!isf.DirectoryExists("Shared/ShellContent")) { isf.CreateDirectory("Shared/ShellContent"); }
                    if (isf.FileExists(fname)) { isf.DeleteFile(fname); }

                    using (var stream = new IsolatedStorageFileStream(fname, System.IO.FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, isf))
                    {
                        ei.WriteToStream(stream, fname);
                        stream.Close();
                    }
                }
            }
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }

}

Now the tile looks like this (Note background color has some transparency) 在此处输入图片说明

And if I add the same UserControl in a grid, it actually looks like this 在此处输入图片说明

here is the original image that this usercontrol is showing

在此处输入图片说明

You can see how red has turned blue even though the image is not transparent there. Why is this happening?

Update: I also tried a different image with only three colors red blue and yellow. turns out only red and blue are getting switched.

It sounds like WriteableBitmap and ExtendedImage expect their bytes to be in different formats. Probably BRGA (for WriteableBitmap) vs. RGBA (for ExtendedImage).

Unless you can specify the order on the ExtendedImage to match the WriteableBitmap you'll need to swizzle the bytes rather than just copying them straight over so that the colours line up properly.

Ok I have managed to swap the red and blue using this function

private static byte[] convertArray(int[] array)
    {
        byte[] newarray = new byte[array.Length * 4];

        for (int i = 0; i < array.Length; i++)
        {

            newarray[i * 4] = (byte)(array[i] >> 16); 
            newarray[i * 4 + 1] = (byte)(array[i] >> 8); 
            newarray[i * 4 + 2] = (byte)(array[i]); 
            newarray[i * 4 + 3] = (byte)(array[i] >> 24); 

        }
        return newarray;
    }

so now I am not using

Buffer.BlockCopy(renderTargetBitmap.Pixels, 0, result, 0, result.Length);

to convert int[] of WriteableBitmap.Pixels to byte[] required by ExtendedImage

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM