我正在开发一个应用程序,其主要功能之一是它可以调整灰度图像并为其应用颜色。
这是我用来计算的主要数学公式:
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)));
}
有人在这方面有经验并可以提供帮助吗?
答案 0 :(得分:3)
问题出在计算中-您正在获取已经是加权平均值的“均值”值。您宁愿对每种颜色成分使用加权平均值 。例如rb
:
int rb = (byte)((b/255.0)*replaceBlack.B + ((255-b)/255.0)*replaceWhite.B));
因此,我们通过将原始颜色中的“白色”量除以255,然后对replaceBlack
做同样的事情来计算replaceWhite
颜色应具有的强度。可以安全地将这两个数字相加,因为它永远都不能超过255(在最坏的情况下,您将累加r * 255 + ( 1 - r ) * 255 = 255
),并且如果因为某些double
舍入而这样做,则转换仍将舍去小数因此我们最多只能有255个。
原始代码几乎是正确的,但是它基本上使用了正确值的一半-因此所有内容都会变得更暗。此外,使用double
值进行计算会更好,因为这样可以避免潜在的舍入误差。