0

调用 IWICComponentFactory.CreateBitmapFromMemory 并将指针传递给 32bppArgb GDI+ 位图的 Scan0 时出现以下错误

WINCODEC_ERR_WIN32ERROR
0x88982F94
Windows Codecs received an error from the Win32 system.

IWICComponentFactory 接口声明:

    new IWICBitmap CreateBitmapFromMemory(
        uint uiWidth,
        uint uiHeight,
        [MarshalAs(UnmanagedType.LPStruct)] 
        Guid pixelFormat,
        uint cbStride,
        uint cbBufferSize,
        [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] 
        byte[] pbBuffer
        );

    new IWICBitmap CreateBitmapFromMemory(
        uint uiWidth,
        uint uiHeight,
        [MarshalAs(UnmanagedType.LPStruct)] 
        Guid pixelFormat,
        uint cbStride,
        uint cbBufferSize,
        IntPtr pbBuffer
        );

完整代码:

    public static IWICBitmap ToWic(IWICComponentFactory factory, Bitmap bit) {
        BitmapData bd = bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height),
                    ImageLockMode.ReadOnly, bit.PixelFormat);
        IWICBitmap b = null;
        try {
            //Create WIC bitmap directly from unmanaged memory
            b = factory.CreateBitmapFromMemory((uint)bit.Width, (uint)bit.Height, 
             ConversionUtils.FromPixelFormat(bit.PixelFormat), (uint)bd.Stride, 
             (uint)(bd.Stride * bd.Height), bd.Scan0);
            return b;
        } finally {
            bit.UnlockBits(bd);
        }
    }

宽度、高度、缓冲区大小、格式 GUID 和扫描大小似乎都是正确的。我无法弄清楚为什么会发生这种情况(错误代码或消息没有谷歌搜索结果

4

1 回答 1

0

这不是为什么原始代码不起作用的答案 - 但它是一种解决方法。使用IWICImagingFactory_CreateBitmapFromMemory_Proxy,一切正常。但是为什么原来的工作没有按预期工作呢?为什么 _Proxy 方法具有几乎相同的签名?

[DllImport("WindowsCodecs.dll", EntryPoint = "IWICImagingFactory_CreateBitmapFromMemory_Proxy")]
internal static extern int CreateBitmapFromMemory(IWICComponentFactory factory, uint width, uint height, ref Guid pixelFormatGuid, uint stride, uint cbBufferSize, IntPtr pvPixels, out IWICBitmap ppIBitmap);


public static IWICBitmap ToWic(IWICComponentFactory factory, Bitmap bit) {
    Guid pixelFormat = ConversionUtils.FromPixelFormat(bit.PixelFormat);
    if (pixelFormat == Guid.Empty) throw new NotSupportedException("PixelFormat " + bit.PixelFormat.ToString() + " not supported.");
    BitmapData bd = bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height), ImageLockMode.ReadOnly, bit.PixelFormat);
    IWICBitmap b = null;
    try {
            //Create WIC bitmap directly from unmanaged memory
        long result = CreateBitmapFromMemory(factory, (uint)bit.Width, 
 (uint)bit.Height,  ref pixelFormat, (uint)bd.Stride, 
 (uint)(bd.Stride * bd.Height), bd.Scan0, out b);

        if (result == 0x80070057) throw new ArgumentException();
        if (result < 0) throw new Exception("HRESULT " + result);
        return b;
    } finally {
        bit.UnlockBits(bd);
    }
}

作为参考,这里是 COM 方法这里是代理方法。两者都使用 [IN] BYTE *pbBuffer。

于 2011-11-12T14:28:29.813 回答