iOS高效图片圆角裁剪方法

自定义裁剪算法

- (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);
}

核心方法

   // 裁剪圆角
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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 版权声明:本文为博主原创文章,未经博主允许不得转载 前言 Canvas 本意是画布的意思,然而将它理解为绘制工具一...
    cc荣宣阅读 41,655评论 1 47
  • 缘起 自己画图在平常开发中不算很常见的需求,但偶尔有些需求还必须通过Canvas自己画出来,最近笔者就遇到了这样的...
    tmp_zhao阅读 1,960评论 1 30
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,679评论 25 708
  • 如果把沿路的思想活出了答案 如果把独自的孤独变成了勇敢 谁还会愿意一次次失去却又重新来 在黑夜里奔跑 寻找遥远的安...
    路小飞小飞阅读 304评论 1 2
  • 又是周六的傍晚,看着窗外慢慢蔓延的晚霞,不知不觉感叹一周时光的飞逝。 有时候,人走在社会的浪潮中容易被淹没甚至从未...
    hi少女心阅读 268评论 0 0