Open chemharuka opened 4 years ago
感谢指导,我有空研究下!
我这边建议提供选项“不包含”、“嵌入”和“转换”三者,因为在网页设计而不是印刷设计的领域,保证颜色代码的稳定性十分关键,而平面设计领域则可能需要反复比对转换前后的色彩。
同样地,现在的各种截图工具对HDR界面的程序截图都不正常,应该也加入一个选项,将HDR映射到SDR或者在截图中附加HDR的metadata
同样地,现在的各种截图工具对HDR界面的程序截图都不正常,应该也加入一个选项,将HDR映射到SDR或者在截图中附加HDR的metadata
可以直接使用支持 hdr 的图片格式吗?比如 jxr 或者 avif、webp 什么之类?
我目前解决 hdr 下截图是通过在使用 Win + Alt + PrtScn 用 Xbox Game Bar 的捕获截图,会同时生成一张 hdr 的 jxr 截图与 sdr 的 png 截图。
“截屏时嵌入ICC Profile”, 这功能macOS, iOS, Android早已支持,虽然Android截图程序对此有额外条件/缺陷:1.要求全屏、2.裁剪后会导致ICC丢失。
Windows的截图程序是时候跟进了。
致开发者 如何在UWP应用程序中获得当前视图的ICC Profile
using Windows.Graphics.Display;
// ...
private async void btnSaveICCProfile_Click(object sender, RoutedEventArgs e)
{
DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
// save ICC profile
FileSavePicker picker = new FileSavePicker();
picker.SuggestedStartLocation = PickerLocationId.Downloads;
picker.FileTypeChoices.Add("application/vnd.iccprofile", new List<string>() { ".icc" });
picker.SuggestedFileName = "display";
StorageFile file = await picker.PickSaveFileAsync();
using (IRandomAccessStream readableStream = await displayInfo.GetColorProfileAsync())
using (Stream inputStream = readableStream.AsStreamForRead())
using (Stream outputStream = await file.OpenStreamForWriteAsync())
{
Console.WriteLine("Writing file " + file.Name);
inputStream.CopyTo(outputStream);
Console.WriteLine("Saved as " + file.Name);
}
}
private void btnShowDisplayInfo_Click(object sender, RoutedEventArgs e)
{
DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
// show advanced color info
AdvancedColorInfo colorInfo = displayInfo.GetAdvancedColorInfo();
StringBuilder sb = new StringBuilder();
bool wgc = colorInfo.IsAdvancedColorKindAvailable(AdvancedColorKind.WideColorGamut);
sb.Append("WideColorGamut: ").Append(wgc).Append("\n");
sb.Append("RedPrimary: ").Append(colorInfo.RedPrimary.ToString()).Append("\n");
sb.Append("GreenPrimary: ").Append(colorInfo.GreenPrimary.ToString()).Append("\n");
sb.Append("BluePrimary: ").Append(colorInfo.BluePrimary.ToString()).Append("\n");
sb.Append("WhitePoint: ").Append(colorInfo.WhitePoint.ToString()).Append("\n");
sb.Append("\n");
bool hdr = colorInfo.IsAdvancedColorKindAvailable(AdvancedColorKind.HighDynamicRange);
sb.Append("HighDynamicRange: ").Append(hdr).Append("\n");
if (hdr)
{
sb.Append("MaxAverageFullFrameLuminanceInNits: ").Append(colorInfo.MaxAverageFullFrameLuminanceInNits).Append("\n");
sb.Append("MaxLuminanceInNits: ").Append(colorInfo.MaxLuminanceInNits).Append("\n");
}
sb.Append("\n");
sb.Append("DPR: ").Append(displayInfo.RawPixelsPerViewPixel).Append("\n");
sb.Append("\n");
txtDisplayInfo.Text = sb.ToString();
}
如何在PNG中嵌入ICC profile 添加iCCP chunk, 设置chunk name为例如"Snipaste", ...
如何在JPEG中嵌入ICC profile 添加APP2 segment, 设置segment identifier 为"ICC_PROFILE\x00", ...
如何在BMP中嵌入ICC profile 使用BITMAPV5HEADER (124字节), 设置colorSpaceType为"MBED", ...
P.S. Windows用户在使用广色域显示器时,需要在显示器端/Windows端同步指定颜色模式/ICC profile(除非有某个应用程序自动来做这件事)。见 You're Using Your Monitor WRONG! (Here's How to Fix It) 的解释。
经常要用但总是缺,我忍在不住再多说几句。目前的变通解决方法有
方法1: 【推荐】使用TweakPNG 先使用TweakPNG从一个内嵌有指定ICC Profile有的正常PNG中导出iCCP chunk,之后对于需要处理的PNG,插入iCCP chunk到PNG image header后即可(同时删除sRGB、gMMa等颜色相关的chunks,如果存在)。
方法2: 使用Exif Tools之类的命令行工具 通过命令行嵌入icc到图片中,如
exiftool "-icc_profile<=profile.icc" photo.jpg
方法3: 使用Photoshop 先在安装所需嵌入icc文件到Windows系统,再运行Photoshop打开图片,通过菜单 Edit / Assign Profile选择一个ICC Profile
在正确校色的显示器下(这个时候会有一个显示器的icc文件)进行截图并输出为文件,使得文件包含屏幕的icc配置文件。 这样一来使用专业软件打开截图的话,可以正确地还原色彩。 icc/icm文件可以让用户手动提供,不过通常校色出来的文件大小约接近1MB,将其嵌入图片会使得大小显著增加。所以正确的办法是使用argyll库,对图片进行色彩空间转换。argyll库的cctiff.exe可以提供图片之间的色彩转换。(argyll库采用的是AGLP许可,因此商业使用也是可行的) https://www.argyllcms.com/doc/cctiff.html 而srgb的icm在displaycal中带有,而且网上可以方便地找到。总之,只要用户提供自己显示器的icm文件,每次保存图片snipaste都可以将其转化为标准srgb色域下的图片。
以snipaste产生的截图 input.jpg为例,首先用imagemagick将其转化为tiff(我并不知道snipaste会如何保留原始数据): linux@wsl: ~$ convert input.jpg input.tiff 之后用cctiff.exe转换: PS C:\xxx> .\cctiff.exe -ip display.icm -i sRGB.icc color.tiff output.tiff 得到的tiff再转化为最终所要的文件: linux@wsl: ~$ convert output.tiff output.png 最终我获得了一个sRGB空间下的png文件,其颜色以感知的形式从高色域屏的色彩空间转化为了sRGB空间中。
上述方法的某些问题:cctiff识别tiff文件不太全面,jpg用imagemagick转化得到的tiff可以正确识别,但png就不行,可能是某些参数需要设置好。但总之这是最方便的解决高色域屏截图出正确颜色的方法了。 左为显示器显示的颜色的大致样貌(饱和度更大),右为如果不进行转换,截图产生的颜色。