iOS 多次获取图片主题色不一样

一个需求中,要求获取图片的主题色

代码如下

复制代码
-(void)kk_getImage:(UIImage *)image fetchthemeColor:(void(^)(UIColor *color))callBack {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 第一步 先把图片缩小 加快计算速度. 但越小结果误差可能越大
        int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
        CGSize thumbSize = CGSizeMake(100, 100*self.backgroundImgView.height/(self.backgroundImgView.width ?: 100));

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL,thumbSize.width,thumbSize.height, 8, thumbSize.width*4, colorSpace,bitmapInfo);
        CGRect drawRect = CGRectMake(0, 0, thumbSize.width, thumbSize.height);
        CGContextDrawImage(context, drawRect, image.CGImage);
        CGColorSpaceRelease(colorSpace);
        
        // 第二步 取每个点的像素值
        unsigned char* data = CGBitmapContextGetData (context);
        if (data == NULL) {
            dispatch_async(dispatch_get_main_queue(), ^{
                callBack(nil);
            });
        };
        NSCountedSet* cls = [NSCountedSet setWithCapacity: thumbSize.width * thumbSize.height];
        for (int x = 0; x < thumbSize.width; x++) {
            for (int y = 0; y < thumbSize.height; y++) {
                int offset = 4 * (x * y);
                int red = data[offset];
                int green = data[offset + 1];
                int blue = data[offset + 2];
                int alpha =  data[offset + 3];
                // 过滤透明的、基本白色、基本黑色
                // 这里限制170是因为要去除偏亮的颜色 越接近250越亮
                if (alpha > 0 && (red < 170 && green < 170 && blue < 170) && (red > 5 && green > 5 && blue > 5)) {
                    NSArray *clr = @[@(red),@(green),@(blue),@(alpha)];
                    [cls addObject:clr];
                }
            }
        }
        CGContextRelease(context);
        
        //第三步 找到出现次数最多的那个颜色
        NSEnumerator *enumerator = [cls objectEnumerator];
        NSArray *curColor = nil;
        NSArray *MaxColor = nil;
        NSUInteger MaxCount = 0;
        while ((curColor = [enumerator nextObject]) != nil){
            NSUInteger tmpCount = [cls countForObject:curColor];
            if ( tmpCount < MaxCount ) continue;
            MaxCount = tmpCount;
            MaxColor = curColor;
        }
        UIColor * subjectColor = [UIColor colorWithRed:([MaxColor[0] intValue]/255.0f) green:([MaxColor[1] intValue]/255.0f) blue:([MaxColor[2] intValue]/255.0f) alpha:([MaxColor[3] intValue]/255.0f)];
        dispatch_async(dispatch_get_main_queue(), ^{
            callBack(subjectColor);
        });
    });
}

以上代码在多数情况下都没有问题,但是遇到一个情况,有一张图片,下拉刷新的时候,获取到的主题色和首次获取到的不一样,然后多次下拉刷新, 又能恢复首次提取的主题色,经过反复排查,发现问题是我们提取主题色的时候设置的size过小,导致每次提取主题色的误差比较大,所以修复方法就是增大提取主题色的size,将

CGSize thumbSize = CGSizeMake(100, 100self.backgroundImgView.height/(self.backgroundImgView.width ?: 100));
这一句代码中的100, 改成200就可以了
CGSize thumbSize = CGSizeMake(200, 200
self.backgroundImgView.height/(self.backgroundImgView.width ?: 200));

这样处理之后,每次获取到的主题色都是相同的

相关推荐
用户094 小时前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift
YungFan4 小时前
iOS26适配指南之UIColor
ios·swift
权咚20 小时前
阿权的开发经验小集
git·ios·xcode
用户0920 小时前
TipKit与CloudKit同步完全指南
ios·swift
小溪彼岸1 天前
macOS自带截图命令ScreenCapture
macos
法的空间1 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
2501_915918411 天前
iOS 上架全流程指南 iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传 ipa 与审核实战经验分享
android·ios·小程序·uni-app·cocoa·iphone·webview
TESmart碲视1 天前
Mac 真正多显示器支持:TESmart USB-C KVM(搭载 DisplayLink 技术)如何实现
macos·计算机外设·电脑
00后程序员张1 天前
iOS App 混淆与加固对比 源码混淆与ipa文件混淆的区别、iOS代码保护与应用安全场景最佳实践
android·安全·ios·小程序·uni-app·iphone·webview
Magnetic_h2 天前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa