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中textField限制字符串長(zhǎng)度、字符數(shù)的方法
這篇文章主要給大家介紹了關(guān)于iOS中textField限制字符串長(zhǎng)度、字符數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位iOS開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-06-06使用SDLocalize實(shí)現(xiàn)高效完成iOS多語(yǔ)言工作
這篇文章主要介紹了使用SDLocalize實(shí)現(xiàn)高效完成iOS多語(yǔ)言工作的相關(guān)資料,需要的朋友可以參考下2022-10-10iOS 獲取當(dāng)前時(shí)間及時(shí)間戳的互換實(shí)例
下面小編就為大家分享一篇iOS 獲取當(dāng)前時(shí)間及時(shí)間戳的互換實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01iOS藍(lán)牙設(shè)備名稱緩存問(wèn)題的解決方法
這篇文章主要給大家介紹了關(guān)于iOS藍(lán)牙設(shè)備名稱緩存問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09iOS中FMDB數(shù)據(jù)庫(kù)之增刪改查使用實(shí)例
本篇文章主要介紹了iOS中FMDB數(shù)據(jù)庫(kù)之增刪改查使用實(shí)例,F(xiàn)MDB是一個(gè)輕量級(jí)的數(shù)據(jù)庫(kù),用于將網(wǎng)絡(luò)資源存儲(chǔ)在本地。2017-05-05iOS表視圖之下拉刷新控件功能的實(shí)現(xiàn)方法
下拉刷新是重新刷新表視圖或列表,以便重新加載數(shù)據(jù),這種模式廣泛用于移動(dòng)平臺(tái),相信大家對(duì)于此也是非常熟悉的,那么iOS是如何做到的下拉刷新呢?下面小編給大家分享iOS表視圖之下拉刷新控件的實(shí)現(xiàn)方法,一起看看吧2017-01-01