.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骚操作】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值