UIImage分类大全

作者: 秦明Qinmin | 来源:发表于2017-10-10 18:42 被阅读302次

    在处理照片的时候,最多的情况就是对UIImage进行处理。虽然UIImage使用起来比较简单,但是我们在需要处理各种繁杂需求的时候,UIImage不是都提供了相关效果的实现。很多时候需要我们自己来实现比较复杂的处理。比如,相机拍摄的图片带有方向,有时候你会发现通过 CGImageGetWidth,CGImageGetHeight获取宽高相反,或者上传的图片,在安卓上方向不对,这时候就需要纠正图片的方向。因此,常备一些分类是很有必要的,以下在开发的过程中,一些常见的UIImage的处理分类。

    判断图片是否有Alpha通道
    - (BOOL)hasAlpha
    {
        CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
        return (alpha == kCGImageAlphaFirst ||
                alpha == kCGImageAlphaLast ||
                alpha == kCGImageAlphaPremultipliedFirst ||
                alpha == kCGImageAlphaPremultipliedLast);
    }
    
    获取图片的元数据
    - (NSData *)ARGBData
    {
        CGContextRef cgctx = CreateARGBBitmapContextWithCGImage(self.CGImage);
        
        if (cgctx == NULL) {
            return nil;
        }
        
        size_t w = CGImageGetWidth(self.CGImage);
        size_t h = CGImageGetHeight(self.CGImage);
        CGRect rect = {{0,0},{w,h}};
        
        CGContextDrawImage(cgctx, rect, self.CGImage);
    
        void *data = CGBitmapContextGetData (cgctx);
        
        CGContextRelease(cgctx);
        
        if (!data) {
            return nil;
        }
        
        size_t dataSize = 4 * w * h; // ARGB = 4 8-bit components
        
        return [NSData dataWithBytes:data length:dataSize];
    }
    
    图片的某一点是否透明
    - (BOOL)isPointTransparent:(CGPoint)point
    {
        NSData *rawData = [self ARGBData];  // See about caching this
        if (rawData == nil) {
            return NO;
        }
    
        size_t bitPerPoint = 4;//每个像素有4位
        size_t bitPerRow = self.size.width * 4; //每一行的像素
        
        NSUInteger index = point.x * bitPerPoint + (point.y * bitPerRow);
        
        char *rawDataBytes = ( char *)[rawData bytes];
        
        return rawDataBytes[index] == 0;
    }
    
    根据颜色生成图片
    + (UIImage *)imageWithColor:(UIColor *)color
    {
        CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
        
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return image;
    }
    
    获取灰度图
    - (UIImage *)grayImage
    {
        int width = self.size.width;
        int height = self.size.height;
        
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
        CGContextRef context = CGBitmapContextCreate(nil,width,height,8,0,colorSpace,kCGImageAlphaNone);
        CGColorSpaceRelease(colorSpace);
        
        if (context == NULL)
        {
            return nil;
        }
        
        CGContextDrawImage(context,CGRectMake(0, 0, width, height), self.CGImage);
        CGImageRef contextRef = CGBitmapContextCreateImage(context);
        UIImage *grayImage = [UIImage imageWithCGImage:contextRef];
        CGContextRelease(context);
        CGImageRelease(contextRef);
        
        return grayImage;
    }
    
    取图片某像素点的颜色
    - (UIColor *)colorAtPixel:(CGPoint)point
    {
        if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point))
        {
            return nil;
        }
        
        NSInteger pointX = trunc(point.x);
        NSInteger pointY = trunc(point.y);
        CGImageRef cgImage = self.CGImage;
        NSUInteger width = self.size.width;
        NSUInteger height = self.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);
        
        CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
        CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
        CGContextRelease(context);
        
        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];
    }
    
    圆角绘制
    - (UIImage *)imageWithConrnerWithRadius:(CGFloat)radius sizeToFit:(CGSize)size
    {
        
        CGRect rect = CGRectMake(0, 0, size.width, size.height);
        
        UIGraphicsBeginImageContextWithOptions(rect.size, false, [UIScreen mainScreen].scale);
        
        CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)].CGPath);
        
        CGContextClip(UIGraphicsGetCurrentContext());
        
        [self drawInRect:rect];
        
        CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
        
        UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
        
        UIGraphicsEndImageContext();
        
        return output;
        
    }
    
    纠正图片的方向
    - (UIImage *)fixOrientation
    {
        if (self.imageOrientation == UIImageOrientationUp) return self;
        
        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        CGAffineTransform transform = CGAffineTransformIdentity;
        
        switch (self.imageOrientation)
        {
            case UIImageOrientationDown:
            case UIImageOrientationDownMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
                transform = CGAffineTransformRotate(transform, M_PI);
                break;
                
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, 0);
                transform = CGAffineTransformRotate(transform, M_PI_2);
                break;
                
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                transform = CGAffineTransformTranslate(transform, 0, self.size.height);
                transform = CGAffineTransformRotate(transform, -M_PI_2);
                break;
            case UIImageOrientationUp:
            case UIImageOrientationUpMirrored:
                break;
        }
        
        switch (self.imageOrientation)
        {
            case UIImageOrientationUpMirrored:
            case UIImageOrientationDownMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, 0);
                transform = CGAffineTransformScale(transform, -1, 1);
                break;
                
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRightMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.height, 0);
                transform = CGAffineTransformScale(transform, -1, 1);
                break;
            case UIImageOrientationUp:
            case UIImageOrientationDown:
            case UIImageOrientationLeft:
            case UIImageOrientationRight:
                break;
        }
        
        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                                 CGImageGetBitsPerComponent(self.CGImage), 0,
                                                 CGImageGetColorSpace(self.CGImage),
                                                 CGImageGetBitmapInfo(self.CGImage));
        CGContextConcatCTM(ctx, transform);
        
        switch (self.imageOrientation)
        {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
                break;
                
            default:
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
                break;
        }
        
        CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
        UIImage *img = [UIImage imageWithCGImage:cgimg];
        CGContextRelease(ctx);
        CGImageRelease(cgimg);
        
        return img;
    }
    
    按给定的方向旋转图片
    - (UIImage*)rotate:(UIImageOrientation)orient
    {
        CGRect bnds = CGRectZero;
        UIImage* copy = nil;
        CGContextRef ctxt = nil;
        CGImageRef imag = self.CGImage;
        CGRect rect = CGRectZero;
        CGAffineTransform tran = CGAffineTransformIdentity;
        
        rect.size.width = CGImageGetWidth(imag);
        rect.size.height = CGImageGetHeight(imag);
        
        bnds = rect;
        
        switch (orient)
        {
            case UIImageOrientationUp:
                return self;
                
            case UIImageOrientationUpMirrored:
                tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
                tran = CGAffineTransformScale(tran, -1.0, 1.0);
                break;
                
            case UIImageOrientationDown:
                tran = CGAffineTransformMakeTranslation(rect.size.width,
                                                        rect.size.height);
                tran = CGAffineTransformRotate(tran, M_PI);
                break;
                
            case UIImageOrientationDownMirrored:
                tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
                tran = CGAffineTransformScale(tran, 1.0, -1.0);
                break;
                
            case UIImageOrientationLeft:
                bnds = swapWidthAndHeight(bnds);
                tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
                tran = CGAffineTransformRotate(tran, 3.0 * M_PI / 2.0);
                break;
                
            case UIImageOrientationLeftMirrored:
                bnds = swapWidthAndHeight(bnds);
                tran = CGAffineTransformMakeTranslation(rect.size.height,
                                                        rect.size.width);
                tran = CGAffineTransformScale(tran, -1.0, 1.0);
                tran = CGAffineTransformRotate(tran, 3.0 * M_PI / 2.0);
                break;
                
            case UIImageOrientationRight:
                bnds = swapWidthAndHeight(bnds);
                tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
                tran = CGAffineTransformRotate(tran, M_PI / 2.0);
                break;
                
            case UIImageOrientationRightMirrored:
                bnds = swapWidthAndHeight(bnds);
                tran = CGAffineTransformMakeScale(-1.0, 1.0);
                tran = CGAffineTransformRotate(tran, M_PI / 2.0);
                break;
                
            default:
                return self;
        }
        
        UIGraphicsBeginImageContext(bnds.size);
        ctxt = UIGraphicsGetCurrentContext();
        
        switch (orient)
        {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                CGContextScaleCTM(ctxt, -1.0, 1.0);
                CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
                break;
                
            default:
                CGContextScaleCTM(ctxt, 1.0, -1.0);
                CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
                break;
        }
        
        CGContextConcatCTM(ctxt, tran);
        CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, imag);
        
        copy = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return copy;
    }
    
    垂直翻转
    - (UIImage *)flipVertical
    {
        return [self rotate:UIImageOrientationDownMirrored];
    }
    
    水平翻转
    - (UIImage *)flipHorizontal
    {
        return [self rotate:UIImageOrientationUpMirrored];
    }
    
    
    将图片旋转一定弧度
    - (UIImage *)imageRotatedByRadians:(CGFloat)radians
    {
        // calculate the size of the rotated view's containing box for our drawing space
        UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
        CGAffineTransform t = CGAffineTransformMakeRotation(radians);
        rotatedViewBox.transform = t;
        CGSize rotatedSize = rotatedViewBox.frame.size;
        
        // Create the bitmap context
        UIGraphicsBeginImageContext(rotatedSize);
        CGContextRef bitmap = UIGraphicsGetCurrentContext();
        
        // Move the origin to the middle of the image so we will rotate and scale around the center.
        CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
        
        //   // Rotate the image context
        CGContextRotateCTM(bitmap, radians);
        
        // Now, draw the rotated/scaled image into the context
        CGContextScaleCTM(bitmap, 1.0, -1.0);
        CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);
        
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return newImage;
    }
    
    将图片旋转一定角度
    - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees
    {
        return [self imageRotatedByRadians:kDegreesToRadian(degrees)];
    }
    
    图片加马赛克
    - (UIImage *)mosaicImageWithLevel:(int)level
    {
        CIContext *context = [CIContext contextWithOptions:nil];
        CIFilter *filter= [CIFilter filterWithName:@"CIPixellate"];
        CIImage *inputImage = [CIImage imageWithCGImage:self.CGImage];
        CIVector *vector = [CIVector vectorWithX:self.size.width /2.0f Y:self.size.height /2.0f];
        [filter setDefaults];
        [filter setValue:vector forKey:@"inputCenter"];
        [filter setValue:[NSNumber numberWithDouble:level] forKey:@"inputScale"];
        [filter setValue:inputImage forKey:@"inputImage"];
        
        CGImageRef cgiimage = [context createCGImage:filter.outputImage fromRect:filter.outputImage.extent];
        UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:self.scale orientation:self.imageOrientation];
        
        CGImageRelease(cgiimage);
        
        return newImage;
    }
    
    图片混合裁剪
    + (UIImage *)clipImage:(UIImage *)aImage CGBlendMode:(int)type;
    + (UIImage *)clipImage:(UIImage *)image withRect:(CGRect)rect;
    + (UIImage *)cropImage:(UIImage *)image
                     frame:(CGRect)frame
                     angle:(NSInteger)angle
              circularClip:(BOOL)circular;
    
    
    + (UIImage *)clipImage:(UIImage *)aImage CGBlendMode:(int)type
    {
        CGContextRef context = CreateRGBABitmapContextWithCGImage(aImage.CGImage);
        
        if (context == NULL) {
            return nil;
        }
        
        size_t w = CGImageGetWidth(aImage.CGImage);
        size_t h = CGImageGetHeight(aImage.CGImage);
        CGRect rect = {{0, 0}, {w, h}};
        
        CGContextSetBlendMode(context, type);
        CGContextDrawImage(context, rect, aImage.CGImage);
        
        
        CGImageRef aCGImage = CGBitmapContextCreateImage(context);
        
        UIImage *newImage = [UIImage imageWithCGImage:aCGImage];
        
        CGImageRelease(aCGImage);
        CGContextRelease(context);
        
        return newImage;
    }
    
    + (UIImage *)clipImage:(UIImage *)image withRect:(CGRect)rect
    {
        CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
        UIImage *tmpImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
        
        return tmpImage;
    }
    
    + (UIImage *)cropImage:(UIImage *)image
                     frame:(CGRect)frame
                     angle:(NSInteger)angle
              circularClip:(BOOL)circular
    {
        CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image.CGImage);
        BOOL hasAlpha = (alphaInfo == kCGImageAlphaFirst || alphaInfo == kCGImageAlphaLast ||
                         alphaInfo == kCGImageAlphaPremultipliedFirst || alphaInfo == kCGImageAlphaPremultipliedLast);
        
        UIImage *croppedImage = nil;
        UIGraphicsBeginImageContextWithOptions(frame.size, !hasAlpha && !circular, [UIScreen mainScreen].scale);
        {
            CGContextRef context = UIGraphicsGetCurrentContext();
            
            if (circular) {
                CGContextAddEllipseInRect(context, (CGRect){CGPointZero, frame.size});
                CGContextClip(context);
            }
            
            //To conserve memory in not needing to completely re-render the image re-rotated,
            //map the image to a view and then use Core Animation to manipulate its rotation
            if (angle != 0) {
                UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
                imageView.layer.minificationFilter = kCAFilterNearest;
                imageView.layer.magnificationFilter = kCAFilterNearest;
                imageView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, angle * (M_PI/180.0f));
                CGRect rotatedRect = CGRectApplyAffineTransform(imageView.bounds, imageView.transform);
                UIView *containerView = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, rotatedRect.size}];
                [containerView addSubview:imageView];
                imageView.center = containerView.center;
                CGContextTranslateCTM(context, -frame.origin.x, -frame.origin.y);
                [containerView.layer renderInContext:context];
            }
            else {
                CGContextTranslateCTM(context, -frame.origin.x, -frame.origin.y);
                [image drawAtPoint:CGPointZero];
            }
            
            croppedImage = UIGraphicsGetImageFromCurrentImageContext();
        }
        UIGraphicsEndImageContext();
        
        return [UIImage imageWithCGImage:croppedImage.CGImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
    }
    
    图片模糊
    // 图片的高斯模糊
    - (UIImage *)gaussianBlurImageWithLevel:(CGFloat)blur
    {
        CIImage *inputImage = [CIImage imageWithCGImage:self.CGImage];
        CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur" keysAndValues:kCIInputImageKey, inputImage, @"inputRadius", @(blur), nil];
        
        CIImage *outputImage = filter.outputImage;
        
        CGImageRef outImage = [[CIContext contextWithOptions:nil] createCGImage:outputImage
                                                 fromRect:[outputImage extent]];
        UIImage *image = [UIImage imageWithCGImage:outImage];
        CGImageRelease(outImage);
        return image;
    }
    
    // Box Blur
    + (UIImage *)boxBlurImage:(UIImage *)image withLevel:(CGFloat)level
    {
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 5.0 ) {
            return nil;
        }
        CFAbsoluteTime t0 = CFAbsoluteTimeGetCurrent();
        
        if ((level < 0.0f) || (level > 1.0f)) {
            level = 0.5f;
        }
        
        int boxSize = (int)(level * 100);
        boxSize -= (boxSize % 2) + 1;
        
        CGImageRef img = image.CGImage;
        
        vImage_Buffer inBuffer, outBuffer;
        vImage_Error error;
        void *pixelBuffer;
        
        CGDataProviderRef inProvider = CGImageGetDataProvider(img);
        CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
        
        inBuffer.width = CGImageGetWidth(img);
        inBuffer.height = CGImageGetHeight(img);
        inBuffer.rowBytes = CGImageGetBytesPerRow(img);
        inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
        
        pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
        
        outBuffer.data = pixelBuffer;
        outBuffer.width = CGImageGetWidth(img);
        outBuffer.height = CGImageGetHeight(img);
        outBuffer.rowBytes = CGImageGetBytesPerRow(img);
        
        error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL,
                                           0, 0, boxSize, boxSize, NULL,
                                           kvImageEdgeExtend);
        
        
        if (error) {
            NSLog(@"error from convolution %ld", error);
        }
        
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef ctx = CGBitmapContextCreate(
                                                 outBuffer.data,
                                                 outBuffer.width,
                                                 outBuffer.height,
                                                 8,
                                                 outBuffer.rowBytes,
                                                 colorSpace,
                                                 CGImageGetBitmapInfo(image.CGImage));
        
        CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
        UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
        
        //clean
        CGContextRelease(ctx);
        CGColorSpaceRelease(colorSpace);
        
        free(pixelBuffer);
        CFRelease(inBitmapData);
        
        CGImageRelease(imageRef);
        
        CFAbsoluteTime t1 = CFAbsoluteTimeGetCurrent();
        
        NSLog(@"boxBlurTime=%f", t1-t0);
        
        return returnImage;
    }
    
    UIImage分类地址

    UIImage的分类还有很多,这里只是列举了一部分,具体可到我的github上面查看

    https://github.com/QinminiOS/GPUImage/tree/master/UIImage%2B

    相关文章

      网友评论

        本文标题:UIImage分类大全

        本文链接:https://www.haomeiwen.com/subject/ruxbyxtx.html