图像调整大小性能:System.Drawing 与 System.Windows.Media

2024-04-26

我遇到了需要调整大量图像大小的情况。这些图像目前在文件系统上存储为 .jpg 文件,但我希望稍后在项目中内存中只有 byte[] 。源图像大小是可变的,但输出应该是 3 个不同的预定大小。应保留长宽比,用空白填充原始图像(即,将调整非常高的图像大小以适合方形目标图像大小,左侧和右侧有大面积的白色)。

我最初构建了针对 .NET 2.0 的项目,并使用 System.Drawing 类来执行加载/调整大小/保存。相关代码包括:

original = Image.FromFile(inputFile); //NOTE: Reused for each of the 3 target sizes
Bitmap resized = new Bitmap(size, size);
//Draw the image to a new image of the intended size
Graphics g = Graphics.FromImage(resized);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.Clear(Color.White);
g.DrawImage(original, center - width / 2f, center - height / 2f, width, height);
g.Dispose();
//Save the new image to the output path
resized.Save(outputFile, ImageFormat.Jpeg);

我想将此项目移植到 .NET 3.5,因此尝试使用 System.Windows.Media 类来执行相同的功能。我让它工作了,但性能很糟糕;每张图像的处理时间大约延长 50 倍。绝大多数时间都花在加载图像上。相关代码包括:

BitmapImage original = new BitmapImage(); //Again, reused for each of the 3 target sizes
original.BeginInit();
original.StreamSource = new MemoryStream(imageData); //imageData is a byte[] of the data loaded from a FileStream
original.CreateOptions = BitmapCreateOptions.None;
original.CacheOption = BitmapCacheOption.Default;
original.EndInit(); //Here's where the vast majority of the time is spent
original.Freeze();

// Target Rect for the resize operation
Rect rect = new Rect(center - width / 2d, center - height / 2d, width, height);

// Create a DrawingVisual/Context to render with
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
    drawingContext.DrawImage(original, rect);
}

// Use RenderTargetBitmap to resize the original image
RenderTargetBitmap resizedImage = new RenderTargetBitmap(
    size, size,                         // Resized dimensions
    96, 96,                             // Default DPI values
    PixelFormats.Default);              // Default pixel format
resizedImage.Render(drawingVisual);

// Encode the image using the original format and save the modified image
SaveImageData(resizedImage, outputFile);

我在这里做错了什么,花了这么多时间吗?我尝试过仅在 BitmapImage 上使用采用 URI 的构造函数,但也存在同样的性能问题。以前有人做过类似的事情,知道是否有更注重性能的方法来做到这一点?或者我仍然需要使用 System.Drawing 吗?谢谢!


输入完所有内容后,我突然想到可以从 MS 加载 System.Windows.Media 类的符号,并单步执行速度较慢的地方。立即找到了原因,并解决了。输入图像使用颜色配置文件保存,并且它尝试加载每个图像的颜色配置文件(从文件系统)。通过在上面的代码中从 BitmapCreateOptions.None 切换到 BitmapCreateOptions.IgnoreColorProfile,它不再这样做,并且执行速度与 System.Drawing 一样快。

希望这可以帮助遇到此问题的其他人!

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

图像调整大小性能:System.Drawing 与 System.Windows.Media 的相关文章

  • __libc_start_main 发生了什么?

    我真的很想理解从高级代码到可执行文件的步骤 但是遇到了一些困难 我写了一个空的int main C 文件并尝试通过以下方式破译反汇编objdump d 这是发生的事情 in start 设置对齐方式 将参数压入堆栈 调用 libc star
  • 我可以在 WinRT / Windows 8 Store 应用程序中绑定 DynamicObject

    我有以下代码 public class MyClass DynamicObject INotifyPropertyChanged Dictionary
  • 如何使构造函数只能由基类访问?

    如果我想要一个只能从子类访问的构造函数 我可以使用protected构造函数中的关键字 现在我想要相反的 我的子类应该有一个构造函数 该构造函数可以由其基类访问 但不能从任何其他类访问 这可能吗 这是我当前的代码 问题是子类有一个公共构造函
  • 相当于一个允许重复键的排序字典

    我需要一个数据结构 可以通过与对象关联的浮动键对对象进行排序 从低到低的在前 问题是键代表成本 所以经常有重复 我不关心这一点 因为如果两个具有相同的成本 我只会抓住第一个 因为它没有区别 问题是编译器抱怨 是否有一种数据结构的行为方式相同
  • EntityFramework:“参数值超出范围。”

    我在 EntityFramework 模型优先 中保存小数时遇到问题 在我的 EDMX 中 我声明我的属性为 Decimal 30 10 然后我尝试保存该数字 1215867935736100000 结果是 Parameter value
  • 使用工作表作为数据源的 VSTO Excel 的简单示例

    我想我遇到了 最简单的答案是最难找到的答案 的情况 而且我还没有遇到过任何搜索能够以直接的方式给我这个答案 这是为了Excel 2010 and VS 2010在现有 VSTO C 项目中 我有一个 Excel 工作表 其中包含 4 列数据
  • 通知另一个线程数据可用的最快方法是什么?有什么替代旋转的方法吗?

    我的一个线程将数据写入循环缓冲区 另一个线程需要尽快处理该数据 我本来想写这么简单的spin 伪代码 while true while a i do nothing just keep checking over and over proc
  • 如何测试 PARTIAL 视图在 C# ASP .NET MVC 中呈现

    我有一个视图 它内部有部分视图渲染 div class partialViewDiv Html RenderPartial partial Model SomeModelProperty div 和一个返回此视图的控制器 public Ac
  • g++.exe 和 x86_64-w64-mingw32-g++.exe 有什么区别?

    同样的问题也适用于 gcc ar 等 在 Code Blocks 中将工具链可执行文件从 Something exe 更改为 x86 64 w64 mingw32 something exe 时 代码仍然可以完美编译 此外 32 位和 64
  • 类模板的可变参数构造函数模板的特化

    这是一个带有可变参数构造函数的类 它专门用于从临时对象进行复制和移动 template
  • FileStream - “不支持给定路径的格式”

    我正在尝试使用EPPlus http epplus codeplex com 在我们的 LAN 上保存电子表格 我正在使用一个FileStream对象执行此操作 但是每当我尝试实例化该对象时 我都会收到错误 The given path s
  • 将迭代器取消引用到临时范围时出现非指针操作数错误

    Using auto empty line auto str return str size 0 我们做得到 auto line range with first non empty ranges view drop while range
  • 如何使用 VBA 将符号/图标格式化为单元格而不使用条件格式

    我使用 VBA 代码放置条件格式以覆盖大型表格中的值 每个单元格使用 2 个公式来确定使用 3 个符号中的哪一个 我需要根据列使用不同的单元格检查每个单元格的值 因此据我了解 我必须将条件格式规则单独放置在每个单元格上 以确保每个单元格中的
  • .NET 查询字符串值的正则表达式

    我需要从 Url PathAndQuery 中删除任何 id SomeValue 其中 SomeValue 可以是整数或字符串 它后面可能有也可能没有另一个 符号 所以它可能是 somepage aspx cat 22 id SomeId
  • 策略模式的现实示例

    我一直在读关于OCP原理 http en wikipedia org wiki Open closed principle以及如何使用策略模式来实现这一目标 我打算尝试向几个人解释这一点 但我能想到的唯一例子是根据 订单 的状态使用不同的验
  • 在 Winforms 中,PreviewKeyDown() 从未针对任何键触发

    我最初试图让我的程序获取箭头键 上 下 左 右 的输入 但发现在 KeyDown 中这些键从未出现过 后来我发现我可以通过进入 PreviewKeyDown 函数并设置来启用箭头键 e IsInputKey true 及其周围的任何条件和逻
  • 自定义编译器警告

    在 Net 中使用 ObsoleteAtribute 时 它 会向您发出编译器警告 告诉您该对象 方法 属性已过时 应使用其他内容 我目前正在从事一个需要大量重构前员工代码的项目 我想编写一个自定义属性 可用于标记方法或属性 这些方法或属性
  • 接口作为类型约束和接口作为参数之间的区别?

    如果我想创建一个采用实例的方法IList作为参数 或任何其他接口 但让我们使用IList作为一个例子 我可以创建一个带有类型约束的通用方法 例如 public static void Foo1
  • C/C++ 特殊 CPU 功能的使用

    我很好奇 新的编译器是否使用了新 CPU 中内置的一些额外功能 例如 MMX SSE 3DNow 所以 我的意思是 在最初的 8086 中甚至没有 FPU 所以旧的编译器甚至不能使用它 但新的编译器可以 因为 FPU 是每个新 CPU 的一
  • 如何注销多个非当前用户的会员用户?

    我正在使用属于 MVC2 默认项目一部分的 MembershipProvider 我希望能够获取用户名列表 注销用户 并在需要时销毁他们的会话 我能想到的最接近的是 foreach string userName in UserNames

随机推荐

  • 如何在 Cython 中传递指向 c 函数的指针?

    我正在尝试打电话qsort在 Cython 中使用自定义比较函数 但我不明白如何传递函数引用 首先 我有一个结构 cdef struct Pair int i j float h 比较函数排序依据h cdef int compare con
  • javascript旋转数组元素[重复]

    这个问题在这里已经有答案了 大家好 我有一个任务 我有一个数组 4 7 3 6 9 我必须创建一个像这样的数组 4 7 3 6 9 9 4 7 3 6 6 9 4 7 3 3 6 9 4 7 7 3 6 9 4 我必须编写一个程序 其中数组
  • AspectJ 加载时间编织不适用于 Spring beans

    我正在开发一个项目 该项目使用 Spring 配置的 Java 而不是 xml 风格来连接依赖项 它还具有分析逻辑 应通过 AspectJ 将其编织到所需的方法上 通过注释 设置正在运行 我可以看到我想要的包中的类正在编织 并且分析信息已从
  • 一个目录下可以有两个oozieworkflow.xml文件吗?

    一个目录下可以有两个oozieworkflow xml文件吗 如果是这样 我如何指示 oozie runner 运行哪一个 您可以有两个工作流程文件 只需为它们指定唯一的名称 然后您可以通过设置oozie wf application pa
  • Qt for Android:无法签署应用程序的发布版本

    我正在使用 Qt 5 13 和 Qt Creator 4 9 2 我可以成功构建 Android 应用程序的调试版本 但是当我尝试编译发布版本时 我得到 16 57 35 过程 opt Qt 5 13 0 android armv7 bin
  • iOS Voice Over 和 Android 无法播报 Span 标签中的文本

    我们希望屏幕阅读器在节点关闭后宣布 项目已关闭 有趣的是 Chrome 上的 NVDA 正确地播报了该消息 而 Android 和 iOS Voice Over 则未能播报此消息 这是打字稿代码 HostListener keydown t
  • 在 Scala / Spark 中将纪元转换为日期时间

    我使用以下方法将表示 DateTime 的 String 转换为 unix time 纪元 def strToTime x String Long DateTimeFormat forPattern YYYY MM dd HH mm ss
  • Spacy 中的自定义句子分割

    I want spaCy使用我提供的句子分割边界而不是它自己的处理 例如 get sentences Bob meets Alice SentBoundary They play together gt Bob meets Alice Th
  • JDK 1.6.x G1 的经验(“垃圾优先”)

    我想知道最新JDK中G1垃圾收集器的体验如何 我懂了NullPointerException尽管代码没有改变并且在早期的 JDK 中表现正常 但我的程序中抛出了这个问题 垃圾收集器只会影响表现您的应用程序 而不是它的正确性 我一直在 Ecl
  • Python中的非阻塞套接字?

    是我 还是我找不到关于Python中非阻塞套接字的好教程 我不确定如何准确地工作 recv和 send在里面 根据 python 文档 至少是我的理解 recv ed or send ed 数据可能只是部分数据 那么这是否意味着我必须以某种
  • 数组对象内相同值的重复分组

    id year 2017 month 4 Confirm 0 id year 2017 month 4 Expired 25 id year 2017 month 4 Pending 390 id year 2017 month 5 Pen
  • 构建启用 COM 互操作的项目,而无需在构建过程中注册它

    在 Visual Studio 2010 中 我尝试构建一个启用 COM 互操作的 C 项目 但在构建过程中不注册它 但我DO需要程序集的类型库 tlb 文件 因此我可以从解决方案中的另一个 C 项目导入它 我还没有找到一种方法来做到这一点
  • KafkaStreams 同一应用程序中的多个流

    我正在尝试根据 KafkaStreams 的惯例和合理性做出实用的设计决策 假设我想将两个不同的事件放入其中KTables 我有一个制作人将这些消息发送给KStream那就是听那个话题 据我所知 我不能对消息使用条件转发KafkaStrea
  • 如何将函数应用于嵌套列表?

    我需要获取嵌套列表中变量的最大值 对于某个站号 s 和某个成员 m mylist s m 其形式为 station date time member bias 6019 2011 08 06 12 00 mbr003 86 6019 201
  • URLError:

    只是想让这段代码直接运行它的基本代码Python 金融 import datetime import matplotlib pyplot as plt from matplotlib finance import quotes histor
  • 复制/粘贴到 Word 时如何保留 rstudio 的格式?

    我想在 Word 2010 中重现我的代码 脚本是用 rstudio 编写的 我想在粘贴到 Word 时保留 rstudio 的格式 主要是 我喜欢 rstudio 使用的字体颜色和间距 我发现当我从 SAS 粘贴到 Word 时 格式会被
  • 如何为pandas数据框中的不同组分配唯一的ID?

    如何根据特定条件为 pandas 数据框中创建的组分配唯一 ID 例如 我有一个名为 df 的数据框 其结构如下 名称标识用户 日期时间标识用户访问资源的日期 时间 Name Datetime Bob 26 04 2018 12 00 00
  • 未找到 Firebase 框架

    我一直在尝试将我的项目迁移到 cocoapods 我觉得我快到了 但我陷入了困境 ld 找不到架构 x86 64 的 Firebase 框架 错误 链接器命令失败 退出代码为 1 使用 v 查看调用 我正在尝试使用我的 app xcwork
  • SwiftUI 预览的 Xcode Canvas 不显示

    我正在尝试从 Xcode 11 运行新的 Canvas 功能 但 Canvas 不会显示 我究竟做错了什么 这个新的 Xcode 功能应该在不运行应用程序的情况下显示我的 SwiftUI 视图的实时预览 当您使用 SwiftUI 创建自定义
  • 图像调整大小性能:System.Drawing 与 System.Windows.Media

    我遇到了需要调整大量图像大小的情况 这些图像目前在文件系统上存储为 jpg 文件 但我希望稍后在项目中内存中只有 byte 源图像大小是可变的 但输出应该是 3 个不同的预定大小 应保留长宽比 用空白填充原始图像 即 将调整非常高的图像大小