iOS獲取圖片區(qū)域主色的方法
之前的項(xiàng)目有這樣的需求,有一個(gè)頁(yè)面可以檢索一塊區(qū)域內(nèi)圖片的主色。效果圖如圖所示

下面是如何獲取區(qū)域主色的實(shí)現(xiàn)思路:
首先,我們需要從相冊(cè),或者相機(jī)去獲取圖片;
其次,得到圖片需要截取區(qū)域圖片;
然后,獲取截取圖片的主色。
理想中是這樣的,但是有很多阻礙,得到的圖片需要自適應(yīng)imageView(imageView的寬高是固定的),截圖的得到的區(qū)域不是自己想要的區(qū)域。這里需要將圖片等比例縮放,按照ImageView的寬高。
那現(xiàn)在就直接上代碼吧!
首先我們需要等比例縮放Image:
/**
* 縮放圖片
*
* @param img image
* @param size 縮放后的大小
*
* @return image
*/
+ (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
// 創(chuàng)建一個(gè)bitmap的context
CGFloat width = CGImageGetWidth(img.CGImage);
CGFloat height = CGImageGetHeight(img.CGImage);
CGFloat max = width >= height ? width:height;
CGSize originSize;
if (max <= 0) {
return nil;
}
if (width >= height) {
originSize = CGSizeMake(size.width, (size.width * height)/width);
}else{
originSize = CGSizeMake((size.height * width)/height, size.height);
}
// 并把它設(shè)置成為當(dāng)前正在使用的context
UIGraphicsBeginImageContext(size);
// 繪制改變大小的圖片
[img drawInRect:CGRectMake((size.width - originSize.width)/2, (size.height - originSize.height)/2, originSize.width, originSize.height)];
// 從當(dāng)前context中創(chuàng)建一個(gè)改變大小后的圖片
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// 使當(dāng)前的context出堆棧
UIGraphicsEndImageContext();
// 返回新的改變大小后的圖片
return scaledImage;
}
之后就是截取區(qū)域圖片,這理解去10*10的方塊:
// 裁剪圖片
+ (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect {
CGImageRef sourceImageRef = [image CGImage];
CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);
return newImage;
}
然后獲取圖片的主色:
/**
* 獲取圖片的主色
*
* @param image image
* @param scale 精準(zhǔn)度0.1~1
*
* @return 圖片的主要顏色
*/
+ (NSDictionary *)mostColor:(UIImage *)image scale:(CGFloat)scale{
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
#else
int bitmapInfo = kCGImageAlphaPremultipliedLast;
#endif
if (scale <= 0.1) {
scale = 0.1;
}else if(scale >= 1){
scale = 1;
}
//第一步 先把圖片縮小 加快計(jì)算速度. 但越小結(jié)果誤差可能越大
CGSize thumbSize=CGSizeMake([image size].width * scale, [image size].height * scale);
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, image.CGImage);
CGColorSpaceRelease(colorSpace);
//第二步 取每個(gè)點(diǎn)的像素值
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.height; x++) {
for (int y=0; y<thumbSize.width; y++) {
int offset = 4*(x*thumbSize.width + y);
int red = data[offset];
int green = data[offset+1];
int blue = data[offset+2];
int alpha = data[offset+3];
NSArray *clr=@[@(red),@(green),@(blue),@(alpha)];
[cls addObject:clr];
}
}
CGContextRelease(context);
//第三步 找到出現(xiàn)次數(shù)最多的那個(gè)顏色
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;
}
//返回三原色色值
NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithCapacity:0];
[dic setValue:@([MaxColor[0] intValue]/255.0f) forKey:@"red"];
[dic setValue:@([MaxColor[1] intValue]/255.0f) forKey:@"green"];
[dic setValue:@([MaxColor[2] intValue]/255.0f) forKey:@"blue"];
return dic;
}
其實(shí)獲取圖片區(qū)域的主要顏色就是這么簡(jiǎn)單,線面附上獲取單點(diǎn)的顏色:
/**
* 獲取圖片上一個(gè)點(diǎn)的顏色
*
* @param point 點(diǎn)擊的點(diǎn)的位置
* @param image image
*
* @return 返回點(diǎn)擊點(diǎn)的顏色
*/
+ (UIColor *)colorAtPixel:(CGPoint)point UIImage:(UIImage *)image CGRect:(CGRect)rect{
// Cancel if point is outside image coordinates
if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f,rect.size.width, rect.size.height), point)) {
return nil;
}
NSInteger pointX = trunc(point.x);
NSInteger pointY = trunc(point.y);
CGImageRef cgImage = image.CGImage;
NSUInteger width = image.size.width;
NSUInteger height = image.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel * 1;
NSUInteger bitsPerComponent = 8;
unsigned char pixelData[4] = { 0, 0, 0, 0 };
CGContextRef context = CGBitmapContextCreate(pixelData,
1,
1,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetBlendMode(context, kCGBlendModeCopy);
// Draw the pixel we are interested in onto the bitmap context
CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
CGContextRelease(context);
// Convert color values [0..255] to floats [0.0..1.0]
CGFloat red = (CGFloat)pixelData[0] / 255.0f;
CGFloat green = (CGFloat)pixelData[1] / 255.0f;
CGFloat blue = (CGFloat)pixelData[2] / 255.0f;
CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}
最終就實(shí)現(xiàn)如上圖的想過(guò),頁(yè)面丑了點(diǎn),但是效果是實(shí)現(xiàn)了,又不真確的地方,請(qǐng)留言。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS中自動(dòng)實(shí)現(xiàn)對(duì)象序列化的方法詳解
這篇文章主要給大家介紹了在iOS中自動(dòng)實(shí)現(xiàn)對(duì)象序列化的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-05-05
iOS 指壓即達(dá)集成iOS9里的3D Touch的方法
這篇文章主要介紹了iOS 指壓即達(dá)集成iOS9里的3D Touch的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03
iOS開(kāi)發(fā)避免安全隱患的要點(diǎn)總結(jié)
在本篇文章里小編給各位整理了關(guān)于iOS開(kāi)發(fā)如何避免安全隱患的知識(shí)點(diǎn)總結(jié),需要的朋友們學(xué)習(xí)下。2019-07-07
iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用
這篇文章主要介紹了iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用的方法,實(shí)例代碼為傳統(tǒng)的Objective-C語(yǔ)言,需要的朋友可以參考下2016-03-03
iOS中的表單按鈕選項(xiàng)UIActionSheet常用方法整理
UIActionSheet經(jīng)常被用來(lái)制作各種彈出的選項(xiàng),這里我們就來(lái)看一下iOS中的表單按鈕選項(xiàng)UIActionSheet常用方法整理,需要的朋友可以參考下2016-06-06
解決iOS11圖片下拉放大出現(xiàn)信號(hào)欄白條的bug問(wèn)題
這篇文章主要介紹了iOS11圖片下拉放大出現(xiàn)信號(hào)欄白條的bug問(wèn)題,需要的朋友參考下吧2017-09-09
iOS開(kāi)發(fā)使用UITableView制作N級(jí)下拉菜單的示例
這篇文章主要介紹了iOS開(kāi)發(fā)使用UITableView制作N級(jí)下拉菜單的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01

