2012-09-11 3 views
1

C# - Создание обновления BackgroundImage в режиме реального времени во время редактирования в других программах

первый я сделал приложение рабочего стола AIR с перетаскивания функций Просмотр фрагментов изображения, но из-за некоторых проблем, я имею попытался сделать то же самое в C#. как вы думаете, лучший выбор? (Я знаю, для этой маленькой производительности програмного не вопрос, но я имею в виду dufficulty и сложность обоих)

я строил простой TileViewer, поэтому изображение выбрано в OpenFileDialog и установить в качестве черепичной BackgroundImage формы.

Моя проблема:

  1. Я использую таймер (интервал = 500), чтобы перезагрузить изображение, так что если я изменить изображение в фотошопе, то TileViewer будет автоматически перезагружать обновленное изображение (как я сохраняю его в фотошопе).

    НО проблема в том, что фотошоп оленья кожа имеет premissions сделать это, Потому что образ открыт в другой программе (мой TileViewer)

  2. Я снял таймер и сделал кнопку обновления вместо этого. но та же проблема.

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

Мой код:

private string FileName; 

    public Form1() { 
     InitializeComponent(); 

     FileName = ""; 
    } 

    // OPEN FILE btn 
    private void button1_Click(object sender, EventArgs e) { 
     openFileDialog1.Filter = "PNG Files (*.png)|*.png|JPG Files (*.jpg)|*.jpg"; 
     if(openFileDialog1.ShowDialog() == DialogResult.OK) { 
      button2.Enabled = true; 
      FileName = openFileDialog1.FileName; 
      setImage(); 
     } 
    } 

    // REFRESH btn 
    private void button2_Click(object sender, EventArgs e) { 
     if(FileName != "") { 
      setImage(); 
     } 
    } 

    private void setImage() { 
     Bitmap tempImg = new Bitmap(FileName); 
     Rectangle rect = new Rectangle(0, 0, 100, 100); 
     PixelFormat format = tempImg.PixelFormat; 

     this.BackgroundImage = new Bitmap(FileName).Clone(rect, format); 
    } 

Так, ребята, если у вас есть какие-либо предложения или решения, дайте мне знать.

+1

Это не отвечает на ваш вопрос, но вместо таймера вы можете посмотреть [FileSystemWatcher] (http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher. aspx). –

+0

Да, я также подумал об использовании этого, но прежде всего хочу исправить проблему препровождения ^^ – Ace

ответ

2

Update 2:

Другой вопрос был в строке Прямоугольник Прямоугольник = новый прямоугольник (0, 0, 100, 100);

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

Вот почему исполняющим говорит, что вы из памяти !! (Он сделал для меня, и у меня есть монстр машина с 18 ГБ)

Update:

вы как раз утечка объектов, следовательно, из-за исключением памяти

(Haans уже предупреждал вас об утилизации объектов Thats.)

Попробуйте следующий код

private string FileName; 

public Form1() 
{ 
    InitializeComponent(); 

    FileName = ""; 
} 

// OPEN FILE btn 
private void button1_Click(object sender, EventArgs e) 
{ 
    openFileDialog1.Filter = "PNG Files (*.png)|*.png|JPG Files (*.jpg)|*.jpg"; 
    if (openFileDialog1.ShowDialog() == DialogResult.OK) 
    { 

     FileName = openFileDialog1.FileName; 
     setImage(); 
    } 
} 

// REFRESH btn 
private void button2_Click(object sender, EventArgs e) 
{ 
    if (FileName != "") 
    { 
     setImage(); 
    } 
} 

private void setImage() 
{ 
Stream str=new FileStream(FileName,FileMode.Open, FileAccess.Read,FileShare.Read); 
     Bitmap tempImg= new Bitmap(Bitmap.FromStream(str)); 
     str.Close(); 
     using(tempImg) 
     { 


     Rectangle rect = new Rectangle(0, 0, tempImg.Width, tempImg.Height); 

     PixelFormat format = tempImg.PixelFormat; 

     this.BackgroundImage = new Bitmap(tempImg); 

     } 
} 

OLD Ответ

Как Джейсон сказал

вам, возможно, придется сделать somethinglike это в методе setimage

Stream str = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); 
    this.BackgroundImage = Bitmap.FromStream(str); 
str.Close(); 

Обратите внимание, что вы «лучше закрыть любой поток, который вы откроете после его использования.

вместо

частного недействительного setImage() {
Растрового tempImg = новый Bitmap (имя_файл); < --- Прямоугольник прямоугольный = новый прямоугольник (0, 0, 100, 100);
Формат PixelFormat = tempImg.PixelFormat;

this.BackgroundImage = new Bitmap(FileName).Clone(rect, format); 
} 
+0

Я думаю, что это решение отлично работает для меня, но я не мог его протестировать, из памяти ", которую я получаю, когда я нажимаю« открывать »и выбираю изображение ..., это все еще просто 32-х 32-пиксельное изображение Oo, и он работал нормально, пока я не пробовал испортить код:/it targetProgramm.cs -> 'Application.Run (новый Form1()); – Ace

+0

@ace см. Мой обновленный ответ на вопрос «из памяти»! –

+0

это то же самое! визуальная студия цели на последней строке, говорящей «недостаточно памяти», делает это, если я использую Visual Studio внутри VMware? (назначил 2gb баранов на vm) , что действительно странно, потому что это всего лишь очень маленькая картинка:/ – Ace

0

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

альтернативой было бы скопировать файл, а затем открыть копию.

Смотрите, если вы CNA запустить следующий код в то время как Photoshop имеет открытый файл

FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read); 
+0

, если бы я сделал копию, она не обновлялась, потому что я редактирую оригинал, а также сохраняю оригинал , разве я? проблема не в том, что я не могу ее открыть, пока работает другая программа, проблема в том, что я не могу переопределить ее, пока она загружается в мою программу. Что значит «полезная нагрузка»? (sry my englisch не самый лучший), я подумал об использовании его, как я использую средство чтения потока для текстовых файлов, например 1. откройте его, 2. прочитайте его и запишите его как bg img 3. закройте его и повторите процесс с помощью таймер. does streamReader работает только с текстовыми файлами? или есть программа для чтения потоков для img? (filestream) – Ace

+0

как использовать FileStream для установки этого.BackgroundImage = Ace

+0

@ace см. мой ответ на использование Filestream на Backgroundimage –

2

Метод Bitmap.Clone() не делает то, что вы надеетесь. Он создает «мелкую» копию. Вы получаете новый объект Bitmap, но он все еще использует базовый буфер пикселей. Включая файл с отображением памяти, который использует GDI +, чтобы сохранить данные пикселя из файла подкачки. Это, в свою очередь, блокирует файл.

Вам нужно сделать «глубокую» копию, сделать это с помощью конструктора Bitmap (Image). Как это:

private void setImage() { 
    using (var tempImg = new Bitmap(FileName)) { 
     this.BackgroundImage = new Bitmap(tempImg); 
    } 
} 

используя заявление обеспечивает исходное изображение расположено и замок освобождается.