Проблема с WriteableBitmap на больших изображениях - PullRequest
0 голосов
/ 04 мая 2020

В программе мне нужно быстро нарисовать изображение. Для этого я выбрал WriteableBitmap и выполняю необходимые манипуляции с BackBuffer. И все рисуется благополучно, пока размер изображения не превышает определенный предел в области 1500 пикселей. Выше этого размера вместо желаемой формы появляется что-то еще.

writeable.Lock();
IntPtr buff = writeable.BackBuffer;
unsafe
{
    byte* pbuff = (byte*)buff.ToPointer();
    ...
}
writeable.AddDirtyRect(new Int32Rect(0, 0, (int)writeable.Width, (int)writeable.Height));
writeable.Unlock();

Вверху неверный результат рисования примерно так, как он должен выглядеть (округлый bru sh).

Если мы не обновляем все изображение целиком, а изменяем только область, результат идентичен обновлению всего изображения. В чем проблема? Это функция BackBuffer или некоторые другие ограничения на размер WriteableBitmap? И что с этим делать, если нам нужен очень быстрый рендеринг на изображениях 15-30 мегапикселей? Пожалуйста, не рассматривайте варианты с Direct2D.

1 Ответ

0 голосов
/ 04 мая 2020

Исходя из сообщения , я решил эту проблему, изменив способ доступа к BackBuffer.

Код, который не работает с большими изображениями:

writeable.Lock();
IntPtr buff = writeable.BackBuffer;
unsafe
{
    byte* pbuff = (byte*)buff.ToPointer();

    pbuff[Index * 3 + 0] = (byte)(B);
    pbuff[Index * 3 + 1] = (byte)(G);
    pbuff[Index * 3 + 2] = (byte)(R);
}
writeable.AddDirtyRect(new Int32Rect(0, 0, writeable.PixelWidth, writeable.PixelHeight));
writeable.Unlock();

Рабочий код:

writeable.Lock();
unsafe
{
    long pBackBuffer = (long)writeable.BackBuffer;
    int stride = writeable.BackBufferStride;

    int offset = (int)(RelativeY * stride + RelativeX * 3);
    long pBackBufferWithOffset = pBackBuffer + offset;
    *((byte*)pBackBufferWithOffset + 0) = (byte)(B);
    *((byte*)pBackBufferWithOffset + 1) = (byte)(G);
    *((byte*)pBackBufferWithOffset + 2) = (byte)(R);
}
writeable.AddDirtyRect(new Int32Rect(0, 0, writeable.PixelWidth, writeable.PixelHeight));
writeable.Unlock();

с возможностью записи. Пиксель Ширина ИЛИ ( int ) writeable.Width - не имеет значения.

Важно использовать это - long , а не это - int .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...