Обновить контейнер изображений при изменении локального исходного файла изображения - PullRequest
1 голос
/ 10 февраля 2012

Я создаю GUI вокруг алгоритма.Для этого у меня есть компонент Window, который содержит компонент Image внутри него.

Содержимое внутри компонента Image (imgHolder) задается объектом BitmapImage (_image), который для целей этого примера инициализируется следующим образом:

_image = new BitmapImage();
_image.BeginInit();
_image.CacheOption = BitmapCacheOption.OnLoad;
_image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
_image.UriSource = new Uri("c:\\a1.bmp");
_image.EndInit();

imgHolder.Source = _image;

Основная программа, содержащаяОкно выполнит вызов одной из функций алгоритма из DLL-файла Matlab.Это запустит одну итерацию алгоритма, к концу которой он запишет результаты в локальный файл bmp сверху ("c: \ a1.bmp").Следовательно, базовые данные для изображения были обновлены, и я хотел бы, чтобы это было отражено в компоненте imgHolder.Для этого я просто дублирую приведенный выше код всякий раз, когда возвращаюсь из функции.

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

Исследуя это, я обнаружил, что вместо этого можно использовать поток памяти, но мне интересно, будет ли это кардинальным улучшением или нет, поскольку мне кажется, что мне все равно придется создавать 100 изображений при выполнении алгоритма.Разве нельзя как-то напрямую изменить базовый буфер?Я слышал, что GetPixel и SetPixel не очень эффективны, так как они устанавливают блокировку при каждом вызове.Возможно ли это сделать, используя тот же объект _image?Если бы это был не локальный файл, я мог бы использовать опцию no cache, и он должен был работать «сам по себе».Отсутствие опции кэширования для локального файла не работает из-за блокировки.

У кого-нибудь есть идея получше?

Спасибо!

1 Ответ

2 голосов
/ 10 февраля 2012

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

Таким образом, вы можете использовать WritableBitmap в качестве _image.Source и циклически обновлять его содержимое одним из его WritePixels методов.

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

XAML:

<Window ...>
   <Grid>
       <Image Name="image" />
   </Grid>
</Window>

Код:

public partial class MainWindow : Window
{
    private WriteableBitmap bitmap = new WriteableBitmap(100, 100, 96d, 96d, PixelFormats.Rgb24, null);
    private byte[] buffer = new byte[30000];

    public MainWindow()
    {
        InitializeComponent();
        image.Source = bitmap;
    }

    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        Point pos = e.GetPosition(image);
        int offset = (int)pos.X + (int)pos.Y;

        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = (byte)(i + offset);
        }

        bitmap.WritePixels(new Int32Rect(0, 0, 100, 100), buffer, 300, 0);
    }
}
...