WINCODEC_ERR_WIN32ERROR 0x88982F94 al llamar a IWICComponentFactory.CreateBitmapFromMemory

Recibo el siguiente error al llamar a IWICComponentFactory.CreateBitmapFromMemory y pasarle un puntero a Scan0 de un mapa de bits GDI + de 32bppArgb

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

IWICComponentFactory interfaz decl:

    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
        );

Código completo:

    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);
        }
    }

El ancho, la altura, el tamaño del búfer, el formato GUID y el tamaño de escaneo parecen correctos. No puedo entender por qué sucede esto (no hay resultados de Google para el código de error o el mensaje)

0

1 Respuestas

Esta no es una respuesta de por qué el código original no funciona, pero es una solución. Usando IWICImagingFactory_CreateBitmapFromMemory_Proxy , todo funciona bien. Pero, ¿por qué no funcionó el original como se supone? ¿Y por qué los métodos _Proxy con firmas casi idénticas?

[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);
    }
}

Para referencia, aquí está el COM método y aquí es el método proxy . Ambos utilizan [IN] BYTE * pbBuffer.

0
agregado
Al usar la función proxy, evita usar una declaración COM rota para las interfaces IWICxxx. Hay evidencia de que te equivocaste en otra pregunta. Una mala declaración hace que el código llame al método incorrecto. El código de error que tienes es ciertamente falso.
agregado el autor Hans Passant, fuente
¿Podría ayudarme a entender qué está mal con la declaración COM? Estoy envolviendo [out] BYTE * pbBuffer con IntPtr en lugar de [Out] [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)]. El parámetro de la función proxy también es [out] BYTE * pbBuffer , pero funciona bien allí. No veo por qué debería funcionar en una instancia y no en otra, cuando ambas llamadas usan la misma firma.
agregado el autor Nathanael Jones, fuente
Tenga en cuenta que mi comentario se refiere a la otra pregunta . Esta pregunta está relacionada con el cambio de [IN] BYTE * pbBuffer a IntPtr en lugar de LPArray, pero por lo demás es idéntico en la situación.
agregado el autor Nathanael Jones, fuente