2012-02-10 4 views
1

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

Содержание внутри компонента изображения (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 различных растровых изображений, все из которых были получены из того же файла.

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

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

Спасибо!

ответ

2

Я не совсем понял, если у вас есть доступ к необработанным данным растрового изображения или нет, или если он всегда записывается в файл. Поскольку вы упоминаете 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); 
    } 
} 
+0

Спасибо, это выглядит как решение, я ищу. Как связать это с изображением так, чтобы он обновлялся каждый раз, когда изменялась записьableableBitmap? Могу ли я просто сделать это, установив свойство source объекта Image в объект WriteableBitmap? Я предполагаю, что политика кэширования также не должна использоваться в объекте WrietableBitmap (так что изменения отражаются в графическом интерфейсе). – filipcampeanu

+0

Я не задал никаких свойств в элементе управления Image в XAML. Просто установите 'image.Source = bitmap', как в приведенном выше примере, и все работает. Попробуйте пример, и изображение будет обновляться при каждом перемещении мыши. Я думаю, что 'WritableBitmap' никогда не кэшируется в любом случае. – Clemens

+0

Добавил XAML ... – Clemens

Смежные вопросы