JpegBitmapEncoder.Save() 在使用元数据写入图像时抛出异常

2023-12-03

我正在构建一个 WPF 桌面应用程序来帮助我组织照片以发布到 Facebook。以下是我在新位置创建照片副本并添加标题(EXIF + IPTC + XMP)的代码:

    private void SaveImageAs(string currPath, string newPath, bool setCaption = false, string captionToSet = "")
    {
        System.IO.FileStream stream = new System.IO.FileStream(currPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        JpegBitmapDecoder decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None);
        BitmapFrame bitmapFrame = decoder.Frames[0];
        BitmapMetadata metadata = bitmapFrame.Metadata.Clone() as BitmapMetadata;
        stream.Close();

        if (setCaption)
        {
            // if we want to set the caption, do it in EXIF, IPTC, and XMP

            metadata.SetQuery("/app1/ifd/{uint=270}", captionToSet);
            metadata.SetQuery("/app13/irb/8bimiptc/iptc/Caption", captionToSet);
            metadata.SetQuery("/xmp/dc:description/x-default", captionToSet);
        }

        MemoryStream memstream = new MemoryStream();   // create temp storage in memory
        JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts));
        encoder.Save(memstream);   // save in memory
        stream.Close();

        stream = new FileStream(newPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
        memstream.Seek(0, System.IO.SeekOrigin.Begin);    // go to stream start
        byte[] bytes = new byte[memstream.Length + 1];
        memstream.Read(bytes, 0, (int)memstream.Length);
        stream.Write(bytes, 0, bytes.Length);
        stream.Close();
        memstream.Close();
    }

运行该程序,我得到一个“COMException was unhandled”异常,突出显示了这一行:

encoder.Save(memstream);

类型为“System.Runtime.InteropServices.COMException”的未处理异常发生在 演示核心.dll

附加信息:句柄无效。 (HRESULT 异常:0x80070006 (E_HANDLE))

I saw here这可能是由于线程问题造成的,因此我没有直接从应用程序调用 SaveImageAs,而是添加了以下内容,但没有效果:

        private void _SaveImageAs(string currPath, string newPath, bool setCaption = false, string captionToSet = "")
    {
        Thread saveThread = new Thread(() => SaveImageAs(currPath, newPath, setCaption, captionToSet));
        saveThread.SetApartmentState(ApartmentState.STA);
        saveThread.IsBackground = false;
        saveThread.Start();
    }

我还尝试将 MemoryStream 替换为 FileStream 创建本地临时文件 - 这没有改变任何内容:

FileStream memstream = new FileStream(System.IO.Path.GetDirectoryName(newPath) + @"\" + "temp.jpg", System.IO.FileMode.OpenOrCreate);

有任何想法吗?


您的代码中有一些错误。

  1. 源流必须保持打开状态,直到 BitmapFrame 写入目标流。

  2. 来自 BitmapDecoder 的 BitmapFrame 的图像元数据是只读的。当您想要修改元数据时,必须从原始 BitmapFrame 创建一个新的 BitmapFrame。

  3. 第三个查询似乎已损坏。异常显示“找不到属性”。

这段代码对我有用:

public static void SaveImageAs(string sourcePath, string targetPath, string caption)
{
    using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        var decoder = new JpegBitmapDecoder(sourceStream, BitmapCreateOptions.None, BitmapCacheOption.None);
        var frame = decoder.Frames[0];

        if (!string.IsNullOrWhiteSpace(caption))
        {
            frame = BitmapFrame.Create(frame);
            var metadata = (BitmapMetadata)frame.Metadata;

            metadata.SetQuery("/app1/ifd/{uint=270}", caption);
            metadata.SetQuery("/app13/irb/8bimiptc/iptc/Caption", caption);
            //metadata.SetQuery("/xmp/dc:description/x-default", caption);
        }

        var encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(frame);

        using (var targetStream = new FileStream(targetPath, FileMode.Create))
        {
            encoder.Save(targetStream);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JpegBitmapEncoder.Save() 在使用元数据写入图像时抛出异常 的相关文章

  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 有什么工具可以说明每种方法运行需要多长时间?

    我的程序的某些部分速度很慢 我想知道是否有我可以使用的工具 例如它可以告诉我可以运行 methodA 花了 100ms 等等 或者类似的有用信息 如果您使用的是 Visual Studio Team System 性能工具 中有一个内置分析
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • gdb 在 docker 上立即退出“进程已完成,退出代码 1”或 lldb“数据包返回错误 8”。另外:如何在 docker 中允许进行 C++ 调试

    这花了我一整天的时间才找到 所以我将其发布以供将来参考 我正在 docker 镜像上开发 C 我正在使用克利翁 我的代码是在调试模式下编译的 并且在运行模式下运行良好 但是当尝试调试时 进程会立即退出 并显示非常丰富的信息 Process
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • “MyClass”的类型初始值设定项引发异常

    以下是我的Windows服务代码 当我调试代码时 我收到错误 异常 CSMessageUtility CSDetails 的类型初始值设定项引发异常 using System using System Collections Generic
  • std::bind 重载解析

    下面的代码工作正常 include
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式

随机推荐

  • Django:通过查询计算列值的总和

    我有一个模型 class ItemPrice models Model price models DecimalField max digits 8 decimal places 2 我尝试用这个来计算总和price在此查询集中 items
  • 两个卷积层之间的互连

    我有一个关于 CNN 中两个卷积层之间互连的问题 例如假设我有这样的架构 输入 28 28 conv1 3 x 3 滤波器 编号 过滤器数量 16 conv2 3 x 3 滤波器 编号 过滤器数量 32 假设图像尺寸没有减小 经过 conv
  • 值传递和 std::move 相对于引用传递的优点

    我现在正在学习C 尽量避免养成坏习惯 据我了解 clang tidy包含许多 最佳实践 我尝试尽可能地坚持它们 尽管我不一定理解why它们还被认为是好的 但我不确定我是否理解这里推荐的内容 我使用了教程中的此类 class Creature
  • 如何使用 Mongoose 删除数据库?

    我正在 Node js 和 Mongoose 中准备一个数据库创建脚本 如何检查数据库是否已存在 如果存在 则使用 Mongoose 删除 删除 它 我找不到用 Mongoose 删除它的方法 没有方法可以从猫鼬中删除集合 您能做的最好的事
  • Oracle 根据出生日期和今天计算年龄

    我想在 Oracle 函数中根据出生日期计算当前年龄 我正在使用的是 Today Dob 30 12 但这并不准确 因为有些月份有 31 天 我需要以最高精度获得正确的年龄 我怎样才能做到这一点 SQL gt select trunc mo
  • 带有附加列的sql批量插入

    csv 文件包含 8 列 col1 col2 col8 文件名也包含必须插入表中的日期 如果表中的列数和 csv 文件中的列数相等 则以下查询将文件中的所有记录导入到表中 query BULK INSERT real data FROM p
  • 如何从分类分布中抽取样本

    我有一个 3D numpy 数组 其中最后一个维度中包含每个类别的概率 就像是 import numpy as np from scipy special import softmax array np random normal size
  • 在控制台显示上对齐 printf() 列并防止溢出到下一行?

    printf processid t threadid t refilling t drinking t thinking t waiting t terminated t p type t required t consumed t wa
  • 如何在循环中追加多个 pandas DataFrame?

    我已经在这个 python 问题上苦苦挣扎了一段时间 但陷入了困境 我正在循环遍历多个 csv 文件 并希望有一个数据框以每个 csv 文件中的一列作为列名称并设置 date time 的公共索引的方式附加 csv 文件 有 11 个 cs
  • RoR 3 限制用户每天发帖 2 条

    我正在寻找方法限制我的用户每天发帖次数不超过两次 并且每周发帖次数不超过 5 个 我有一个用户和帖子模型 控制器 我一直在研究这些问题 但它们并不完全是我想要的 Rails 3 1 限制用户创建的对象 如何验证 Rails 中的时间 限制用
  • Fortran if 语句中的隐式转换整数 <--> 逻辑

    我有一些遗留的 Fortran 代码 我被要求分析它们并将其翻译成现代语言 我不知道过去使用哪个编译器来编译代码 所以现在我尝试使用 gfortran 来编译它 该代码包含这样的语句 导致 gfortran 抱怨 program test
  • 将元素形成 numpy 数组作为另外两个 numpy 数组时出现广播错误

    我正在尝试生成一个 numpy 数组 其元素作为另外两个 numpy 数组 如下所示 W1b1 np zeros 256 161 W2b2 np zeros 256 257 Wx np array W1b1 W2b2 dtype np ob
  • 具有空布局的 JPanel 类不显示组件

    因此 我创建了一个 CustomPanel 类的对象 该对象创建一个带有 GridLayout 的 JPanel 和其中的标签 然后将其添加到我的 JFrame 中 它可以很好地显示标签 HELLO 但是当我将 jpanel 的布局管理器更
  • 带有单位的 POSIXct 的差异,就像 difftime 一样

    我有一个 POSIXct data 向量 想要计算连续元素之间的差异 就像通过diff e g burst lt as POSIXct c 2016 11 07 17 20 52 2016 11 07 16 21 52 2016 11 07
  • constexpr 和 RTTI

    我想做这样的事情 template
  • 如何在编译时显示 #define 的值?

    我试图找出我的代码认为它使用的 Boost 版本 我想做这样的事情 error BOOST VERSION 但预处理器不会扩展 BOOST VERSION 我知道我可以在程序运行时将其打印出来 并且我知道我可以查看预处理器的输出来找到答案
  • C# 中用户定义的编译器警告或错误[重复]

    这个问题在这里已经有答案了 是否可以让某些代码让编译器生成编译警告或错误 也许有属性 有了第一个答案和一些评论 我意识到我的问题并不像我预期和希望的那么清晰 我道歉 希望所有贡献者仍然和我们在一起 所以我更倾向于内部 DSL S Th 喜欢
  • 以固定的迭代次数迭代 for 循环

    我在 ant 脚本中使用 ant contrib 库 但我不知道如何制作固定金额 使用 foreach 标签的循环 我所说的固定迭代次数并不是指某些硬编码值 而是从命令行提供的 ant 属性 以下代码创建一个具有固定次数 5 次迭代的循环
  • 来自 iframe 本身的 iframe 上的 div

    我有一个 div 包含在外部 html 的 iframe 内 基于 html 的 上下文菜单 需要位于 iframe 之上 但上下文菜单的 html 代码位于 iframe 本身中 首选纯 CSS 解决方案 iframe 的内容无法显示在
  • JpegBitmapEncoder.Save() 在使用元数据写入图像时抛出异常

    我正在构建一个 WPF 桌面应用程序来帮助我组织照片以发布到 Facebook 以下是我在新位置创建照片副本并添加标题 EXIF IPTC XMP 的代码 private void SaveImageAs string currPath s