【问题标题】:Save image after modifying metadata修改元数据后保存图像
【发布时间】:2014-01-03 06:44:31
【问题描述】:

我在修改元数据后保存图像时遇到问题。 基本上,我想打开我的图像,显​​示它,修改它的 EXIF 元数据,然后保存它。

首先,我在尝试保存图像时遇到了问题,因为原始文件已被锁定(我遇到了一般性 GTI+ 错误)。在阅读了这里的一些帖子并发现问题后,我使用 using 关键字解决了锁定问题。

但问题是,如果我使用“using”,我的 Image 的 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);

你能解释一下为什么我使用“使用”时没有propertyItems,我该如何修改图像元数据而不是保存它?

【问题讨论】:

  • 它似乎有效,但是为每张图片读取/写入元数据会导致大量图片出现性能问题

标签: c# image


【解决方案1】:

您必须在阅读后保留原始图像,修改属性值,然后将其保存为新图像。显然,微软不会在内存中制作元数据的副本——只有更改。因此原始图像保持锁定以保留原始元数据。要修改图像的元数据,请保存新图像,然后用它替换旧图像(或删除并重命名)。

【讨论】:

  • 我同意——这很愚蠢。问题在于,每当 exif 数据的大小发生变化时,几乎都必须重新写入图像,因为它在文件中较早,并且具有绝对和相对偏移。要考虑的另一件事是,如果您使用 .net 重写图像,则必须小心,否则质量会降低。如果您想使用第三方库,我相信 imageMagick 会更好。
【解决方案2】:

似乎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);
    }
}

这似乎仍然比复制文件好。

【讨论】:

  • 正如我所说,这是解决问题的一种更简洁的方法,但在我的情况下效果不佳。当我要加载数百张图像时,会导致真正的性能问题。此外,需要使用此解决方案而不是 xpda 来管理副作用
  • @thibon 我明白了。不幸的是,没有想出更好的东西:) 但我很好奇,在性能方面复制内存中的属性如何比复制文件更痛苦?
  • 它并没有真正将它们复制到内存中。尽管 bmpTemp 在内存中,但元数据不在。这就是文件被锁定的原因。每个属性项至少需要一个磁盘访问权限,并且它们以相当混乱的格式保存。
  • @BartoszKP 在我的情况下,我的所有图像都是在程序启动时加载的。使用您的解决方案,对于每个文件,我将 propertyItem 复制到解锁图像中。使用另一种解决方案,我只创建/删除/重命名我想要更改属性项目的图像,并且一次一个,这对用户是透明的。我希望我的解释足够清楚
  • @thibon 是的,这是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2014-08-21
  • 2018-03-10
相关资源
最近更新 更多