美文网首页代码片段iOS俱乐部程序猿阵线联盟-汇总各类技术干货
UIImage的分类:截图功能和修改图片中的指定颜色

UIImage的分类:截图功能和修改图片中的指定颜色

作者: 李贤立 | 来源:发表于2018-01-18 10:20 被阅读92次

    一,截图一般需要用到两大功能:全屏截图和指定区域截图。
    二,拿到一些图片,需要对图片进行合成的时候,外层图片的底色会很讨厌,我们需要把那层讨厌的颜色去掉,换成透明的,或者指定的某种颜色。比如我们代码生成的二维码图片,默认出来就是白色底,但是将该二维码和展示公司形象的图片组合的时候,那张白色底在很显眼,最好是给换成透明的。

    全屏截图需要考虑的是当前界面是否有导航栏,指定区域截图需要考虑的是当前手机屏幕对图片的缩放比例。
    修改图片的颜色,其实是遍历该image的每个像素点,然后找到对应的ARGB进行值替换。

    /**
     *  将图片中的指定颜色转换为透明
     */
    - (UIImage *)imageToTransparentWithOriginalColor:(UIColor *)originalColor {
        // 分解原来的颜色
        CGFloat red = 0.0;
        CGFloat green = 0.0;
        CGFloat blue = 0.0;
        CGFloat alpha = 0.0;
        [originalColor getRed:&red green:&green blue:&blue alpha:&alpha];
        
        // 分配内存
        const int imageWidth = self.size.width;
        const int imageHeight = self.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), self.CGImage);
        
        // 遍历像素
        int pixelNum = imageWidth * imageHeight;
        uint32_t* pCurPtr = rgbImageBuf;
        for (int i = 0; i < pixelNum; i++, pCurPtr++) {
            //将像素点转成子节数组来表示---第一个表示透明度即ARGB这种表示方式。ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
            //分别取出RGB值后。进行判断需不需要设成透明。
            uint8_t* ptr = (uint8_t *)pCurPtr;
            // NSLog(@"1是%d,2是%d,3是%d",ptr[1],ptr[2],ptr[3]);
            if(ptr[1] == red * 255 || ptr[2] == green * 255 || ptr[3] == blue * 255) {
                ptr[0] = 0;
            }
        }
        
        // 将内存转成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;
    }
    /**
     *  将图片中的指定颜色转换为新的颜色
     *
     *  @pram originalColor 原来的颜色
     *  @pram newColor      新的颜色
     */
    - (UIImage *)imageOriginalColor:(UIColor *)originalColor toNewColor:(UIColor *)newColor {
        // 分解原来的颜色
        CGFloat red1 = 0.0;
        CGFloat green1 = 0.0;
        CGFloat blue1 = 0.0;
        CGFloat alpha1 = 0.0;
        CGFloat red2 = 0.0;
        CGFloat green2 = 0.0;
        CGFloat blue2 = 0.0;
        CGFloat alpha2 = 0.0;
        [originalColor getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
        [newColor getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];
        
        // 分配内存
        const int imageWidth = self.size.width;
        const int imageHeight = self.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), self.CGImage);
        
        // 遍历像素
        int pixelNum = imageWidth * imageHeight;
        uint32_t* pCurPtr = rgbImageBuf;
        for (int i = 0; i < pixelNum; i++, pCurPtr++) {
            // 将像素点转成子节数组来表示---第一个表示透明度即ARGB这种表示方式。
            // ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
            uint8_t* ptr = (uint8_t *)pCurPtr;
            if (ptr[0] == alpha1) ptr[0] = alpha2;
            if (ptr[1] == red1 * 255) ptr[1] = red2 * 255;
            if (ptr[2] == green1 * 255) ptr[2] = green2 * 255;
            if (ptr[3] == blue1 * 255) ptr[3] = blue2 * 255;
        }
        
        // 将内存转成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;
    }
    /**
     *  全屏截图
     */
    + (UIImage *)screenShot {
        return  [self screenShotWithRect:[UIApplication sharedApplication].keyWindow.bounds isNavigation:NO];
    }
    /**
     *  屏幕截图
     *
     *  @pram rect         截图的frame
     *  @pram isNavigation 导航栏是否显示
     */
    + (UIImage *)screenShotWithRect:(CGRect)rect isNavigation:(BOOL)isNavigation {
        // 获取屏幕放大比例
        CGFloat scale = [UIScreen mainScreen].scale;
        CGRect newRect = rect;
        newRect.size.width *= scale;
        newRect.size.height *= scale;
        CGFloat height = 0;
        if (isNavigation) {
            height = NavigationViewHeight;
        }
        newRect.origin.y += height;
        newRect.origin.x *= scale;
        newRect.origin.y *= scale;
        // 设置截屏大小
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(newRect.size.width, newRect.size.height), YES, 0);
        [[UIApplication sharedApplication].keyWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        CGImageRef imageRef = viewImage.CGImage;
        // 设置截图的区域
        CGImageRef imageRefRect = CGImageCreateWithImageInRect(imageRef, newRect);
        UIImage *sendImage = [[UIImage alloc] initWithCGImage:imageRefRect];
        // 保存图片到照片库
        //    UIImageWriteToSavedPhotosAlbum(sendImage, nil, nil, nil);
        return sendImage;
    }
    /**
     *  返回截取到的图片数据类型
     */
    + (NSData *)dataWithScreenshot {
        UIImage *image = [self imageWithScreenshot];
        UIGraphicsEndImageContext();
        return UIImagePNGRepresentation(image);
    }
    /**
     *  截取当前屏幕
     */
    + (UIImage *)imageWithScreenshot {
        CGSize imageSize = CGSizeZero;
        UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
        if (UIInterfaceOrientationIsPortrait(orientation))
            imageSize = [UIScreen mainScreen].bounds.size;
        else
            imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
            CGContextSaveGState(context);
            CGContextTranslateCTM(context, window.center.x, window.center.y);
            CGContextConcatCTM(context, window.transform);
            CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
            if (orientation == UIInterfaceOrientationLandscapeLeft) {
                CGContextRotateCTM(context, M_PI_2);
                CGContextTranslateCTM(context, 0, -imageSize.width);
            } else if (orientation == UIInterfaceOrientationLandscapeRight) {
                CGContextRotateCTM(context, -M_PI_2);
                CGContextTranslateCTM(context, -imageSize.height, 0);
            } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
                CGContextRotateCTM(context, M_PI);
                CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
            }
            if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
                [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
            } else {
                [window.layer renderInContext:context];
            }
            CGContextRestoreGState(context);
        }
        return UIGraphicsGetImageFromCurrentImageContext();
    }
    

    相关文章

      网友评论

        本文标题:UIImage的分类:截图功能和修改图片中的指定颜色

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