【问题标题】:How to correctly color a grayscale image through a UWP app?如何通过 UWP 应用正确为灰度图像着色?
【发布时间】:2018-08-16 12:50:15
【问题描述】:

我正在开发一个应用程序,其中一个主要功能是它调整灰度图像并为其应用颜色。

这是我用来计算的主要数学:

Color replaceWhite = Color.FromArgb(255, byte.Parse(acent.Substring(0, 2), 
    System.Globalization.NumberStyles.HexNumber), byte.Parse(acent.Substring(2, 2),
    System.Globalization.NumberStyles.HexNumber), byte.Parse(acent.Substring(4, 2),
    System.Globalization.NumberStyles.HexNumber));
WriteableBitmap source = await GetImageFile(sourceImage);
byte[] byteArray = null;
using (Stream stream = source.PixelBuffer.AsStream())
  {
    long streamLength = stream.Length;
    byteArray = new byte[streamLength];
    await stream.ReadAsync(byteArray, 0, byteArray.Length);
    if (streamLength > 0)
      {
        for (int i = 0; i < streamLength; i += 4)
          {
            if (byteArray[i + 3] != 0)
              {
                int b = Convert.ToInt32(byteArray[i]);
                int g = Convert.ToInt32(byteArray[i + 1]);
                int r = Convert.ToInt32(byteArray[i + 2]);

                int rB = ((((b * replaceBlack.B) / 255) + (((255 - b) * replaceWhite.B) / 255)) / 2);
                int rG = ((((g * replaceBlack.G) / 255) + (((255 - g) * replaceWhite.G) / 255)) / 2);
                int rR = ((((r * replaceBlack.R) / 255) + (((255 - r) * replaceWhite.R) / 255)) / 2);

                byte blue = Convert.ToByte(rB);
                byte green = Convert.ToByte(rG);
                byte red = Convert.ToByte(rR);

                byteArray[i] = blue; // Blue
                byteArray[i + 1] = green;  // Green
                byteArray[i + 2] = red; // Red
              }
          }
      }
  }
if (byteArray != null)
  {
    WriteableBitmap result = await PixelBufferToWritableBitmap(byteArray, source.PixelWidth, source.PixelHeight);
    StorageFile image = await WriteableBitmapToStorageFile(result, fileName, folderName);
    BitmapImage imageSource = await StorageFileToBitmapImage(image);
    return imageSource;
  }

幸运的是,该代码有效,但是当图像通过它时,颜色看起来比原始颜色深得多。我知道这很可能是数学问题,但我无法确定它在哪里。

值得一提的是,我使用的是应用设置中存储的颜色:

settings.Values["FlatWallpaperColor"] = theme.ColorCode;
string color = theme.ColorCode.Replace("#", "");
if (color.Length == 6)
  {
    SelectFlatWallpaperColorButton.Background = new SolidColorBrush (ColorHelper.FromArgb(255,
      byte.Parse(color.Substring(0, 2), System.Globalization.NumberStyles.HexNumber),
      byte.Parse(color.Substring(2, 2), System.Globalization.NumberStyles.HexNumber),
      byte.Parse(color.Substring(4, 2), System.Globalization.NumberStyles.HexNumber)));
  }

有没有人有这方面的经验可以提供帮助?

【问题讨论】:

    标签: c# uwp bitmapimage grayscale argb


    【解决方案1】:

    问题在于计算 - 您正在获取已经是加权平均值的“平均值”。您需要为颜色的每个组件使用加权平均值本身。例如rb:

    int rb = (byte)((b/255.0)*replaceBlack.B + ((255-b)/255.0)*replaceWhite.B));
    

    所以我们计算 replaceBlack 颜色的强度应该是多少(将原始颜色中“白色”的数量除以 255,我们对 replaceWhite 做同样的事情。然后我们可以安全地将这些相加两个数字,因为它永远不会超过 255(在最坏的情况下你会加起来 r * 255 + ( 1 - r ) * 255 = 255),如果因为某些 double 舍入,演员仍然会切断小数部分,所以我们最多只有 255。

    原始代码几乎是正确的,但它基本上使用了正确值的一半——所以一切都变暗了。此外,使用double 值进行计算会更好,因为您可以避免潜在的舍入错误。

    【讨论】:

      猜你喜欢
      • 2011-11-23
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 2010-12-22
      • 2023-02-22
      • 1970-01-01
      相关资源
      最近更新 更多