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

首頁 > 系統 > iOS > 正文

iOS實現高效裁剪圖片圓角算法教程

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

前言

項目有個需求:裁剪圖片,針對頭像,下面是要求:

 iOS,裁剪圖片,圓角算法

大家可以看到這張圖片的圓角已經去除,下面說說我在項目利用了兩種方式實現此裁剪以及查看技術文檔發現更高效裁剪方式,下面一一講解:看下來大約需要15-20分鐘。

在公共類中Util類中創建類方法

1.CGContext裁剪

//CGContext裁剪+ (UIImage *)CGContextClip:(UIImage *)img cornerRadius:(CGFloat)c;

實現該方法:

// CGContext 裁剪+ (UIImage *)CGContextClip:(UIImage *)img cornerRadius:(CGFloat)c{ int w = img.size.width * img.scale; int h = img.size.height * img.scale; UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), false, 1.0); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextMoveToPoint(context, 0, c); CGContextAddArcToPoint(context, 0, 0, c, 0, c); CGContextAddLineToPoint(context, w-c, 0); CGContextAddArcToPoint(context, w, 0, w, c, c); CGContextAddLineToPoint(context, w, h-c); CGContextAddArcToPoint(context, w, h, w-c, h, c); CGContextAddLineToPoint(context, c, h); CGContextAddArcToPoint(context, 0, h, 0, h-c, c); CGContextAddLineToPoint(context, 0, c); CGContextClosePath(context);  // 先裁剪 context,再畫圖,就會在裁剪后的 path 中畫 CGContextClip(context); [img drawInRect:CGRectMake(0, 0, w, h)]; // 畫圖 CGContextDrawPath(context, kCGPathFill); UIImage *ret = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();  return ret;}

在該需要的地方調用如下:

[Util CGContextClip:image cornerRadius:radius];

2.UIBezierPath 裁剪

在Util.h類中聲明

//UIBezierPath 裁剪+ (UIImage *)UIBezierPathClip:(UIImage *)img cornerRadius:(CGFloat)c;

在Util.m實現方法

//UIBezierPath 裁剪+ (UIImage *)UIBezierPathClip:(UIImage *)img cornerRadius:(CGFloat)c{ int w = img.size.width * img.scale; int h = img.size.height * img.scale; CGRect rect = CGRectMake(0, 0, w, h); UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), false, 1.0); [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:c] addClip]; [img drawInRect:rect];  UIImage *ret = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return ret;}

3.空域處理的辦法,寫個裁剪圓角的算法

對于圖像上的一個點(x, y),判斷其在不在圓角矩形內,在的話 alpha 是原值,不在的話 alpha 設為 0 即可

iOS,裁剪圖片,圓角算法

遍歷所有像素,判斷每個像素在不在4個圓的圓內就行了,4個角,每個角有一個四分之一的圓。

一個優化就是,我不需要遍歷全部的像素就能裁出圓角,只需要考慮類似左下角三角形的區域就行了,左下,左上,右上,右下,一共4個三角形區域(另外3個圖中沒畫出),for循環的時候,就循環這個4個三角形區域就行了。

所以對于一幅 w * h 的圖像,設圓角大小為 n,n <= min(w, h) / 2,其復雜度為 O(n) = 2(n^2),最壞的情況計算量也不會超過 wh / 2。

對于一個像素點(x, y),判斷其在不在圓內的公式:
如果  (x-cx)^2 + (y-cy)^2 <= r^2  就表示點 (x, y) 在圓內,反之不在。通過測試:此算法效率可以提高幾倍之上(時間)

在Util.h中聲明:

+ (UIImage *)dealImage:(UIImage *)img cornerRadius:(CGFloat)c

在Util.m中實現:

+ (UIImage *)dealImage:(UIImage *)img cornerRadius:(CGFloat)c { // 1.CGDataProviderRef 把 CGImage 轉 二進制流 CGDataProviderRef provider = CGImageGetDataProvider(img.CGImage); void *imgData = (void *)CFDataGetBytePtr(CGDataProviderCopyData(provider)); int width = img.size.width * img.scale; int height = img.size.height * img.scale;  // 2.處理 imgData// dealImage(imgData, width, height); cornerImage(imgData, width, height, c);  // 3.CGDataProviderRef 把 二進制流 轉 CGImage CGDataProviderRef pv = CGDataProviderCreateWithData(NULL, imgData, width * height * 4, releaseData); CGImageRef content = CGImageCreate(width , height, 8, 32, 4 * width, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, pv, NULL, true, kCGRenderingIntentDefault); UIImage *result = [UIImage imageWithCGImage:content]; CGDataProviderRelease(pv); // 釋放空間 CGImageRelease(content);  return result;}void releaseData(void *info, const void *data, size_t size) { free((void *)data);}// 在 img 上處理圖片, 測試用void dealImage(UInt32 *img, int w, int h) { int num = w * h; UInt32 *cur = img; for (int i=0; i<num; i++, cur++) { UInt8 *p = (UInt8 *)cur; // RGBA 排列 // f(x) = 255 - g(x) 求負片 p[0] = 255 - p[0]; p[1] = 255 - p[1]; p[2] = 255 - p[2]; p[3] = 255; }}// 裁剪圓角void cornerImage(UInt32 *const img, int w, int h, CGFloat cornerRadius) { CGFloat c = cornerRadius; CGFloat min = w > h ? h : w;  if (c < 0) { c = 0; } if (c > min * 0.5) { c = min * 0.5; }  // 左上 y:[0, c), x:[x, c-y) for (int y=0; y<c; y++) { for (int x=0; x<c-y; x++) {  UInt32 *p = img + y * w + x; // p 32位指針,RGBA排列,各8位  if (isCircle(c, c, c, x, y) == false) {  *p = 0;  } } } // 右上 y:[0, c), x:[w-c+y, w) int tmp = w-c; for (int y=0; y<c; y++) { for (int x=tmp+y; x<w; x++) {  UInt32 *p = img + y * w + x;  if (isCircle(w-c, c, c, x, y) == false) {  *p = 0;  } } } // 左下 y:[h-c, h), x:[0, y-h+c) tmp = h-c; for (int y=h-c; y<h; y++) { for (int x=0; x<y-tmp; x++) {  UInt32 *p = img + y * w + x;  if (isCircle(c, h-c, c, x, y) == false) {  *p = 0;  } } } // 右下 y~[h-c, h), x~[w-c+h-y, w) tmp = w-c+h; for (int y=h-c; y<h; y++) { for (int x=tmp-y; x<w; x++) {  UInt32 *p = img + y * w + x;  if (isCircle(w-c, h-c, c, x, y) == false) {  *p = 0;  } } }}// 判斷點 (px, py) 在不在圓心 (cx, cy) 半徑 r 的圓內static inline bool isCircle(float cx, float cy, float r, float px, float py) { if ((px-cx) * (px-cx) + (py-cy) * (py-cy) > r * r) { return false; } return true;}// 其他圖像效果可以自己寫函數,然后在 dealImage: 中調用 otherImage 即可void otherImage(UInt32 *const img, int w, int h) { // 自定義處理}

上面是三種方式,可以解決圖片裁剪的需求,

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久久久久免费| 久久久久久国产免费| 欧美午夜激情视频| 懂色av影视一区二区三区| 亚洲在线视频观看| 精品欧美国产一区二区三区| 久久久精品2019中文字幕神马| 国产欧美精品va在线观看| 日韩精品在线观看网站| 国产日韩欧美自拍| 久久精品国产视频| 成人久久一区二区| 中文字幕亚洲激情| 久久色在线播放| 亚洲激情视频在线| 亚洲女人天堂网| 91视频国产一区| 久久久久久久久久婷婷| 亚洲xxxxx| 国产精品日韩久久久久| 国产日韩精品一区二区| 欧美人交a欧美精品| 欧美日韩福利在线观看| 麻豆国产va免费精品高清在线| 4k岛国日韩精品**专区| 久久人91精品久久久久久不卡| 中文字幕日韩av综合精品| 中文字幕视频一区二区在线有码| 欧美日韩免费区域视频在线观看| 91精品综合视频| 中文字幕日韩精品有码视频| 国产精品视频免费观看www| 久久人人爽人人爽人人片av高请| 中文字幕亚洲国产| 欧美电影免费观看高清| 亚洲一区二区三区四区在线播放| 国产精品成人av在线| 欧美精品一区三区| 成人国内精品久久久久一区| 97视频免费在线看| 日韩中文综合网| 红桃av永久久久| 精品久久久一区二区| 亚洲性av网站| 亚洲国产免费av| 亚洲欧洲黄色网| 日韩最新免费不卡| 国模叶桐国产精品一区| 亚洲综合视频1区| 91精品国产高清久久久久久| 91在线视频免费| 亚洲网站在线播放| 日韩成人激情视频| 欧美一区二区色| 亚洲美女在线视频| 久久国产精品99国产精| 日韩男女性生活视频| 亚洲japanese制服美女| 亚洲欧美日韩天堂一区二区| 国产福利精品视频| 不卡中文字幕av| 亚洲一区二区国产| 日本精品中文字幕| 欧美日韩国产精品一区二区三区四区| 国产精品亚洲精品| 91久久精品国产91久久性色| 97久久精品视频| 97色在线观看| 国产91在线高潮白浆在线观看| 国产精品成av人在线视午夜片| 92国产精品视频| 久久久999国产精品| 亚洲高清不卡av| 国产综合在线观看视频| 国产精品亚发布| 最近2019中文字幕第三页视频| 久久精品国产99国产精品澳门| 精品无人国产偷自产在线| 欧美一区二区三区精品电影| 欧美亚洲在线视频| 亚洲女人天堂视频| 日韩精品免费在线播放| 欧美成人中文字幕| 成人网在线免费看| 国产亚洲一级高清| 国产一区私人高清影院| 亚洲黄色av女优在线观看| 欧美一级黄色网| 久久久91精品| 国产主播喷水一区二区| 精品久久香蕉国产线看观看gif| 中文字幕欧美亚洲| www日韩欧美| 亚洲的天堂在线中文字幕| 91久久久久久久| 日韩av免费在线观看| 日韩欧美综合在线视频| 欧美美最猛性xxxxxx| 欧美日韩性生活视频| 伊人久久综合97精品| 成人免费视频97| 亚洲精品国偷自产在线99热| 日韩美女中文字幕| 亚洲福利视频久久| 国产日韩欧美黄色| 欧美极品在线视频| 日韩电影网在线| 中文字幕日韩免费视频| 欧美另类交人妖| 国产精品亚洲第一区| 美女视频久久黄| 97视频在线看| 伊人久久久久久久久久久久久| 在线观看亚洲视频| 日韩中文字幕网站| 亚洲精品一区在线观看香蕉| 色综合久久天天综线观看| 欧美黑人性生活视频| 亚洲最大av在线| 日韩一区二区欧美| 日韩精品久久久久久福利| 国内精品久久久久影院 日本资源| 国产99久久精品一区二区 夜夜躁日日躁| 人人做人人澡人人爽欧美| 色偷偷偷亚洲综合网另类| 91精品视频网站| 欧美性猛交xxx| 久久免费视频网| 国产欧美一区二区三区在线| 欧美多人爱爱视频网站| 国产精品国产福利国产秒拍| 国产精品99导航| 久久亚洲精品国产亚洲老地址| 日韩经典中文字幕在线观看| www.日韩免费| 国产精品主播视频| 日韩av一区二区在线观看| 2021久久精品国产99国产精品| 一本色道久久综合亚洲精品小说| 综合激情国产一区| 欧美日韩国产123| 欧美三级免费观看| 日韩av免费观影| 欧美精品九九久久| 欧美巨乳在线观看| 国产亚洲精品一区二区| 国产一区二区在线播放| 欧美一级电影久久| 欧美激情小视频| 欧美性猛交xxxx久久久| 欧美日韩国产一区中文午夜| 最近2019好看的中文字幕免费| 亚洲最大中文字幕| 欧美亚洲免费电影| 国产精品丝袜一区二区三区| 久久全国免费视频| 亚洲电影免费观看高清完整版| 亚洲国产精品悠悠久久琪琪| 午夜精品在线视频| 97香蕉超级碰碰久久免费软件| 精品在线观看国产| 国产91ⅴ在线精品免费观看| 久久精品国产清自在天天线| 亚洲欧美第一页|