Можно ли изменить небезопасность WPF Bitmapsource в памяти из другого потока

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

Вопрос

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

В настоящее время мне удается сделать это, используя «небезопасный» код против старомодной системы. Drawing.bitmap, и он работает (заблокирован рабочей зоной, скрипку с пикселями) выполнена. Подход описан в этом посте: http://blogs.msdn.com/b/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx

Чтобы работать в WPF, я затем создаю WPF Bitmapsource, используя этот подход:

    BitmapSource destination;
    IntPtr hBitmap = bitmap.GetHbitmap();
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
    destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions);
    destination.Freeze();
    return destination;

Тем не менее, это создает много копий в памяти, и я действительно хочу попасть туда и возиться с базовыми битами внутри Bitmapsource, как это показал Эрикгу в примере растрового изображения. Это возможно?

Я понимаю, что Pixelshaders, вероятно, могут сделать это, но это академическое упражнение, включающее несколько потоков (которое поддерживается при редактировании растрового изображения в небезопасном режиме).

заранее спасибо

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

Решение

Я скажу вам столько, сколько я знаю.

Сначала вы, кажется, уже знаете о замораживающих растровых картах, прежде чем вернуть их в главную ветку. Это хорошее начало.

Однажды я попытался уменьшить копирование, выводя новую реализацию из Bitmapsource, и переопределить виртуальные функции, которые копируют ваши данные из растрового изображения. Это сработало, но создало огромные утечки памяти. Никогда не понял.

Конечно, вы также можете создать растросие непосредственно из множества байтов (и потерять накладные расходы GDI Bitmap). MSDN DOCS

Вы рассматривали Riseablebitmap? Это был ответ команды WPF на общую жалобу на все копии.

Редактировать: MSDN говорит явно (в документации writeburebitmap.backbuffer), что ее можно использовать из фонового потока:

Вы можете передать указатель Backbuffer на внешние компоненты и другие потоки для обработки, но если вы это сделаете, вы должны предоставить вам собственную координацию потока. В частности, вы должны убедиться, что поток пользовательского интерфейса определяет измененные области, вызывая метод AddDirtyRect, и что поток пользовательского интерфейса разблокирует буфер, вызывая метод разблокировки.

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

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