激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - IOS - iOS去除圖片背景顏色的方法

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

2021-04-12 10:51segmentfault IOS

本篇文章給大家分享一下iOS去除圖片中指定范圍內顏色的三種方式,需要的朋友參考學習下吧。

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

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

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,如果直接拿來用,會出現不顯示的情況。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
- (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在官方文檔中并沒有提及,筆者在下文中提到的大佬的博客中找到了相關轉換處理。感謝

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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

調用一下方法試一下

?
1
[[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.

?
1
32-bit and 16-bit pixel formats for cmyk and rgb color spaces in quartz 2d

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- (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顏色模式中,很好確定),我們可以大致封裝一下。如下

?
1
2
3
- (uiimage *)removewhitecolorwithimage:(uiimage *)image{
 return [self removecolorwithmaxr:255 minr:250 maxg:255 ming:240 maxb:255 minb:240 image:image];
}
?
1
2
3
- (uiimage *)removeblackcolorwithimage:(uiimage *)image{
 return [self removecolorwithmaxr:15 minr:0 maxg:15 ming:0 maxb:15 minb:0 image:image];
}

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

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

看起來似乎還不錯,但是對于紗質的衣服,就顯得很不友好。看一下筆者做的幾組圖片的測試

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

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

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

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

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

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

masking an image with color

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

?
1
2
3
4
5
6
- (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則正好相反。筆者因為項目中,只需要去除白色背景,所以最終采用了最后一種方式。

原文鏈接:https://segmentfault.com/a/1190000012523188

延伸 · 閱讀

精彩推薦
  • IOSiOS開發技巧之狀態欄字體顏色的設置方法

    iOS開發技巧之狀態欄字體顏色的設置方法

    有時候我們需要根據不同的背景修改狀態欄字體的顏色,下面這篇文章主要給大家介紹了關于iOS開發技巧之狀態欄字體顏色的設置方法,文中通過示例代碼...

    夢想家-mxj8922021-05-10
  • IOS詳解iOS中多個網絡請求的同步問題總結

    詳解iOS中多個網絡請求的同步問題總結

    這篇文章主要介紹了詳解iOS中多個網絡請求的同步問題總結,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    liang199111312021-03-15
  • IOSiOS實現控制屏幕常亮不變暗的方法示例

    iOS實現控制屏幕常亮不變暗的方法示例

    最近在工作中遇到了要將iOS屏幕保持常亮的需求,所以下面這篇文章主要給大家介紹了關于利用iOS如何實現控制屏幕常亮不變暗的方法,文中給出了詳細的...

    隨風13332021-04-02
  • IOSiOS開發之視圖切換

    iOS開發之視圖切換

    在iOS開發中視圖的切換是很頻繁的,獨立的視圖應用在實際開發過程中并不常見,除非你的應用足夠簡單。在iOS開發中常用的視圖切換有三種,今天我們將...

    執著丶執念5282021-01-16
  • IOSiOS中UILabel實現長按復制功能實例代碼

    iOS中UILabel實現長按復制功能實例代碼

    在iOS開發過程中,有時候會用到UILabel展示的內容,那么就設計到點擊UILabel復制它上面展示的內容的功能,也就是Label長按復制功能,下面這篇文章主要給大...

    devilx12792021-04-02
  • IOSiOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)

    iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和

    這篇文章主要介紹了iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)的相關資料,需要的朋友可以參考下...

    CodingFire13652021-02-26
  • IOSiOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    這篇文章主要介紹了iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果的相關資料,需要的朋友可以參考下...

    jiangamh8882021-01-11
  • IOSiOS中MD5加密算法的介紹和使用

    iOS中MD5加密算法的介紹和使用

    MD5加密是最常用的加密方法之一,是從一段字符串中通過相應特征生成一段32位的數字字母混合碼。對輸入信息生成唯一的128位散列值(32個字符)。這篇文...

    LYSNote5432021-02-04
主站蜘蛛池模板: 国产一级爱c视频 | 色播av在线 | 最新av在线免费观看 | 亚洲尻逼视频 | 亚洲综合一区在线观看 | 一级大片一级一大片 | 激情小说激情电影 | 51国产偷自视频区视频小蝌蚪 | 国产日本欧美在线观看 | 国产精品午夜小视频观看 | 九九视屏 | 国产精品午夜未成人免费观看 | 香蕉视频1024| 久久精品国产99国产精品澳门 | 欧美一级毛片免费观看 | 日日摸夜夜添夜夜添牛牛 | 亚洲精品欧美二区三区中文字幕 | 9999视频| 国产精品刺激对白麻豆99 | asian附近女人裸体pics | 国产精品久久久久久久久久久天堂 | 成年免费看 | 成人 日韩 | 日本久久视频 | 免费观看高清视频网站 | 亚洲第一成人久久网站 | 日韩精品久久久久久久电影99爱 | 最新中文字幕免费视频 | 中国的免费的视频 | 国产一国产一级毛片视频 | 久久久久久艹 | a集毛片| 男女一边摸一边做羞羞视频免费 | 久久久久在线观看 | 国产精品久久久久久影视 | 国产精品亚洲欧美一级在线 | 国产18成人免费视频 | 亚洲一区二区在线视频 | av噜噜在线 | 国产三级国产精品国产普男人 | 污版视频在线观看 |