IWICComponentFactory.CreateBitmapFromMemoryを呼び出すときにWINCODEC_ERR_WIN32ERROR 0x88982F94

IWICComponentFactory.CreateBitmapFromMemoryを呼び出すときに、Scan0に32bppArgb GDI +ビットマップのポインタを渡すと、次のエラーが発生します。

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、およびスキャンサイズはすべて正しいようです。なぜこれが起こっているのか分かりません(エラーコードやメッセージのGoogleの結果はありません)

0

1 答え

これは、元のコードが機能しない理由についての答えではありませんが、回避策です。 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);
    }
}

参考までに、<�​​a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee690291%28v=vs.85%29.aspx" rel="nofollow">ここではCOM方法とこちらプロキシメソッドです。どちらも[IN] BYTE * pbBufferを使用します。

0
追加された
プロキシ関数を使用することにより、IWICxxxインターフェイスに対して壊れたCOM宣言を使用することは避けられます。あなたが別の質問で間違っているという証拠があります。悪い宣言は、コードが間違ったメソッドを呼び出すことになります。あなたが持っているエラーコードは確かに偽です。
追加された 著者 Hans Passant,
COM宣言の何が間違っているのか理解できますか?私は[Out] [MarshalAs(UnmanagedType.LPArray、SizeParamIndex = 2)]の代わりにIntPtrをBYTE * pbBufferにラッピングしています。プロキシ関数のパラメータも [out] BYTE * pbBuffer ですが、そこでは正常に動作します。両方の呼び出しが同じシグネチャを使用する場合、なぜそれが1つのインスタンスで動作するのか、別のインスタンスで動作しないのか分かりません。
追加された 著者 Nathanael Jones,
私のコメントは、その他の質問に関するものです。この質問は、[IN] BYTE * pbBufferをLPArrayの代わりにIntPtrに変更することに関するものですが、それ以外は同じです。
追加された 著者 Nathanael Jones,