Почему BitmapSource.Create выдает исключение ArgumentException?

StackOverflow https://stackoverflow.com/questions/1983781

  •  22-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь получить растровое изображение, созданное из необработанных данных, для отображения в WPF, используя Image и BitmapSource:

Int32[] data = new Int32[RenderHeight * RenderWidth];

for (Int32 i = 0; i < RenderHeight; i++)
{
    for (Int32 j = 0; j < RenderWidth; j++)
    {
        Int32 index = j + (i * RenderHeight);

        if (i + j % 2 == 0)
            data[index] = 0xFF0000;
        else
            data[index] = 0x00FF00;
    }
}

BitmapSource source = BitmapSource.Create(RenderWidth, RenderHeight, 96.0, 96.0, PixelFormats.Bgr32, null, data, 0);

RenderImage.Source = source;

Однако вызов BitmapSource.Create выдает исключение ArgumentException, сообщающее "Значение не попадает в ожидаемый диапазон".Разве это не тот способ, которым нужно это сделать?Я что, неправильно делаю этот звонок?

Это было полезно?

Решение

Ваш шаг неверен.Шаг - это количество байтов, выделенных для одной строки сканирования растрового изображения.Таким образом, используйте следующее:

int stride = ((RenderWidth * 32 + 31) & ~31) / 8;

и замените последний параметр (в данный момент 0) с stride как определено выше.

Вот объяснение таинственной формулы шага:

Факт:Линии сканирования должны быть выровнены по 32-разрядным границам (ссылка).

Наивная формула для количества байтов в строке сканирования была бы следующей:

(width * bpp) / 8

Но это может не дать нам растровое изображение, выровненное по 32-битной границе, и (ширина * bpp), возможно, даже не была кратна 8.

Итак, что мы делаем, так это заставляем наше растровое изображение содержать не менее 32 бит подряд (мы предполагаем, что width > 0):

width * bpp + 31

и затем мы говорим, что нас не волнуют биты младшего порядка (биты 0--4), потому что мы пытаемся выровнять 32-битные границы:

(width * bpp + 31) & ~31

а затем разделите на 8, чтобы вернуться к байтам:

((width * bpp + 31) & ~31) / 8

Заполнение может быть вычислено с помощью

int padding = stride - (((width * bpp) + 7) / 8)

Наивная формула была бы такой

stride - ((width * bpp) / 8)

Но width * bpp может не выровняться по границе байта, и когда этого не произойдет, эта формула превысит количество заполнений на байт.(Представьте себе растровое изображение шириной в 1 пиксель с использованием 1 битов в секунду.Шаг равен 4, и наивная формула сказала бы, что отступ равен 4, но на самом деле это 3.) Итак, мы добавляем немного, чтобы охватить случай, когда width * bpp не является границей байта, и тогда мы получаем правильную формулу, приведенную выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top