C# 图像大小调整 - 丢失 EXIF

2023-11-22

是的,是的...我看过与此问题相关的其他帖子,是的...我已经用谷歌搜索过它。

但到目前为止,我还没有达到我需要的结果。

我正在加载以 300 dpi 拍摄的大图像,并且需要调整其大小。

我知道...我知道... dpi 是相对的,并不重要...重要的是像素尺寸:

DPI 本质上是打印图像时而不是在屏幕上查看图像时对应于一英寸的像素数。因此,通过增加图像的 DPI,您不会增加屏幕上图像的尺寸。您只会提高打印质量。

尽管存储在图像 EXIF 中的 DPI 信息有些无用,但它给我带来了问题。

我正在调整大小的图像是丢失原来的exif信息,包括水平和垂直分辨率(dpi),因此以默认值 96 dpi 保存。可能的原因是只有 JPEG 和其他格式可以保存元数据信息。

最终图像结果应如下所示:275x375 at 300dpi 相反,看起来像这样:275x375 at 96dpi

您可以说它们是相同的,我同意,但我们有一个用于加载这些图像的 corel 绘图脚本,并且由于此 dpi 信息不同,因此它在文档上以不同的大小放置它。

这是我用来调整大小的:

public System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
    {
        Bitmap result = new Bitmap(width, height);

        // set the resolutions the same to avoid cropping due to resolution differences
        result.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        //use a graphics object to draw the resized image into the bitmap
        using (Graphics graphics = Graphics.FromImage(result))
        {
            //set the resize quality modes to high quality
            graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            //draw the image into the target bitmap
            graphics.DrawImage(image, 0, 0, result.Width, result.Height);
        }

        //return the resulting bitmap
        return result;
    }

这样可以很好地完成工作,但会丢失 EXIF 信息。

将 SetResolution 设置为 SetResolution(300, 300) 不起作用!

我研究了读取和更改图像的 EXIF 信息,并且尝试过:

public void setImageDpi(string Filename, string NewRes)
    {
        Image Pic;
        PropertyItem[] PropertyItems;
        byte[] bDescription = new Byte[NewRes.Length];
        int i;
        string FilenameTemp;
        System.Drawing.Imaging.Encoder Enc = System.Drawing.Imaging.Encoder.Transformation;
        EncoderParameters EncParms = new EncoderParameters(1);
        EncoderParameter EncParm;
        ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg");

        // copy description into byte array
        for (i = 0; i < NewRes.Length; i++) bDescription[i] = (byte)NewRes[i];

        // load the image to change
        Pic = Image.FromFile(Filename);

        foreach (PropertyItem item in Pic.PropertyItems)
        {
            if (item.Id == 282 || item.Id == 283)
            {
                PropertyItem myProperty = item;
                myProperty.Value = bDescription;
                myProperty.Type = 2;
                myProperty.Len = NewRes.Length;
                Pic.SetPropertyItem(item);
                Console.WriteLine(item.Type);
            }
        }

        // we cannot store in the same image, so use a temporary image instead
        FilenameTemp = Filename + ".temp";

        // for lossless rewriting must rotate the image by 90 degrees!
        EncParm = new EncoderParameter(Enc, (long)EncoderValue.TransformRotate90);
        EncParms.Param[0] = EncParm;

        // now write the rotated image with new description
        Pic.Save(FilenameTemp, CodecInfo, EncParms);

        // for computers with low memory and large pictures: release memory now
        Pic.Dispose();
        Pic = null;
        GC.Collect();

        // delete the original file, will be replaced later
        System.IO.File.Delete(Filename);

        // now must rotate back the written picture
        Pic = Image.FromFile(FilenameTemp);
        EncParm = new EncoderParameter(Enc, (long)EncoderValue.TransformRotate270);
        EncParms.Param[0] = EncParm;
        Pic.Save(Filename, CodecInfo, EncParms);

        // release memory now
        Pic.Dispose();
        Pic = null;
        GC.Collect();

        // delete the temporary picture
        System.IO.File.Delete(FilenameTemp);
    }

那也没用。

我尝试在稍后的过程中查找并更改 DPI(282 和 283)的 EXIF 信息,如下所示:

        Encoding _Encoding = Encoding.UTF8;
        Image theImage = Image.FromFile("somepath");

        PropertyItem propItem282 = theImage.GetPropertyItem(282);
        propItem282.Value = _Encoding.GetBytes("300" + '\0');
        theImage.SetPropertyItem(propItem282);

        PropertyItem propItem283 = theImage.GetPropertyItem(283);
        propItem283.Value = _Encoding.GetBytes("300" + '\0');
        theImage.SetPropertyItem(propItem283);

        theImage.Save("somepath");

但程序崩溃了找不到财产。

如果该属性不存在,显然我无法添加它:

PropertyItem 不打算用作独立对象。 PropertyItem 对象旨在由派生自 Image 的类使用。 PropertyItem 对象用于检索和更改现有图像文件的元数据,而不是创建元数据。因此,PropertyItem 类没有定义的 Public 构造函数,并且您无法创建 PropertyItem 对象的实例。

我陷入困境...我所需要的只是调整大小的图像,并将 dpi 设置为 300,它不应该那么难。

非常感谢任何帮助。谢谢


以下代码对我有用:

const string InputFileName = "test_input.jpg";
const string OutputFileName = "test_output.jpg";
var newSize = new Size(640, 480);

using (var bmpInput = Image.FromFile(InputFileName))
{
    using (var bmpOutput = new Bitmap(bmpInput, newSize))
    {
        foreach (var id in bmpInput.PropertyIdList)
            bmpOutput.SetPropertyItem(bmpInput.GetPropertyItem(id));
        bmpOutput.SetResolution(300.0f, 300.0f);
        bmpOutput.Save(OutputFileName, ImageFormat.Jpeg);
    }
}

当我检查输出文件时,我可以看到 EXIF 数据,并且 DPI 已更改为 300。

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

C# 图像大小调整 - 丢失 EXIF 的相关文章

  • .Net Core 中 String 默认不可序列化吗?

    我正在查看其他的 Fortify 静态分析安全测试 SAST 扫描报告 以识别和抑制误报 应用程序框架是C NET Core SAST 报告部分内容如下 Method1 在第 111 行将不可序列化的对象存储为 HttpSessionSta
  • 在 C# 中实例化 python 类

    我已经用 python 编写了一个类 我想通过 IronPython 将其包装到 net 程序集中 并在 C 应用程序中实例化 我已将该类迁移到 IronPython 创建了一个库程序集并引用了它 现在 我如何真正获得该类的实例 该类看起来
  • Ruby 解释器嵌入到 C 代码中

    我只是尝试书中的一个简单例子 我有一个 sum rb 文件 class Summer def sum max raise Invalid maximum max if max lt 0 max max max 2 end end 还有一个
  • Rx Framework:在超时时执行操作,而不中断原始可观察序列

    给定一个可观察的源 通过轮询低级设备的 变化 状态生成 observable source metacode IObservable
  • 模拟 EF core dbcontext 和 dbset

    我正在使用 ASP NET Core 2 2 EF Core 和 MOQ 当我运行测试时 我收到此错误 消息 System NotSupportedException 非虚拟 可在 VB 中重写 成员上的设置无效 x gt x Movies
  • 混合 VS2012 平台工具集

    我们正在从 VS2005 切换到 VS2012 update 2 我们正在构建大量 主要是控制台 本机 C 无 MFC ATL 可执行文件 它们使用几个常见的静态链接库 这些可执行文件主要在 Win7 计算机上运行 但有些也部署在较旧的 X
  • 是否有更好(更简单)的方法来获取特定域 SID?

    我被指派修改 WinForms 应用程序 主要检查登录用户是否属于特定域 这是我到目前为止所想出的 byte domainSid var directoryContext new DirectoryContext DirectoryCont
  • 如何使用 ASP.NET MVC 4.0 DonutOutputCache VaryByCustom 使缓存失效

    我正在为我的 ASP NET 应用程序使用 DevTrends MvcDonutCaching 包 它工作得很好 我目前遇到的一个问题是使我为子操作设置的 VaryByCustom 缓存无效 这是我用于 VaryByCustom 设置的一些
  • 如何从c++调用python

    我是Python新手 我尝试像这样从 C 调用 python 脚本 在 Raspberry Pi 中 std string pythonCommand python Callee py a b int res system pythonCo
  • 当应用程序未聚焦时监听按键

    我有一个应用程序 C 4 0 WPF 它是隐藏的 可以通过单击系统托盘图标或我创建的其他框架 停靠在左侧和最上面的小框架 来显示 My customer wants to add a new way to display the appli
  • C#中如何将委托转换为对象?

    我正在使用反射类来调用其他 dll 上的一些方法 方法的参数之一是委托类型 我想通过使用反射来调用这个方法 所以我需要将函数参数作为对象数组传递 但我找不到任何关于 如何将委托转换为对象 提前致谢 委托是一个对象 只需像平常一样创建预期的委
  • 从 Linq 的列表中选择多个字段

    在 ASP NET C 中 我有一个结构 public struct Data public int item1 public int item2 public int category id public string category
  • 位图太大 as3

    在AS3中 我从zip文件加载png nochump的zip库通过ByteArray到Loader png 的宽度最大可达 45k 像素 但高度仅为 120 像素 这在 Flash 中产生了一个问题 因为图像的宽度只能约为 8000 像素
  • 在 C# 4.0 中,是否可以从泛型类型参数派生类?

    我一直在尝试这个 但我似乎无法弄清楚 我想做这个 public abstract class SingletonType
  • Facebook Graph API“/userid/feed”返回空白

    我正在使用 Facebook C SDK 但似乎无法使用 Graph API 获取反馈数据 我已从用户那里获得了以下扩展权限 范围 离线访问 publish stream publish checkins create event read
  • 如何在OpenGL中像这样绘制连接的带状线

    我想用以下方式绘制一系列连接线 GL LINE STRIP 我尝试过自己编写代码 但没有得到想要的结果 所以我来到这里 帮助我找出我错在哪里 这里我只给出我的draw 函数 glBegin GL LINE STRIP glVertex2f
  • C中的pipe()和fork()

    我需要创建两个子进程 一个子进程需要运行命令 ls al 并将其输出重定向到下一个子进程的输入 而下一个子进程又将对其输入数据运行命令 sort r n k 5 最后 父进程需要读取该数据 已排序的数据 并将其显示在终端中 终端中的最终结果
  • Android NDK - 仅用 C/C++ 编写

    有没有一种可能的方法可以使用 C C 编写整个 NDK 应用程序 而无需像 hello jni 示例项目 HelloJni java 中那样的 Java 入门 类 以某种方式创建一个 HelloJni c 来执行相同的操作 从 Androi
  • 为什么没有参数的函数(与实际函数定义相比)可以编译?

    我刚刚看到某人的 C 代码 我很困惑为什么要编译它 有两点我不明白 The 函数原型与实际函数定义相比没有参数 中的参数函数定义没有类型 include
  • 从哪里开始阅读 SQLite 源代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想了解sqlite是如何实现的 并且 想阅读源代码 我已经下载了源代码 我应该开始查看代码的哪一部分 SQLite文档页 http

随机推荐

  • Coredata 错误“数据:<故障>”

    我尝试使用以下代码从 CoreData 中提取数据 NSFetchRequest request NSFetchRequest alloc init request entity NSEntityDescription entityForN
  • 哪些(有)语言只能通过引用传递?

    我想知道 是否有语言使用only传递引用作为他们的评估策略 我不知道什么是 评估策略 但 Perl 子例程调用只是通过引用传递 sub change 0 10 x 5 change x print x prints 10 change 0
  • 为什么 JsonResult 会产生 500 内部服务器错误?

    我正在尝试从 Microsoft SQL Server 数据库中检索值 它是一个可为空的 位 要检索的代码 HttpGet public JsonResult WishesVisit int firmaid SessionExtension
  • Arm架构中的域意味着什么

    当我在 Cortex A9 MPCore 中调试 MMU 时 我总是看到域访问控制寄存器 但是 域是什么意思 最多 16 个域 任何人都可以给我一个链接来解释这一点 TL 博士DACR不仅减少了上下文切换的代码路径 还可以加快上下文切换发生
  • 捕获由 Makefile 启动的后台进程的 PID

    我有一个启动 Django Web 服务器的 Makefile 我希望服务器在后台启动 并将 PID 保存到文件中 我的食谱是这样的 run venv PYTHON APP manage py runserver 80 直观地说 要使进程后
  • 如何验证由 createCustomToken() 创建的自定义 Firebase 身份验证令牌

    我通过 createCustomToken 创建了自定义身份验证令牌 请参阅https firebase google com docs auth admin create custom tokens 但后来当我尝试通过 verifyIdT
  • 从 iOS 将数据发送到 PHP 脚本

    我正在尝试以下代码 该代码在用户在字段 标题 描述 城市 中输入数据然后单击 保存 后执行 IBAction saveDataAction id sender NSString lEventTitle NSString stringWith
  • 使用 jquery 粘性标题

    我想创建多个两个粘性标题 就像在该网站中一样 http www trendyol com Kappa ButikDetay 8690当您向下滚动时 第一个标题与第二个粘性元素结合在一起 说完 两人一起往下走 我该怎么做 感谢提前支持 实现这
  • 将数据表导出到 Excel 文件

    我有一个包含 30 多列和 6500 多行的 DataTable 我需要将整个 DataTable 值转储到 Excel 文件中 任何人都可以帮助编写 C 代码吗 我需要每个列值都在一个单元格中 准确地说 我需要 Excel 文件中数据表的
  • Mongo ObjectID:在野外使用安全吗?

    我正在设计一个与 MongoDB 交互的 API 现在的问题是 如果是safe使用原始 ObjectID 来查询对象等 直接使用 OID 时 例如在查询中 是否会出现任何安全问题 或者我应该在它们离开我的服务器环境之前对其进行加密 解密 查
  • 如何在 iPhone x 中设置安全区域布局

    我正在开发 Xamarin 表单应用程序 我的应用程序似乎在顶部设置了安全区域 但需要忽略它 当前场景 例外场景 我已经用谷歌搜索了这个问题并得到了下面的链接 按照下面的链接中提到的方式进行了尝试 但没有任何效果 https forums
  • 寻找积极维护的 php 矩阵数学库

    有谁知道我在哪里可以找到仍在积极维护的 PHP 矩阵数学库 我需要能够执行基本的矩阵运算 例如归约 转置 包括非方阵 求逆 行列式等 这个问题过去被问过 然后没有答案就关闭了 现在我需要同一问题的答案 请参阅相关问题的链接 PHP 中的矩阵
  • 错误 - “gem install Rails” - libxml2 丢失

    我一直在研究 Rails 安装说明 http railsapps github io installrubyonrails mac html 一切都很好 直到我到达gem install rails部分下新轨道应用 当我运行时 我发现 li
  • Firebase 云消息传递 (FCM) - HTTP V1 API 还是旧版 HTTP API?

    我们的目标是将通知发送至设备组从我们的后端 并且只有从服务器端才能知道哪个设备应该接收通知 我们已经对 AppCenter 进行了一些尝试 因为我们主要使用 Xamarin iOS Android Forms 但现在我们怀疑直接使用 Fir
  • 获取远程注册表值

    我有下面的脚本 我希望它发送到多个服务器并获取注册表的值 不幸的是 它目前只是回发我正在运行脚本的计算机的本地注册表值 如何让脚本针对远程注册表运行 SCRIPT clear ErrorActionPreference silentlyco
  • 与 rpath 的动态链接在 Ubuntu 17.10 下不起作用

    我构建了一个 R 包 它使用 Rcpp 并链接到第三方共享对象 libbarraopt so 它还链接到其他共享对象 例如liboptsrvr so在它自己的目录中 为了确保它能够找到它链接的那些共享对象 我将以下变量放入 Renviron
  • 如何使用委托将数据从自定义单元格传递到父视图中的标签

    我已经弄清楚如何在其他情况下在视图与代表之间传递数据 但这一个难倒了我 在此示例中 我尝试使用委托模式将按下按钮产生的数据发送到标签 但没有成功 我的猜测是 我在这里遗漏了一些基本的东西 并且我还没有找到任何以这种方式处理代表的例子 Vie
  • 将新行数据添加到gridview asp.net c#

    我用这段代码创建了一个类 public class Customer public Customer public Customer Customer cust ID cust ID Name cust Name FatherName cu
  • 删除 HTML 或 ASPX 扩展

    在托管的 IIS7 环境中 我正在寻找使用无扩展名文件名的最简单方法 只是我有以下页面 index html or aspx gt example com gallery html gt example com gallery videos
  • C# 图像大小调整 - 丢失 EXIF

    是的 是的 我看过与此问题相关的其他帖子 是的 我已经用谷歌搜索过它 但到目前为止 我还没有达到我需要的结果 我正在加载以 300 dpi 拍摄的大图像 并且需要调整其大小 我知道 我知道 dpi 是相对的 并不重要 重要的是像素尺寸 DP