Неожиданное исключение «Область растрового изображения уже заблокирована» с GetEncoderParameterList.Есть идеи? - PullRequest
4 голосов
/ 30 июня 2010

Я пытаюсь использовать этот пример кода от Microsoft, чтобы определить, какие параметры кодировщика доступны для кодера JPEG.(Реальная проблема, которую я пытаюсь решить, - посмотреть, могу ли я установить параметры подвыборки Chroma явно)

http://msdn.microsoft.com/en-us/library/bb882589.aspx

private void GetSupportedParameters(PaintEventArgs e)
{
    Bitmap bitmap1 = new Bitmap(1, 1);
    ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
    EncoderParameters paramList = bitmap1.GetEncoderParameterList(jpgEncoder.Clsid);
    EncoderParameter[] encParams = paramList.Param;
    StringBuilder paramInfo = new StringBuilder();

    for (int i = 0; i < encParams.Length; i++)
    {
        paramInfo.Append("Param " + i + " holds " + encParams[i].NumberOfValues +
            " items of type " +
            encParams[i].ValueType + "\r\n" + "Guid category: " + encParams[i].Encoder.Guid + "\r\n");

    }
    e.Graphics.DrawString(paramInfo.ToString(), this.Font, Brushes.Red, 10.0F, 10.0F);
}

private ImageCodecInfo GetEncoder(ImageFormat format)
{

    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

    foreach (ImageCodecInfo codec in codecs)
    {
        if (codec.FormatID == format.Guid)
        {
            return codec;
        }
    }
    return null;
}

Проблема в том, что GetEncoderParameterList всегда выдаетИсключение: область растрового изображения уже заблокирована.

Я пытался поместить код в самое начало моей программы, а не в обработчик события на рисовании.То же самое.Я пытался изменить битовую глубину на растровом изображении и создавать растровые изображения другими способами, без разницы.

Любая идея, почему .NET считает, что только что созданное растровое изображение имеет заблокированную область?


Обновить!Немного больше информации: если я использую кодировщик TIFF, он не выходит из строя:

    Bitmap bitmap1 = new Bitmap(1, 1);
    ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.TIFF);  // TIFF instead of JPEG
    EncoderParameters paramList = bitmap1.GetEncoderParameterList(jpgEncoder.Clsid);
    EncoderParameter[] encParams = paramList.Param;

Так что я думаю, что это может быть просто ошибкой / ограничением GetEncoderparameterList для jpeg ....

1 Ответ

5 голосов
/ 01 июля 2010

Я повторяю это. Сообщение об исключении является поддельным, оно типично для исключений GDI +. Источником проблемы является кодек jpeg, GetEncoderParameterList () запрашивает у него список параметров, которые он поддерживает. Список, который он возвращает, содержит одну неверную запись, NumberOfValues ​​равно 0. Это приводит к тому, что Marshal.AllocHGlobal () возвращает NULL, ошибочно интерпретируемый как исключение нехватки памяти, что в свою очередь неверно интерпретируется, поскольку «область битовой карты уже заблокирована "исключение.

Тьфу, GDI +, конечно, беспорядок. Эта проблема почти наверняка характерна для GDI + версии 1.10, версии, которая впервые была поставлена ​​с Vista. Также может быть специфично для Win7, я видел несколько сообщений на форуме о проблемах с кодеком JPEG в этой операционной системе.

Ну, вы ничего не можете с этим поделать, пока не станет доступен следующий пакет обновления для Windows, если тогда. Чтобы ответить на ваш конкретный запрос, нет, вероятно, нет. Список параметров кодера, о которых GDI + знает, указан в заголовочном файле SDK GdiPlusImaging.h. Единственное, что близко, это «EncoderChrominanceTable», доступный как Encoder.ChrominanceTable.Guid в .NET Framework. Не знаю, если это близко к тому, что вы ищете.

Вы действительно должны рассмотреть класс WPF JpegBitmapEncoder, значительное улучшение по сравнению с GDI =.

...