从 SharpDX 位图转换为 GorgonImage 失败

Fail in converting from SharpDX bitmap to GorgonImage

我在我的项目中使用 Gorgon 2D 库(基于 SharpDX 构建)。我在从 SharpDX 位图转换为 GorgonImage 时遇到问题。我post我的问题在这里,希望你们能帮助我解决它。谢谢

我使用此代码创建 SharpDX 位图:

private GorgonImage D2DBitmapToGorgonImage(this SharpDX.Direct2D1.Bitmap1 bm, SharpDX.Direct2D1.DeviceContext5 D2D1Context5)
{
    SharpDX.DataRectangle map;
    if (bm.Options == SharpDX.Direct2D1.BitmapOptions.Target)
    {
        var img1 = new SharpDX.Direct2D1.Bitmap1(D2D1Context5, new SharpDX.Size2(bm.PixelSize.Width, bm.PixelSize.Height), new SharpDX.Direct2D1.BitmapProperties1()
        {
            PixelFormat = new SharpDX.Direct2D1.PixelFormat(DXGI.Format.R8G8B8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied),
            DpiX = 96,
            DpiY = 96,
            BitmapOptions = SharpDX.Direct2D1.BitmapOptions.CannotDraw | SharpDX.Direct2D1.BitmapOptions.CpuRead
        });

        img1.CopyFromBitmap(bm, new SharpDX.Mathematics.Interop.RawPoint(0, 0), new SharpDX.Mathematics.Interop.RawRectangle(0, 0, bm.PixelSize.Width, bm.PixelSize.Height));

        map = img1.Map(SharpDX.Direct2D1.MapOptions.Read);

        img1.Unmap();
        img1.Dispose();
    }

    else if (bm.Options == (SharpDX.Direct2D1.BitmapOptions.CannotDraw | SharpDX.Direct2D1.BitmapOptions.CpuRead))
        map = bm.Map(SharpDX.Direct2D1.MapOptions.Read);
    else
        throw new Exception("Can not convert from Direc2D1.Bitmap1 to GorgonImage");

    var size = bm.PixelSize.Width * bm.PixelSize.Height * 4;
    byte[] bytes = new byte[size];
    Marshal.Copy(map.DataPointer, bytes, 0, size);

    IGorgonImageInfo info = new GorgonImageInfo(ImageType.Image2D, BufferFormat.R8G8B8A8_UNorm)
    {
        Width = bm.PixelSize.Width,
        Height = bm.PixelSize.Height,

    };
    GorgonImage nqi = new GorgonImage(info);

    unsafe
    {

        for (int y = 0; y < info.Height; y++)
        {
            // We only need the width here, as our pointer will handle the stride by virtue of being an int.
            //int* offset = pixels + (y * bitmapLock.Width);

            int destOffset = y * nqi.Buffers[0].PitchInformation.RowPitch;
            for (int x = 0; x < info.Width; x++)
            {
                var position = (y * info.Width + x) * 4;


                byte r = 0, g = 0, b = 0, alpha = bytes[position + 3];
                if(bm.PixelFormat.AlphaMode == SharpDX.Direct2D1.AlphaMode.Premultiplied)
                {
                    if (alpha != 0)
                    {
                        var div_alpha = 0xff00 / alpha;
                        r = (byte)((bytes[position] * div_alpha + 0x80) >> 8);
                        g = (byte)((bytes[position + 1] * div_alpha + 0x80) >> 8);
                        b = (byte)((bytes[position + 2] * div_alpha + 0x80) >> 8);
                    }
                }
                else
                {
                    r = bytes[position+1];
                    g = bytes[position+2];
                    b = bytes[position+3];
                }

                SharpDX.Color4 cl4 = new SharpDX.Color4((float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)alpha/255.0f);
                // The DXGI format nomenclature is a little confusing as we tend to think of the layout as being highest to 
                // lowest, but in fact, it is lowest to highest.
                // So, we must convert to ABGR even though the DXGI format is RGBA. The memory layout is from lowest 
                // (R at byte 0) to the highest byte (A at byte 3).
                // Thus, R is the lowest byte, and A is the highest: A(24), B(16), G(8), R(0).

                int* destBuffer = (int*)(Unsafe.AsPointer(ref nqi.Buffers[0].Data[destOffset]));
                *destBuffer = cl4.ToRgba(); //color.ToABGR();
                //offset++;
                destOffset += 4;
            }
        }
    }
    return nqi;
}

问题是,SharpDX 位图的大小为 (1280,720)。转换后的图像正常:

但使用大小为 (1281,720) 的 SharpDX 位图。转换功能无法正常工作。我得到了这个转换后的图像:

我找不到我的代码有什么问题。你们能帮我指出问题吗?谢谢

这些是我使用的 Gorgon 类型:

GorgonImage GorgonImageInfo GorgonImageBuffer GorgonNativeBuffer

这种带有环绕的倾斜通常是步幅与宽度的问题。您可以使用倾斜的方向(结合行顺序,通常是自上而下但并非总是如此)来查看它是源地址计算中的问题还是目标地址计算中的问题。这里倾斜的角度为 "backwards",这意味着 src 地址前进得太慢,结果像素与它们应该在的位置相比越来越向右和向下。原则上,相同的效果可能是由目标地址前进太快引起的,但这不太可能(步幅与宽度问题不会这样做,使用 错误的 步幅可能)

所以 position 是错误的,并且 (y * info.Width + x) * 4 使用宽度而不是可疑的步幅。

源步长是 map.Pitch 所以 position 应该是 y * map.Pitch + 4 * x