gpt4 book ai didi

c# - (Bitmap)image 的行为不同于 new Bitmap(image)

转载 作者:太空狗 更新时间:2023-10-29 22:28:01 30 4
gpt4 key购买 nike

这是我写的测试,目前会失败:

var unusableColor = Color.FromArgb(13, 19, 20, 19);
var retrievedColor = Color.Empty;
var tempFile = Path.GetTempFileName();

using (var bitmap = new Bitmap(1, 1))
{
bitmap.SetPixel(0, 0, unusableColor);
bitmap.Save(tempFile, ImageFormat.Png);
}

using (var image = Image.FromFile(tempFile))
// This will lead to the error
using (var bitmap = new Bitmap(image))
// But this will work
//using (var bitmap = (Bitmap)image)
{
retrievedColor = bitmap.GetPixel(0, 0);
}

Assert.That(retrievedColor, Is.SameAs(unusableColor));

如果您查看 retrievedColor,您会发现它与 Color.FromArgb(13, 19, 19, 19) 相同。所以不同之处在于绿色部分从 20 变为 19。

知道为什么会发生这种情况,或者在什么情况下位图的构造函数会更改像素?

更新

似乎是一个嵌套更深的问题。通过用图像变量的简单转换替换 Bitmap 构造函数,问题就消失了。这也许可以解决问题,但不能解释它。此外,我什至能够通过以下过程在 Paint.Net 中重现该问题:

  • 打开 Paint.Net 并创建一个新图像(大小无关紧要)
  • 全选(Ctrl+A)
  • 删除选择(Del)
  • 打开颜色对话框(F8)
  • 为 RGB 输入上述值 (19, 20, 19) 并在底部输入透明度 (13)。
  • 选择填充工具(F)
  • 给空白图片填充颜色
  • 选择颜色选择工具(K)
  • 点击某处进入您的新图像并观看颜色对话框

所以看起来这可能是一个更深层次的问题,不是由 Bitmap 或 Image 类引起的,而可能是由一些更深层次的功能引起的,比如 GDI+ 或类似的东西。

更新2

我刚刚写了一个新测试来找出所有受影响的颜色:

for (int a = 0; a < 256; a++)
{
for (int r = 0; r < 256; r++)
{
for (int g = 0; g < 256; g++)
{
for (int b = 0; b < 256; b++)
{
using (var bitmap = new Bitmap(1, 1))
{
var desiredColor = Color.FromArgb(a, r, g, b);
bitmap.SetPixel(0, 0, desiredColor);

// This will fail in a lot of colors with a low alpha channel value
using (var copiedBitmap = new Bitmap(bitmap))
// This will work, cause the information is entirely copied.
//using (var copiedBitmap = (Bitmap)bitmap.Clone())
{
var retrievedColor = copiedBitmap.GetPixel(0, 0);

if (desiredColor != retrievedColor)
{
Debug.Print(desiredColor + " != " + retrievedColor);
}
}
}
}
}
}

请不要让它完全自行运行,因为它会花费很长时间才能完成,而且它还会发现很多不同之处。但是您可以看到,如果您调整透明度(设置为 1 或 10),那么您会看到 RGB 值使用它作为某种位深度。

因此,如果您从使用低透明度值的现有位图创建新位图,就会出现问题。真正的根本原因似乎远在 GDI、内核或该区域的某个地方,无法从 .Net 中解决。

请注意,如果颜色具有较低的透明度值,则可以通过调用位图构造函数来更改颜色。如果你真的需要原始颜色在第二个实例中保持活力,而不是使用 (Bitmap)myBitmap.Clone() 或者如果你从磁盘加载它使用 (Bitmap)Image.FromFile(filename ) 因为 Image 只是一个抽象类,通常会通过 Bitmap 类实例化。

最佳答案

我使用 Paint.NET 检查了与您的代码一起保存的 PNG 文件,像素颜色完全是 unusableColor
如果你用这个改变你的阅读代码:

using (Bitmap bitmap = (Bitmap)Image.FromFile(tempFile))
{
retrievedColor = bitmap.GetPixel(0, 0);
}

一切正常

关于c# - (Bitmap)image 的行为不同于 new Bitmap(image),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8048175/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com