最近遇到了一个很奇怪的现象,相同的一张图在iOS原生能正常显现,但是在Flutter就显得很暗 具体往下看

现象

什么?同一张图在Flutter和iOS原生渲染出来效果不一样?

可以很明晰的看到iOS关于原图的复原度要比Flutter好太多

思考

看到这种场景顿时懵逼,明明是一张图,不至于Flutter这么拉胯吧,但是这个现象是做了这么久的Flutter第一次遇见(或者是之前没太仔细看小的icon,这次大图渲染愈加直观。。),所以觉得这个工作或许没那么复杂。于是开始怀疑是Impeller的问题,但是我尝试了@恋猫de小郭的文章里的 在iOS工程中修改info.plist

<key>FLTEnableImpeller</key>
<true />

尝试封闭Impeller,但是并没有什么作用,所以初步怀疑Impeller的思路或许不太对,所以就开始看之前的在Flutter显现正常的图,最终发现了一个奇妙之处,在图片的简介里有一个我不明白的地方不一样,便是色彩描绘文件

什么?同一张图在Flutter和iOS原生渲染出来效果不一样?

这儿询问chatgpt色彩描绘文件:sRGB IEC61966-2.1Display P3有什么差异,得到的答复是

sRGB IEC61966-2.1和Display P3是两种不同的色彩描绘文件,它们首要用于不同的显现设备和应用场景。它们的差异首要在于色彩规模和应用领域

  1. sRGB IEC61966-2.1:sRGB是一种规范的RGB色彩空间,广泛用于互联网、数字拍摄和普通的显现设备上。sRGB IEC61966-2.1的色彩规模相对较窄,适合一般图画显现,它的色域较小,可以在大多数常见显现设备上提供相对共同的色彩显现。sRGB通常是图画文件的默许色彩描绘文件。
  2. Display P3:Display P3是一种更广大的色彩空间,倾向于更明显和逼真的色彩展示。它首要用于高档的显现设备,如苹果公司的Retina显现器。相关于sRGB,Display P3可以出现更广大的色彩规模,关于鲜艳和饱和度较高的色彩作用更为明显。 总结来说,sRGB IEC61966-2.1适合一般的互联网应用和常见显现设备,而Display P3则适用于高档显现设备,如高分辨率显现器和专业图形处理工作。在选择使用哪一种色彩描绘文件时,需要考虑图画的应用场景和目标设备的才能来做出合适的选择。

呃。。如同看不出来咋回事,后来看到一篇文章提到Flutter关于Display P3的支持问题,具体意思便是原因便是 Flutter 直接把 Display P3 色域当做 sRGB 色域的图画处理了,而没有做色域转化,这一下就水落石出了~。

解决办法

文章中提到可以让原生来处理图片

CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
    NSUInteger frameCount = CGImageSourceGetCount(src);
    if (frameCount > 0) {
        NSDictionary *options = @{(__bridge NSString *)kCGImageSourceShouldCache : @YES,
                                  (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @NO
                                  };
        NSDictionary *props = (NSDictionary *) CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(src, (size_t) 0, (__bridge CFDictionaryRef)options));
        NSString *profileName = [props objectForKey:(NSString *) kCGImagePropertyProfileName];
        if ([profileName isEqualToString:@"Display P3"]) {
            NSMutableData *data = [NSMutableData data];
            CGImageDestinationRef destRef = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)data, kUTTypePNG, 1, NULL);
            NSMutableDictionary *properties = [NSMutableDictionary dictionary];
            properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = @(1);
            properties[(__bridge NSString *)kCGImageDestinationEmbedThumbnail] = @(0);
            properties[(__bridge NSString *)kCGImagePropertyNamedColorSpace] = (__bridge id _Nullable)(kCGColorSpaceSRGB);
            properties[(__bridge NSString *)kCGImageDestinationOptimizeColorForSharing] = @(YES);
            CGImageDestinationAddImageFromSource(destRef, src, 0, (__bridge CFDictionaryRef)properties);
            CGImageDestinationFinalize(destRef);
            CFRelease(destRef);
            return data;
        }
    }
    return imageData;

这儿偷闲了,因为找UI小姐姐让她切图的时候调整一下就可以了~,最终的解决方案是UI依据设计稿导出sRGB IEC61966-2.1类型的图片,同时这个图片的色值是向Display P3靠拢的,至此问题解决。