Date
Nov. 23rd, 2024
 
2024年 10月 23日

Post: iOS: UIImage 获取主色调

iOS: UIImage 获取主色调

Published 12:11 Nov 12, 2014.

Created by @ezra. Categorized in #Programming, and tagged as #iOS.

Source format: Markdown

Table of Content

获取一个 UIImage 实例的主色调:

// @implementation UIImage (Detector)
- (UIColor *)mainColor {

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
    int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
#else
    int bitmapInfo = kCGImageAlphaPremultipliedLast;
#endif

    // 1 先把图片缩小 加快计算速度. 但越小结果误差可能越大
    CGSize thumbSize = CGSizeMake(50, 50);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL,
                                                 thumbSize.width,
                                                 thumbSize.height,
                                                 8,//bits per component
                                                 thumbSize.width*4,
                                                 colorSpace,
                                                 bitmapInfo);

    CGRect drawRect = CGRectMake(0, 0, thumbSize.width, thumbSize.height);
    CGContextDrawImage(context, drawRect, self.CGImage);
    CGColorSpaceRelease(colorSpace);

    // 2 取每个点的像素值
    unsigned char* data = CGBitmapContextGetData(context);

    if (data == NULL) {
        CGContextRelease(context);
        return 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];

            NSArray <NSNumber *>*clr = @[@(red), @(green), @(blue), @(alpha)];
            [cls addObject:clr];

        }
    }
    CGContextRelease(context);

    // 3 找到出现次数最多的那个颜色
    NSEnumerator *enumerator = [cls objectEnumerator];
    NSArray *curColor = nil;

    NSArray <NSNumber *>*MaxColor = nil;
    NSUInteger MaxCount = 0;

    while ((curColor = [enumerator nextObject]) != nil) {
        NSUInteger tmpCount = [cls countForObject:curColor];

        if (tmpCount < MaxCount) {
            continue;
        }

        MaxCount = tmpCount;
        MaxColor = curColor;
    }

    CGFloat r = [MaxColor[0] intValue] / 255.0f;
    CGFloat g = [MaxColor[1] intValue] / 255.0f;
    CGFloat b = [MaxColor[2] intValue] / 255.0f;
    CGFloat a = [MaxColor[3] intValue] / 255.0f;

    return [UIColor colorWithRed:r green:g blue:b alpha:a];
}
Pinned Message
HOTODOGO
The Founder and CEO of Infeca Technology.
Developer, Designer, Blogger.
Big fan of Apple, Love of colour.
Feel free to contact me.
反曲点科技创始人和首席执行官。
开发、设计与写作皆为所长。
热爱苹果、钟情色彩。
随时恭候 垂询