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));

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

相关推荐
あ-2 小时前
mac dbeaver安装后显示数据包损坏
macos
钱栈up2 小时前
从 macOS 切回 Windows,我用 5 个免费工具把 80% 操作习惯搬了回来
windows·macos·策略模式
9144062324 小时前
mac Git 账户切换问题
git·macos
铁锚5 小时前
清理macos系统DS_Store文件的sh脚本
macos
茶底世界之下5 小时前
窗光静物一定要更亮吗?用 Awaking 把曝光收回一点
ios
ii_best7 小时前
ios手机开发安卓脚本开发软件[按键精灵教程]从「找最小值」到「Boss 最近刷新」再到「屏幕范围极值」
android·ios·智能手机·自动化·按键精灵
Hello_Pyhx10 小时前
CrossPaste 跨系统剪贴板配置:按发现、配对、同步逐层排查
macos·电脑
king13598745501 天前
LFM2.5-24B-A2B Mac 本地部署:内存估算、GGUF/MLX 与 Python 预检脚本
人工智能·macos
骑着蜗牛撵大象3271 天前
链路层不只是 MAC:以太网帧、ARP 与 802.1Q VLAN 的逐跳拆解
计算机网络·macos·ar·vlan·mac地址·链路层
茶底世界之下1 天前
林间步道要不要加暗角?用 Awaking 把强度收在20%
前端·ios·图片资源