亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS去除圖片背景顏色的方法

2019-10-21 18:42:52
字體:
來源:轉載
供稿:網友

實際項目場景:去除圖片的純白色背景圖,獲得一張透明底圖片用于拼圖功能

介紹兩種途徑的三種處理方式(不知道為啥想起了孔乙己),具體性能鶸并未對比,如果有大佬能告知,不勝感激。

Core Image Core Graphics/Quarz 2D Core Image

Core Image是一個很強大的框架。它可以讓你簡單地應用各種濾鏡來處理圖像,比如修改鮮艷程度,色澤,或者曝光。 它利用GPU(或者CPU)來非??焖?、甚至實時地處理圖像數據和視頻的幀。并且隱藏了底層圖形處理的所有細節,通過提供的API就能簡單的使用了,無須關心OpenGL或者OpenGL ES是如何充分利用GPU的能力的,也不需要你知道GCD在其中發揮了怎樣的作用,Core Image處理了全部的細節。

iOS,去背景色

在蘋果官方文檔Core Image Programming Guide中,提到了Chroma Key Filter Recipe對于處理背景的范例

其中使用了HSV顏色模型,因為HSV模型,對于顏色范圍的表示,相比RGB更加友好。

大致過程處理過程:

創建一個映射希望移除顏色值范圍的立方體貼圖cubeMap,將目標顏色的Alpha置為0.0f 使用CIColorCube濾鏡和cubeMap對源圖像進行顏色處理獲取到經過CIColorCube處理的Core Image對象CIImage,轉換為Core Graphics中的CGImageRef對象,通過imageWithCGImage:獲取結果圖片

注意:第三步中,不可以直接使用imageWithCIImage:,因為得到的并不是一個標準的UIImage,如果直接拿來用,會出現不顯示的情況。

- (UIImage *)removeColorWithMinHueAngle:(float)minHueAngle maxHueAngle:(float)maxHueAngle image:(UIImage *)originalImage{ CIImage *image = [CIImage imageWithCGImage:originalImage.CGImage]; CIContext *context = [CIContext contextWithOptions:nil];// kCIContextUseSoftwareRenderer : CPURender /** 注意 * UIImage 通過CIimage初始化,得到的并不是一個通過類似CGImage的標準UIImage * 所以如果不用context進行渲染處理,是沒辦法正常顯示的 */ CIImage *renderBgImage = [self outputImageWithOriginalCIImage:image minHueAngle:minHueAngle maxHueAngle:maxHueAngle]; CGImageRef renderImg = [context createCGImage:renderBgImage fromRect:image.extent]; UIImage *renderImage = [UIImage imageWithCGImage:renderImg]; return renderImage;}struct CubeMap { int length; float dimension; float *data;};- (CIImage *)outputImageWithOriginalCIImage:(CIImage *)originalImage minHueAngle:(float)minHueAngle maxHueAngle:(float)maxHueAngle{  struct CubeMap map = createCubeMap(minHueAngle, maxHueAngle); const unsigned int size = 64; // Create memory with the cube data NSData *data = [NSData dataWithBytesNoCopy:map.data   length:map.length   freeWhenDone:YES]; CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"]; [colorCube setValue:@(size) forKey:@"inputCubeDimension"]; // Set data for cube [colorCube setValue:data forKey:@"inputCubeData"];  [colorCube setValue:originalImage forKey:kCIInputImageKey]; CIImage *result = [colorCube valueForKey:kCIOutputImageKey];  return result;}struct CubeMap createCubeMap(float minHueAngle, float maxHueAngle) { const unsigned int size = 64; struct CubeMap map; map.length = size * size * size * sizeof (float) * 4; map.dimension = size; float *cubeData = (float *)malloc (map.length); float rgb[3], hsv[3], *c = cubeData;  for (int z = 0; z < size; z++){ rgb[2] = ((double)z)/(size-1); // Blue value for (int y = 0; y < size; y++){ rgb[1] = ((double)y)/(size-1); // Green value for (int x = 0; x < size; x ++){ rgb[0] = ((double)x)/(size-1); // Red value rgbToHSV(rgb,hsv); // Use the hue value to determine which to make transparent // The minimum and maximum hue angle depends on // the color you want to remove float alpha = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) ? 0.0f: 1.0f; // Calculate premultiplied alpha values for the cube c[0] = rgb[0] * alpha; c[1] = rgb[1] * alpha; c[2] = rgb[2] * alpha; c[3] = alpha; c += 4; // advance our pointer into memory for the next color value } } } map.data = cubeData; return map;}

rgbToHSV在官方文檔中并沒有提及,筆者在下文中提到的大佬的博客中找到了相關轉換處理。感謝

void rgbToHSV(float *rgb, float *hsv) { float min, max, delta; float r = rgb[0], g = rgb[1], b = rgb[2]; float *h = hsv, *s = hsv + 1, *v = hsv + 2; min = fmin(fmin(r, g), b ); max = fmax(fmax(r, g), b ); *v = max; delta = max - min; if( max != 0 ) *s = delta / max; else { *s = 0; *h = -1; return; } if( r == max ) *h = ( g - b ) / delta; else if( g == max ) *h = 2 + ( b - r ) / delta; else *h = 4 + ( r - g ) / delta; *h *= 60; if( *h < 0 ) *h += 360;}

接下來我們試一下,去除綠色背景的效果如何

iOS,去背景色

我們可以通過使用HSV工具,確定綠色HUE值的大概范圍為50-170

調用一下方法試一下

[[SPImageChromaFilterManager sharedManager] removeColorWithMinHueAngle:50 maxHueAngle:170 image:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"nb" ofType:@"jpeg"]]]

效果

iOS,去背景色

效果還可以的樣子。

如果認真觀察HSV模型的同學也許會發現,我們通過指定色調角度(Hue)的方式,對于指定灰白黑顯得無能為力。我們不得不去用飽和度(Saturation)和明度(Value)去共同判斷,感興趣的同學可以在代碼中判斷Alpha float alpha = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) ? 0.0f: 1.0f;那里試一下效果。(至于代碼中為啥RGB和HSV這么轉換,請百度他們的轉換,因為鶸筆者也不懂。哎,鶸不聊生)

對于Core Image感興趣的同學,請移步大佬的系列文章

iOS8 Core Image In Swift:自動改善圖像以及內置濾鏡的使用

iOS8 Core Image In Swift:更復雜的濾鏡

iOS8 Core Image In Swift:人臉檢測以及馬賽克

iOS8 Core Image In Swift:視頻實時濾鏡

Core Graphics/Quarz 2D

上文中提到的基于OpenGlCore Image顯然功能十分強大,作為視圖另一基石的Core Graphics同樣強大。對他的探究,讓鶸筆者更多的了解到圖片的相關知識。所以在此處總結,供日后查閱。

如果對探究不感興趣的同學,請直接跳到文章最后 Masking an Image with Color 部分

Bitmap

iOS,去背景色

在Quarz 2D官方文檔中,對于BitMap有如下描述:

A bitmap image (or sampled image) is an array of pixels (or samples). Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.

32-bit and 16-bit pixel formats for CMYK and RGB color spaces in Quartz 2D

回到我們的需求,對于去除圖片中的指定顏色,如果我們能夠讀取到每個像素上的RGBA信息,分別判斷他們的值,如果符合目標范圍,我們將他的Alpha值改為0,然后輸出成新的圖片,那么我們就實現了類似上文中cubeMap的處理方式。

強大的Quarz 2D為我們提供了實現這種操作的能力,下面請看代碼示例:

- (UIImage *)removeColorWithMaxR:(float)maxR minR:(float)minR maxG:(float)maxG minG:(float)minG maxB:(float)maxB minB:(float)minB image:(UIImage *)image{ // 分配內存 const int imageWidth = image.size.width; const int imageHeight = image.size.height; size_t bytesPerRow = imageWidth * 4; uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight); // 創建context CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();// 色彩范圍的容器 CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage); // 遍歷像素 int pixelNum = imageWidth * imageHeight; uint32_t* pCurPtr = rgbImageBuf; for (int i = 0; i < pixelNum; i++, pCurPtr++) { uint8_t* ptr = (uint8_t*)pCurPtr; if (ptr[3] >= minR && ptr[3] <= maxR && ptr[2] >= minG && ptr[2] <= maxG && ptr[1] >= minB && ptr[1] <= maxB) { ptr[0] = 0; }else{ printf("/n---->ptr0:%d ptr1:%d ptr2:%d ptr3:%d<----/n",ptr[0],ptr[1],ptr[2],ptr[3]); } } // 將內存轉成image CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil); CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,NULL,true,kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];  // 釋放 CGImageRelease(imageRef); CGContextRelease(context); CGColorSpaceRelease(colorSpace); return resultUIImage;}

 

還記得我們在Core Image中提到的HSV模式的弊端嗎?那么Quarz 2D則是直接利用RGBA的信息進行處理,很好的規避了對黑白色不友好的問題,我們只需要設置一下RGB的范圍即可(因為黑白色在RGB顏色模式中,很好確定),我們可以大致封裝一下。如下

- (UIImage *)removeWhiteColorWithImage:(UIImage *)image{ return [self removeColorWithMaxR:255 minR:250 maxG:255 minG:240 maxB:255 minB:240 image:image];}
- (UIImage *)removeBlackColorWithImage:(UIImage *)image{ return [self removeColorWithMaxR:15 minR:0 maxG:15 minG:0 maxB:15 minB:0 image:image];}

看一下我們對于白色背景的處理效果對比

iOS,去背景色

看起來似乎還不錯,但是對于紗質的衣服,就顯得很不友好??匆幌鹿P者做的幾組圖片的測試

iOS,去背景色

很顯然,如果不是白色背景,“衣衫襤褸”的效果非常明顯。這個問題,在筆者嘗試的三種方法中,無一幸免,如果哪位大佬知道好的處理方法,而且能告訴鶸,將不勝感激。(先放倆膝蓋在這兒)

除了上述問題外,這種對比每個像素的方法,讀取出來的數值會同作圖時出現誤差。但是這種誤差肉眼基本不可見。

iOS,去背景色

如下圖中,我們作圖時,設置的RGB值分別為100/240/220 但是通過CG上述處理時,讀取出來的值則為92/241/220。對比圖中的“新的”“當前”,基本看不出色差。這點小問題各位知道就好,對實際去色效果影響并不大

iOS,去背景色

Masking an Image with Color

筆者嘗試過理解并使用上一種方法后,在重讀文檔時發現了這個方法,簡直就像是發現了Father Apple的恩賜。直接上代碼

- (UIImage *)removeColorWithMaxR:(float)maxR minR:(float)minR maxG:(float)maxG minG:(float)minG maxB:(float)maxB minB:(float)minB image:(UIImage *)image{ const CGFloat myMaskingColors[6] = {minR, maxR, minG, maxG, minB, maxB}; CGImageRef ref = CGImageCreateWithMaskingColors(image.CGImage, myMaskingColors); return [UIImage imageWithCGImage:ref]; }

官方文檔點這兒

總結

HSV顏色模式相對于RGB模式而言,更利于我們摳除圖片中的彩色,而RGB則正好相反。筆者因為項目中,只需要去除白色背景,所以最終采用了最后一種方式。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品国产福利| www.欧美精品| 亚洲石原莉奈一区二区在线观看| 国产精品永久免费| 国产一区二区三区三区在线观看| 日韩电影在线观看免费| 国产欧美韩国高清| 国产精品久久视频| 性欧美暴力猛交69hd| 秋霞成人午夜鲁丝一区二区三区| 日韩在线视频免费观看高清中文| www.亚洲一区| 亚洲性xxxx| 亚洲国产精品美女| 神马久久久久久| 久久久久一本一区二区青青蜜月| 欧美老妇交乱视频| 国产午夜精品美女视频明星a级| 日本久久亚洲电影| 久久久精品国产网站| 亚洲综合大片69999| 亚洲第一页自拍| 亚洲精品视频在线播放| 国产精品69精品一区二区三区| 亚洲综合中文字幕在线观看| 97福利一区二区| 国产成+人+综合+亚洲欧洲| 自拍偷拍亚洲在线| 亚洲精品99久久久久| 欧美老女人性生活| 有码中文亚洲精品| 国产日韩视频在线观看| 欧美亚洲日本黄色| 国产精品日韩久久久久| 亚洲精品自在久久| 欧美多人乱p欧美4p久久| 成人在线视频福利| 日韩免费观看在线观看| 国产精品一久久香蕉国产线看观看| 亚洲国内精品在线| 久久久免费精品视频| 黑人巨大精品欧美一区二区一视频| 亚洲一区久久久| 欧美美女18p| 亚洲香蕉成人av网站在线观看| 亚洲免费小视频| 国产精品高清在线| 日韩欧美亚洲范冰冰与中字| 欧美大尺度激情区在线播放| 日韩精品视频在线免费观看| 国产精品一区久久久| 欧美性xxxx极品hd欧美风情| 麻豆精品精华液| 欧美激情一级精品国产| 色综合视频网站| 久久久亚洲影院你懂的| 国产视频福利一区| 美女精品视频一区| 欧美激情videoshd| 久久免费观看视频| 亚洲欧美日韩国产中文专区| 97久久精品视频| 成人精品视频在线| 国产成人精品久久久| 5278欧美一区二区三区| 国产成人在线视频| 日韩激情av在线免费观看| 中文字幕精品影院| 久久久91精品国产| 九九热这里只有精品6| 亚洲视频一区二区三区| 久久久噜噜噜久久久| 欧美电影免费观看高清| 午夜精品久久久久久99热| 国产98色在线| 欧美国产日韩精品| 亚洲国产另类 国产精品国产免费| 国产一区二区三区在线看| 日韩在线国产精品| 久久综合88中文色鬼| 久久在线免费视频| 久久国产精品久久久| 黄色一区二区在线| 日韩av一区在线观看| 正在播放欧美视频| 欧美极度另类性三渗透| 欧美日韩中文字幕日韩欧美| 日韩最新在线视频| 亚洲精品视频网上网址在线观看| 日韩av观看网址| 亚洲一二在线观看| 国产日产欧美a一级在线| 色噜噜国产精品视频一区二区| 亚洲免费av片| 亚洲欧美制服另类日韩| 亚洲片国产一区一级在线观看| 欧美性视频精品| 亚洲精品中文字| 亚洲人成电影在线| 亚洲伦理中文字幕| 欧美一级成年大片在线观看| 欧美日韩国产精品| 欧美精品生活片| 成人免费网视频| 精品视频偷偷看在线观看| 91亚洲精品视频| 精品成人久久av| 国产精品爽爽爽爽爽爽在线观看| 午夜精品国产精品大乳美女| 91久久综合亚洲鲁鲁五月天| 亚洲国产成人精品久久久国产成人一区| 91精品久久久久久久久久久久久久| 国产成人久久久精品一区| 成人a级免费视频| 国产精品免费视频xxxx| 8x海外华人永久免费日韩内陆视频| 亚洲国产欧美一区二区三区久久| 欧美性高潮床叫视频| 亚洲女人天堂网| 亚洲一区二区久久久久久久| 亚洲丝袜av一区| 欧美性猛交xxxx偷拍洗澡| 色偷偷av亚洲男人的天堂| 成人午夜高潮视频| 91精品在线观看视频| 欧美久久精品一级黑人c片| 国产欧美日韩免费看aⅴ视频| 国产精品com| 欧美一区亚洲一区| 精品中文字幕在线| 高清欧美性猛交xxxx黑人猛交| 久久久久一本一区二区青青蜜月| 国产精品pans私拍| 成人午夜激情网| 精品国产欧美一区二区五十路| 亚洲老板91色精品久久| 色琪琪综合男人的天堂aⅴ视频| 亚洲bt欧美bt日本bt| 欧美乱人伦中文字幕在线| 日韩小视频在线观看| 国产欧美日韩丝袜精品一区| 欧美日韩国产va另类| 精品动漫一区二区三区| 国产精品av电影| 这里只有精品在线观看| 狠狠色狠狠色综合日日五| 国产精品美乳一区二区免费| 国产欧洲精品视频| 2019中文字幕在线免费观看| 日本成熟性欧美| 色在人av网站天堂精品| 精品亚洲夜色av98在线观看| 国产91免费看片| 激情成人在线视频| 亚洲aⅴ日韩av电影在线观看| 欧美性猛交xxxx免费看久久久| 国产午夜精品一区理论片飘花| 色综合男人天堂| 免费不卡在线观看av| 日本精品一区二区三区在线| 亚洲欧美国产日韩天堂区| 欧美视频在线观看免费网址| 亚洲欧美日本精品| 亚洲人成电影在线|