gpt4 book ai didi

c# - 将位图复制到另一个位图后圆圈周围有黑色边框

转载 作者:太空宇宙 更新时间:2023-11-03 10:41:02 26 4
gpt4 key购买 nike

我从 BitmapSource (RenderTargetBitmap) 中提取了带有蓝色圆圈的位图。 RenderTargetBitmap 是使用 PixelFormats.Pbgra32 创建的。

PixelFormats Pbgra32 将每个颜色 channel 预乘以 alpha 值。因此,当我尝试将位图转换为光标时,我得到的不透明图像比应有的要少。

我找到了问题的解决方案 here它将位图克隆到 Format24bppRgb 并手动设置 R、B、G 和 alpha 值。然而,解决方案工作得很好,但对于克隆的位图,我看到视觉周围有黑色边框。

我可以去除克隆位图中的黑色边框吗? (我怀疑这是 SafeCopy 方法内部的东西)

链接中使用的方法是:

private static void SafeCopy(BitmapData srcData, BitmapData dstData, byte alphaLevel)
{
for (int y = 0; y < srcData.Height; y++)
for (int x = 0; x < srcData.Width; x++)
{
byte b = Marshal.ReadByte(srcData.Scan0, y * srcData.Stride + x * 3);
byte g = Marshal.ReadByte(srcData.Scan0, y * srcData.Stride + x * 3 + 1);
byte r = Marshal.ReadByte(srcData.Scan0, y * srcData.Stride + x * 3 + 2);

Marshal.WriteByte(dstData.Scan0, y * dstData.Stride + x * 4, b);
Marshal.WriteByte(dstData.Scan0, y * dstData.Stride + x * 4 + 1, g);
Marshal.WriteByte(dstData.Scan0, y * dstData.Stride + x * 4 + 2, r);
Marshal.WriteByte(dstData.Scan0, y * dstData.Stride + x * 4 + 3, alphaLevel);
}
}

private static Cursor CreateCustomCursorInternal(Bitmap bitmap, double opacity)
{
Bitmap cursorBitmap = null;
IconInfo iconInfo = new IconInfo();
Rectangle rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

try
{
byte alphaLevel = System.Convert.ToByte(byte.MaxValue * opacity);

// Here, the pre-multiplied alpha channel is specified
cursorBitmap = new Bitmap(bitmap.Width, bitmap.Height,
PixelFormat.Format32bppPArgb);

// Assuming the source bitmap can be locked in a 24 bits per pixel format
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
BitmapData cursorBitmapData = cursorBitmap.LockBits(rectangle,
ImageLockMode.WriteOnly, cursorBitmap.PixelFormat);

// Use SafeCopy() to set the bitmap contents
SafeCopy(bitmapData, cursorBitmapData, alphaLevel);

cursorBitmap.UnlockBits(cursorBitmapData);
bitmap.UnlockBits(bitmapData);

.......
}

原始位图:

enter image description here

克隆位图:

enter image description here

最佳答案

将 WPF 32 位 PBGRA 位图转换为 WinForms PARRGB 位图并同时应用全局不透明度的最简单方法似乎只是将所有 A、R、G 和 B 值与不透明度因子(介于两者之间的浮点值)相乘0 和 1) 如下所示的方法。但是,我原以为还需要交换字节,但显然不是。

private static void CopyBufferWithOpacity(byte[] sourceBuffer,
System.Drawing.Imaging.BitmapData targetBuffer, double opacity)
{
for (int i = 0; i < sourceBuffer.Length; i++)
{
sourceBuffer[i] = (byte)Math.Round(opacity * sourceBuffer[i]);
}

Marshal.Copy(sourceBuffer, 0, targetBuffer.Scan0, sourceBuffer.Length);
}

给定一个 32 位 PBGRA 位图 pbgraBitmap(例如 RenderTargetBitmap),您可以使用如下方法:

var width = pbgraBitmap.PixelWidth;
var height = pbgraBitmap.PixelHeight;
var stride = width * 4;
var buffer = new byte[stride * height];
pbgraBitmap.CopyPixels(buffer, stride, 0);

var targetFormat = System.Drawing.Imaging.PixelFormat.Format32bppPArgb;
var bitmap = new System.Drawing.Bitmap(width, height, targetFormat);
var bitmapData = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, width, height),
System.Drawing.Imaging.ImageLockMode.WriteOnly,
targetFormat);

CopyBufferWithOpacity(buffer, bitmapData, 0.6);

bitmap.UnlockBits(bitmapData);

关于c# - 将位图复制到另一个位图后圆圈周围有黑色边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25330802/

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