【问题标题】:WriteableBitmap.Render changing color in the imageWriteableBitmap.Render 在图像中改变颜色
【发布时间】:2015-03-17 20:17:00
【问题描述】:

所以我正在尝试保存 UserControl 的 png 以用作图块。我使用的代码是

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

RenderExtension 类看起来像这样

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;
        }
    }

}

现在瓷砖看起来像这样(注意背景颜色有一些透明度)

如果我在网格中添加相同的 UserControl,它实际上看起来像这样

这是这个用户控件显示的原始图像

即使图像在那里不透明,您也可以看到红色是如何变成蓝色的。 为什么会这样?

更新: 我还尝试了一个不同的图像,只有红蓝和黄三种颜色。原来只有红色和蓝色正在切换。

【问题讨论】:

    标签: c# silverlight windows-phone-8.1 render writeablebitmap


    【解决方案1】:

    听起来 WriteableBitmap 和 ExtendedImage 希望它们的字节采用不同的格式。可能是 BRGA(用于 WriteableBitmap)与 RGBA(用于 ExtendedImage)。

    除非您可以在 ExtendedImage 上指定顺序以匹配 WriteableBitmap,否则您需要调整字节而不是直接复制它们以使颜色正确排列。

    【讨论】:

      【解决方案2】:

      好的,我已经设法使用此功能交换了红色和蓝色

      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;
          }
      

      所以现在我没有使用

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

      将 WriteableBitmap.Pixels 的 int[] 转换为 ExtendedImage 所需的 byte[]

      【讨论】:

      • 使用BitmapEncoder怎么样?我认为您不需要第三方库,也不需要进行这种转换,而且速度更快。它在 8.1 之前不可用,但我看到问题标有 wp8.1 标签,所以您可能想尝试一下。
      • silverlight 或运行时是否可用
      • 两者都可用
      猜你喜欢
      • 1970-01-01
      • 2013-05-26
      • 2013-03-26
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 2019-04-06
      • 2023-03-21
      相关资源
      最近更新 更多