WINCODEC_ERR_WIN32ERROR 0x88982F94 bij het aanroepen van IWICComponentFactory.CreateBitmapFromMemory

Ik ontvang de volgende fout bij het aanroepen van IWICComponentFactory.CreateBitmapFromMemory en geef dit een aanwijzer door naar Scan0 van een 32bppArgb GDI + -bitmap

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

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

Volledige code:

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

Breedte, hoogte, buffergrootte, GUID formaat en scanformaat lijken allemaal correct. Ik kan niet achterhalen waarom dit gebeurt (er zijn geen google-resultaten voor de foutcode of het bericht

0

1 antwoord

Dit is geen antwoord waarom de originele code niet werkt, maar het is een tijdelijke oplossing. Met IWICImagingFactory_CreateBitmapFromMemory_Proxy werkt alles goed. Maar waarom werkte het oorspronkelijke werk niet zoals het hoort? En waarom de _Proxy-methoden met bijna identieke handtekeningen?

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

Ter referentie, hier is de COM methode en hier is de proxy-methode . Beide gebruiken [IN] BYTE * pbBuffer.

0
toegevoegd
Door de proxy-functie te gebruiken, vermijdt u het gebruik van een kapotte COM-verklaring voor de IWICxxx-interfaces. Er zijn aanwijzingen dat je het fout hebt in een andere vraag. Een slechte verklaring zorgt ervoor dat de code de verkeerde methode aanroept. De foutcode die je hebt is zeker nep.
toegevoegd de auteur Hans Passant, de bron
Kunt u mij helpen begrijpen wat er mis is met de COM-verklaring? Ik verpak [uit] BYTE * pbBuffer met IntPtr in plaats van [Out] [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)]. De proxy-functieparameter is ook [uit] BYTE * pbBuffer , maar daar werkt het prima. Ik zie niet in waarom het in één geval zou moeten werken en niet in een ander, wanneer beide oproepen dezelfde handtekening gebruiken.
toegevoegd de auteur Nathanael Jones, de bron
Merk op dat mijn opmerking betrekking heeft op de andere vraag . Deze vraag heeft betrekking op het wijzigen van de [IN] BYTE * pbBuffer in IntPtr in plaats van LPArray, maar is verder identiek in de situatie.
toegevoegd de auteur Nathanael Jones, de bron