gpt4 book ai didi

c# - 使用 LockBits/Marshal.Copy 将 S.D.Bitmap 转换为 MonoGame Texture2D - 结果失真

转载 作者:行者123 更新时间:2023-12-04 10:59:40 35 4
gpt4 key购买 nike

我正在尝试编写一个函数,该函数采用 System.Drawing.Bitmap,并尽快吐出 Monogame Texture2D。

我已经设法在位图上使用 GetPixel 使其工作,这很简单,但它当然太慢了。

我仔细研究并发现了一种使用 LockBits 和 Marshal.Copy 快速访问像素值的更快的技术。问题是,它在某些图像上完美运行,而其他图像最终看起来像这样:
Example Image

从我能够收集到的信息来看,这与没有正确补偿 Stride 有关,但我是直接处理这个级别的图像数据的新手,我完全迷失了。我在这里做错了什么导致这种灰度倾斜的结果?

当这有效时,它适用于大多数图像,速度非常快,正是我想要的。如果重要的话,我将专门处理网络上非常典型的 JPG/PNG 图像。

public static Texture2D FromBitmap(MagickImage input, GraphicsDevice graphicsDevice)
{
var bounds = new Rectangle(0, 0, input.Width, input.Height);

var bitmap = input.ToBitmap();

var output = new Texture2D(graphicsDevice, bitmap.Width, bitmap.Height);

var outputArray = new Color[bitmap.Width * bitmap.Height];

var bitmapBits = bitmap.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
var bitmapDepth = Image.GetPixelFormatSize(bitmapBits.PixelFormat) / 8;
var bitmapBuffer = new byte[bitmapBits.Stride * bitmapBits.Height];

Marshal.Copy(bitmapBits.Scan0, bitmapBuffer, 0, bitmapBuffer.Length);

for (var y = 0; y < bitmap.Height; y++)
{
for (var x = 0; x < bitmap.Width; x++)
{
var arrayPoint = x + (y * bitmap.Width);

outputArray[arrayPoint].R = bitmapBuffer[(arrayPoint * bitmapDepth) + 2];
outputArray[arrayPoint].G = bitmapBuffer[(arrayPoint * bitmapDepth) + 1];
outputArray[arrayPoint].B = bitmapBuffer[(arrayPoint * bitmapDepth) + 0];
}
}

output.SetData(outputArray);

return output;
}
}

编辑:我在指向 outputArray 中的 arrayPoint 时犯了一个简单的错误,这是上一次尝试的剩余部分。纠正这个 + 重写 arrayPoint 定义修复了它。下面的作品:
var arrayPoint = (y * bitmapBits.Stride) + (x * bitmapDepth);

outputArray[(y * bitmap.Width) + x].R = bitmapBuffer[arrayPoint + 2];
outputArray[(y * bitmap.Width) + x].G = bitmapBuffer[arrayPoint + 1];
outputArray[(y * bitmap.Width) + x].B = bitmapBuffer[arrayPoint + 0];

最佳答案

你忽略了 stride ,这意味着有些图像会起作用,有些则不会。

步幅不是 bitmap.Width * bitmapDepth。
步幅是单行像素(扫描线)的宽度,四舍五入到四字节边界。

因此,您始终必须为每一行按步幅增加 arrayPoint,而不是进行一些手动计算。

关于c# - 使用 LockBits/Marshal.Copy 将 S.D.Bitmap 转换为 MonoGame Texture2D - 结果失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58907976/

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