2014-01-02 4 views
4

У меня проблема с сохранением изображения после изменения его метаданных. В принципе, я хочу открыть свое изображение, отобразить его, изменить его метаданные EXIF ​​и сохранить его.Сохранить изображение после изменения метаданных

Во-первых, у меня была проблема с попыткой сохранить изображение, потому что исходный файл был заблокирован (у меня была общая ошибка GTI +). Прочитав некоторые сообщения здесь и выяснив, в чем проблема, я решил проблему блокировки с использованием ключевого слова using.

Но проблема в том, что если я использую «использование», список свойств PropertyItems моего изображения пуст, и я не могу изменить свои метаданные.

Вот как я загружаю мое изображение (с различными тестами)

this.image = new Bitmap(this.path);   // this cause lock on file 

/* the following doesn't lock the file, but image.propertyItems is empty */ 

//using (var bmpTemp = new Bitmap(this.path)) 
//{ 
// this.image = new Bitmap(bmpTemp); 
//} 

Использование StreamReader или MemoryStream не помогает ...

А вот как я могу изменить и сохранить мое изображение:

PropertyItem p = this.photo.Image.GetPropertyItem(0x5090); 

p.Id = 0x320; 
p.Type = 2; // Type ASCII 
p.Len = boxTitle.Text.Length; 
p.Value = Encoding.ASCII.GetBytes(boxTitle.Text); 

this.photo.Image.SetPropertyItem(p); 
this.photo.Image.Save(this.photo.Path); 

Можете ли вы объяснить мне, почему нет свойстваItems, когда я использую «использование» и как это сделать, чтобы изменить метаданные изображения и сохранить его?

+0

Кажется, что работа, но чтение/запись метаданных для каждой картинки вызывает проблемы с большим количеством фотографий. – thibon

ответ

1

Вы должны оставить исходное изображение только после его прочтения, изменить значения свойств, а затем сохранить его как новое изображение. По-видимому, Microsoft не делает копию метаданных в памяти - только изменения. Поэтому исходное изображение остается заблокированным, чтобы сохранить исходные метаданные. Чтобы изменить метаданные изображения, вы сохраняете новое изображение, а затем заменяете его старым (или удаляете и переименовываете).

+0

Я думал об этом, но я нашел это немного экстремальным ... – thibon

+1

Согласен - это довольно глупо. Проблема в том, что изображение в значительной степени должно быть переписано всякий раз, когда изменяется размер exif-данных, поскольку он ранее в файле и имеет смещения, как абсолютные, так и относительные. Еще одна вещь, которую следует учитывать, - если вы переписываете изображение с помощью .net, вам придется быть осторожным или вы получите более низкое качество. Я считаю, что imageMagick будет лучше для этого, если вы хотите использовать стороннюю библиотеку. – xpda

1

Кажется, что Bitmap конструктор не копирует PropertyItems. Вы можете скопировать PropertyItems между изображениями, а релиз файла:

using (var bmpTemp = new Bitmap(this.path)) 
{ 
    this.image = new Bitmap(bmpTemp); 
    foreach (var pi in bmpTemp.PropertyItems) 
    { 
     this.image.SetPropertyItem(pi); 
    } 
} 

Это все еще кажется лучше, чем копирование файлов.

+0

Как я уже сказал, это более чистый способ решить проблему, но в моем случае это не работает. Когда у меня есть сотни изображений для загрузки, это вызывает реальную проблему выступлений. Более того, есть побочные эффекты, которые нужно решать с помощью этого решения, а не с xpda – thibon

+0

@thibon. Я понимаю. К сожалению, не придумали ничего лучшего :) Но мне любопытно, как копирование свойств в памяти может быть более болезненным с точки зрения производительности, чем копирование файлов? – BartoszKP

+0

На самом деле это не копирует их в памяти. Несмотря на то, что bmpTemp находится в памяти, метаданных нет. Вот почему файл заблокирован. Для каждого свойства требуется как минимум один доступ к диску, и они сохраняются в довольно грязном формате. – xpda

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