首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将位图复制到另一个位图后的圆周黑色边框

将位图复制到另一个位图后的圆周黑色边框
EN

Stack Overflow用户
提问于 2014-08-15 17:00:04
回答 1查看 574关注 0票数 2

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

PixelFormats Pbgra32预乘每个颜色通道的α值.因此,当我试图将位图转换为光标时,我得到的不透明图像比原来应该看到的要少。

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

我能去掉克隆位图中的黑色边框吗?(我怀疑这是SafeCopy方法中的一些东西)

从链接中使用的方法是

代码语言:javascript
复制
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);

        .......
}

原始位图

克隆位图

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-16 17:06:31

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

代码语言:javascript
复制
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),您将使用如下方法:

代码语言:javascript
复制
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);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25330802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档