.NET解所有相机RAW格式照片

再聊.NET解相机RAW格式照片

上次我发了一篇文章《用.NET解索尼相机ARW格式照片》,提到通过安装 SonyRawFileDecoder的方式,然后调用 WindowsImagingComponents来解析 RAW格式文件。后来我经过进一步研究、探索,发现还有更简单的办法。

新的方法实在是太简单、好用了,相比之下,我前一篇文章简直就是在“挖坑”。

其实啥都不装,什么相机都支持!

其实 Windows10自带了一个 RAW格式解码器,也集成在 WindowsImagingComponents中,通过 SharpDX.Direct2D1的几行代码,可以将这个解码器的信息调出来:

// 安装NuGet包:SharpDX.Direct2D1
using var wic = new ImagingFactory2();
using var decoder = new BitmapDecoder(wic, file, DecodeOptions.CacheOnDemand);
string json = JsonSerializer.Serialize(decoder.DecoderInfo, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);

运行结果如下(为突出重点,有少量删减):

{"PixelFormats": ["6fddc324-4e03-4bfe-b185-3d77768dc90d"],"ColorManagementVersion": "1.0.0.0\u0000","MimeTypes": "image/3FR,image/ARI,image/ARW,image/BAY,image/CAP,image/CR2,image/CR3,image/CRW,image/DCS,image/DCR,image/DRF,image/EIP,image/ERF,image/FFF,image/IIQ,image/K25,image/KDC,image/MEF,image/MOS,image/MRW,image/NEF,image/NRW,image/ORF,image/ORI,image/PEF,image/PTX,image/PXN,image/RAF,image/RAW,image/RW2,image/RWL,image/SR2,image/SRF,image/SRW,image/X3F,image/DNG\u0000","FileExtensions": ".3FR,.ARI,.ARW,.BAY,.CAP,.CR2,.CR3,.CRW,.DCS,.DCR,.DRF,.EIP,.ERF,.FFF,.IIQ,.K25,.KDC,.MEF,.MOS,.MRW,.NEF,.NRW,.ORF,.ORI,.PEF,.PTX,.PXN,.RAF,.RAW,.RW2,.RWL,.SR2,.SRF,.SRW,.X3F,.DNG\u0000","ContainerFormat": "fe99ce60-f19c-433c-a3ae-00acefa9ca21","IsAnimationSupported": false,"IsChromakeySupported": false,"IsLosslessSupported": true,"IsMultiframeSupported": false,"Author": "Microsoft Corporation\u0000","Version": "10.0.18362.1\u0000","SpecVersion": "1.0.0.0\u0000","FriendlyName": "Microsoft Raw Image Decoder\u0000","ComponentType": 1,"CLSID": "41945702-8302-44a6-9445-ac98e8afa086","SigningStatus": 1,"VendorGUID": "f0e749ca-edef-4589-a73a-ee0e626a2a2b",
}

可见,什么都不用装,就已经支持了高达 36种 RAW格式文件,索尼的 .ARW、佳能的 .CR2和 .CR3和尼康的 .NEF都在列——就可能就是为什么 Windows10可以直接打开相机的 RAW格式文件。

使用上次文章中的同样代码,即可将 .ARW格式文件转换为 jpeg

// 依赖于WPF,不用装NuGet包
var decoder = BitmapDecoder.Create(new Uri(@"DSC05458.ARW"), BitmapCreateOptions.None, BitmapCacheOption.Default);
var transformedBitmap = new TransformedBitmap(decoder.Frames[0], Transform.Identity);
var jpg = new JpegBitmapEncoder();
jpg.Frames.Add(BitmapFrame.Create(transformedBitmap));
using var stream = new MemoryStream();
jpg.Save(stream);

上次还挖了个坑说如果是我,一般会选择用 SharpDX而不是 WPF,但我又没说 SharpDX的代码该怎么写,这里面我将 SharpDX的代码贴出来(运行效果完全一样):

// 安装NuGet包:SharpDX.Direct2D1
using var wic = new ImagingFactory2();
using FormatConverter converter = LoadImage(wic, @"DSC00115.ARW");
Util.Image(SaveToJpeg(wic, converter)).Dump();
static byte[] SaveToJpeg(ImagingFactory2 wic, BitmapSource source)
{using var ms = new MemoryStream();using (var encoder = new JpegBitmapEncoder(wic, ms)){using (var frame = new BitmapFrameEncode(encoder)){frame.Options.ImageQuality = 0.7f;frame.Initialize();frame.WriteSource(source);frame.Commit();}encoder.Commit();}return ms.ToArray();
}
static FormatConverter LoadImage(ImagingFactory2 wic, string file)
{using var decoder = new BitmapDecoder(wic, file, DecodeOptions.CacheOnDemand);decoder.Dump();var converter = new FormatConverter(wic);converter.Initialize(decoder.GetFrame(0), PixelFormat.Format32bppPBGRA);return converter;
}

代码中我加入了缩放,运行上次的 .ARW文件后,可以得出一样的 jpeg图片。

跨平台?没问题!

故名思义 WindowsImagingComponnets,显然只有 Windows上才能运行。想跨平台读取相机 RAW格式文件就必须另找一个库—— Magick.NET,其使用也非常简单,甚至比 WIC更简单,只要两行代码!:

// 安装NuGet包:Magick.NET-Q8-AnyCPU
using var image = new MagickImage(@"DSC00115.ARW");
byte[] bytes = image.ToByteArray(MagickFormat.Jpeg);

除了读取保存, Magick.NET还能缩放图片、转换 pdf、加水印、读取 Exif数据、无损压缩、绘图等功能,具体功能可以参见:https://github.com/dlemstra/Magick.NET/blob/master/docs/Readme.md。

另外, Magick.NET还支持超过 200种图片格式,其中甚至还包括 Photoshop的 psd文件。可以在这个链接中查看是否支持你所需要的格式:https://imagemagick.org/index.php

……更别它还可以跨平台

有一点需要注意,它的 NuGet包有许多个,初一看可能会一惊: 

这里可以说一下,首先它有 Q8、 Q16和 Q16-HDRI三种版本:

  • Q8表示一个像素使用 8位颜色深度,它占用内存最小;

  • Q16表示一个像素使用 16位颜色深度,比 Q8多一倍;

  • Q16-HDRI则使用 32位浮点型来表示颜色,比 Q16再多一倍;

正常使用建议 Q8即可,有微单/单反修图需求的,可以考虑 Q16Q16-HDRI

另外它还有 x86、 x64和 AnyCPU三个平台版本,一般选 AnyCPU,但注意 Magick.NET是基于本地代码,因此它需要下载多个平台,因此 AnyCPU大小( 45.34MB)比 x64( 20.85MB)大一倍。

缺点?

有这么多优点,还要什么自行车?……其实它也是有缺点的,有个明显的缺点,就是性能慢。我测试了上次那张 ARW格式文件,性能分析如下(平均需要 3.7秒):

次数分配内存内存提高耗时
143,918,7921,0803739
243,884,9441603748
343,966,0006643878
444,015,928803778
543,902,7844163747

换成 WIC,性能数据如下,耗时只要 705毫秒,明显快得多:

次数分配内存内存提高耗时
111,939,0721,488713
211,939,76810,256709
312,013,8724,608705
411,931,66496705
511,919,384-25,968704

总结

如果你用 Windows10,则什么都不用装,就能体验到极致性能的 RAW解析工具,因为系统自带了 MicrosoftRawImageDecoder

如果你想跨平台(但不特别在意性能),则可以使用开源的 Magick.NET,它提供最便利的 API和最省心的功能、格式支持,特别强大。但话又说回来, RAW这种东西一般都是骚操作才需要,谁在意跨平台呢?

我也特意试了一下收费的 Aspose.Imaging,但解析 RAW格式文件不是它的长项,直接不支持。

本想研究一下 libraw,但它只提供了 C API——也不是不能用。正准备用 P/Invoke时刚正面就有了本文中的发现。

喜欢的朋友 请关注我的微信公众号:【DotNet骚操作】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AspNetCore结合Redis实践消息队列

这是年中首发在博客园上的文章,个人觉得是AspNetCore结合Redis做的一次比较优秀的消息队列重构,其中对于点对点/发布-订阅的思路应该也是面试必考题。引言.Net TPL Dataflow是一个进程内数据流管道,应对高并发、低延迟的要求非常有效&#xf…

提升Azure App Service的几个建议

本文介绍了6个技巧,这些技巧可以改善Azure App Service托管应用程序的性能。其中一些技巧是你现在就可以进行的配置变更,而其他技巧则可能需要对应用程序进行一些重新设计和重构, 本文的几个技巧对于常规企业部署依旧有指引作用。长话短说开发…

单向链表的逆转(数据结构)(c语言)

逆转单向链表的意思是:给定你一个单向链表,一个整数n(n为要逆转的结点数),要求你把链表从头结点到第n个结点给逆转过来 图示: 给出一个单向链表,一个整数n4。也就是要求把该链表从头结点&#x…

广东职业教育信息化研究会2019年会暨区块链专题研讨会

兹定于2019年12月28日(星期六)上午9:30召开广东职业教育信息化研究会2019年会暨专题研讨会,本次会议由广东职业教育信息化研究会主办,华南师范大学网络教育学院协办。会议地址:广州市天河区中山大道西55号华南师范大学…

如何快速融入一个团队?

作者:邹溪源,长沙资深互联网从业者,架构师社区特邀嘉宾!一我们难免需要离开一个圈子,加入一个陌生的集体。毋庸置疑,离开熟知的圈子,走向未知的圈子难免会产生许多畏惧甚至情怯,这都…

关于C#异步编程你应该了解的几点建议

前段时间写了一篇关于C#异步编程入门的文章,你可以点击《C#异步编程入门看这篇就够了》查看。这篇文章我们来讨论下关于C#异步编程几个不成文的建议,希望对你写出高性能的异步编程代码有所帮助。注:本文的很多内容都是学习《Effective C#》的…

数据库分区

一、分区原理分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘,系统或是不同服务器存储介子中,实际上还是一张表。要实现这一功能,首先要了解数据库对水平分区表进行分区存储的原理。数据库分区和分表相似&#xff0…

如何在 C# 平台调用云开发?

▌关于作者苏震巍,云开发Linker计划成员,《微信开发深度解析》作者、Senparc.Weixin 微信 SDK 作者、微软最有价值专家(MVP)、盛派网络创始人兼首席架构师、微软 Ignite 技术大会讲师、从事软件及互联网研发已有26年,发…

如何打造组织级敏捷,你想知道的都在这里!

“敏捷是适应和响应变化的能力……敏捷组织将变化视为机遇,而不是威胁。” — Jim Highsmith注:Highsmith 在软件开发和 IT 行业有着超过 30 年的经验,曾是敏捷宣言的签署人之一,敏捷联盟的发起人和第一任理事,在很多行…

Azure DevOps Server CI - 自搭跨平台容器代理Agents

前言最近在地端(On-premises)幫團隊搭一套CI/CD流程,也順帶整理了一下從無到有的搭建過程,這次使用了docker技術來解決現有團隊使用CI/CD時讓現有CI/CD hosting環境過於複雜的問題。在開始之前,我先預備一下搭建的環境,如下:Windo…

.Net Core 认证组件源码解析

不知不觉.Net Core已经推出到3.1了,大多数以.Net为技术栈的公司也开始逐步的切换到了Core,从业也快3年多了,一直坚持着.不管环境怎么变,坚持自己的当初的选择,坚持信仰 .Net Core是个非常优秀的框架,如果各位是从WebForm开始,一步步走到今天,自然而然就会发现.微软慢慢的开始将…

在.NET Core下的机器学习--学习笔记

摘要.NET Core 在机器学习的应用场景,除了 ML .NET 还会介绍一个非常棒的開源技術 TensorFlow .NET , Keras .NET.讲师介绍本课内容人工智能介绍ML .NETICSharpCoreTensorFlow .NETKeras .NETSciSharp人工智能应用图像识别/物体识别自然语言/翻译搜索/知…

asp.net core 自定义基于 HttpContext 的 Serilog Enricher

asp.net core 自定义基于 HttpContext 的 Serilog EnricherIntro通过 HttpContext 我们可以拿到很多有用的信息,比如 Path/QueryString/RequestHeader 等请求信息, StatusCode/ResponseHeader 等响应信息,借助 HttpContext 我们可以在日志中记录很多有用…

我的 .NET Core 博客性能优化经验总结

点击上方蓝字关注“汪宇杰博客”导语去年8月,我用 .NET Core 重写了我的博客系统。经过一年多的优化,服务器响应速度从上线时候的 80ms 提高到了现在的 8ms,十倍提速。可惜由于部署在国外,自然不可抗力会导致中国用户晚上访问速度…

Redis 6 RC1发布,带来众多新特性

Redis 6 RC1 发布了,项目创建人 antirez 在博客中介绍,这是迄今最“企业”化的版本(SSL 与 ACL 等特性与企业极相关),也是最大的版本,同时也是参与人数最多的版本。GA 版本预计在明年三月到五月之间发布。R…

Serverless那么火,2019年的采用如何?

传统的 IT 架构已经不适合当今快速发展的数字经济环境。技术顾问 Declan Morris 表示:“客户不仅期望零停机时间,而且要求应用程序无论在世界任何地方都具有一致的性能。”他还预测到,接下来是 Serverless 计算和函数即服务(FaaS&…

【C】Natasha 插件编程

文章转载授权级别:CNatasha 是一个代替 Emit / Expression 的动态构建项目,旨在为开发者提供方便、快捷、高性能的动态构建服务,动态编程是生态的重要组成部分,希望开发者们能有足够的兴趣来了解、使用、建设它。1、插件生成使用 …

二叉树先序,中序,后序,层次遍历(数据结构)

先序遍历 先序遍历可以想象为,一个小人从一棵二叉树的根节点为起点,沿着二叉树的外沿,逆时针走一圈回到根节点,路上遇到的元素顺序,就是先序遍历的结果 先序遍历的结果为:A B D H I E J C F K G 中序遍…

.NET Core 在 K8S 上的开发实践--学习笔记

摘要本主题受众是架构师,开发人员,互联网企业 IT 运维人员。大纲:1、 K8S 对应用的要求;2、 .NET Core 上 K8S 的优势;3、 K8S 下的 .NET Core 配置;4、 .NET Core 上分布式组件概览。大纲kubernetes 对应用…

.NetCore 3.1 安装本地化中文智能提示

A、平时在群里,很多小伙伴都会问,.net core的智能提示和注释都是英文的,如果英语水平不是很高的,看着是挺麻烦,所以经常需要在身边有一个翻译软件,如果有汉化的中文智能提示就好了(当然&#xf…