代码改变世界

iOS,图片处理

2016-09-20 17:08  帅不过三秒  阅读(791)  评论(0编辑  收藏  举报

1.旋转图片

2.缩放图片

3.截取图片指定区域

4.图片颜色变换处理

5.将UIView转化为UIImage,并转化为data和base64 

6.将视频一帧(CMSampleBufferRef)转换为UIImage

7.使用UIWebView加载gif动态图

8.实现图片(UIImage)圆角

9.图片加印章图

10.图片压缩到指定大小

11.图片黑白处理

12.保存网页长图到相册

旋转图片

//给定角度旋转图片
-(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
    long double rotate = 0.0;
    CGRect rect;
    float translateX = 0;
    float translateY = 0;
    float scaleX = 1.0;
    float scaleY = 1.0;
    
    switch (orientation) {
        case UIImageOrientationLeft:
            rotate = M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = 0;
            translateY = -rect.size.width;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationRight:
            rotate = 3 * M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = -rect.size.height;
            translateY = 0;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationDown:
            rotate = M_PI;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = -rect.size.width;
            translateY = -rect.size.height;
            break;
        default:
            rotate = 0.0;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = 0;
            translateY = 0;
            break;
    }

    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //做CTM变换
    CGContextTranslateCTM(context, 0.0, rect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextRotateCTM(context, rotate);
    CGContextTranslateCTM(context, translateX, translateY);
    CGContextScaleCTM(context, scaleX, scaleY);

    //绘制图片
    CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
    return newPic;
}

 

缩放图片

//按比例缩放,size 是你要把图显示到 多大区域 CGSizeMake(980, 560)
-(UIImage *) imageCompressForSize:(UIImage *)sourceImage targetSize:(CGSize)size{
    UIImage *newImage = nil;
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = size.width;
    CGFloat targetHeight = size.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);

    if(CGSizeEqualToSize(imageSize, size) == NO){
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;
        if(widthFactor > heightFactor){
            scaleFactor = widthFactor;
        }
        else{
            scaleFactor = heightFactor;
        }
        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        if(widthFactor > heightFactor){
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        }else if(widthFactor < heightFactor){
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }
    UIGraphicsBeginImageContext(size);
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    [sourceImage drawInRect:thumbnailRect];
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil){
        NSLog(@"scale image fail");
    }
    UIGraphicsEndImageContext();
    return newImage;
}

 

 

截取图片指定区域

CGRect rect=CGRectMake(0, 0, 100, 100);
//截取图片指定区域
img=[UIImage imageWithCGImage:CGImageCreateWithImageInRect(img.CGImage, rect)];

 

图片颜色变换处理

void ProviderReleaseData (void *info, const void *data, size_t size)
{
    free((void*)data);
}
//图片颜色变换处理
- (UIImage*) imageBlackToTransparent:(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++)
    {
                if ((*pCurPtr & 0xFFFFFF00) == 0xffffff00)    // 将白色变成透明
//        if ((*pCurPtr & 0x65815A00) == 0x65815a00)    // 将背景变成透明
        {
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[0] = 0;
        }else{//其他颜色修改
            // 改成下面RGB值的代码,会将图片转成想要的颜色
            uint8_t* ptr = (uint8_t*)pCurPtr;
            //rgb 值0~255
            ptr[3] = 226;//red
            ptr[2] = 89;//green
            ptr[1] = 72;//blue
        }
    }
    
    // 将内存转成image
    CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
    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;
}

 

 

 

 

将UIView转化为UIImage,并转化为data和base64 

//将UIView转化为UIImage
-(UIImage *)createImageFromView:(UIView *)view{
    //屏幕密度
    CGFloat scale=[UIScreen mainScreen].scale;
    //开始绘图,区域大小,半透明效果,屏幕密度
    UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, scale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    //开始生成图片
    UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return  image;
}

//确定签名事件
-(void)okAction:(UIButton *)sender{
    [self.touchView.cleanBtn removeFromSuperview];
    //将有签名的视图转化为img并获取data
    UIImage *img=[self createImageFromView:self.touchView];
    NSData *data=UIImageJPEGRepresentation(img, 80.0f);
    //将data转化为base64字符串
    NSString *base64Str=[data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    NSString *utf8Str=[NSString stringWithUTF8String:[base64Str UTF8String]];
    //base64转UIImage
    NSData *dataUtf8=[[NSData alloc] initWithBase64EncodedString:utf8Str options:NSDataBase64DecodingIgnoreUnknownCharacters];
    UIImage *base64Image=[UIImage imageWithData:dataUtf8];
}

 

 
 将视频一帧(CMSampleBufferRef)转换为UIImage

//用AVFoundation捕捉视频帧,很多时候需要把某一帧转换成UIImage,用此函数:

 - (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer {

    // 为媒体数据设置一个CMSampleBuffer的Core Video图像缓存对象

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

    // 锁定pixel buffer的基地址

    CVPixelBufferLockBaseAddress(imageBuffer, 0);

    // 得到pixel buffer的基地址

    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);

    // 得到pixel buffer的行字节数

    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

    // 得到pixel buffer的宽和高

    size_t width = CVPixelBufferGetWidth(imageBuffer);

    size_t height = CVPixelBufferGetHeight(imageBuffer);

    // 创建一个依赖于设备的RGB颜色空间

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // 用抽样缓存的数据创建一个位图格式的图形上下文(graphics context)对象

    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

    // 根据这个位图context中的像素数据创建一个Quartz image对象

    CGImageRef quartzImage = CGBitmapContextCreateImage(context);

    // 解锁pixel buffer

    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // 释放context和颜色空间

    CGContextRelease(context);

    CGColorSpaceRelease(colorSpace);

    // 用Quartz image创建一个UIImage对象image

    UIImage *image = [UIImage imageWithCGImage:quartzImage];

    // 释放Quartz image对象

    CGImageRelease(quartzImage);

    return (image);

}

当然,先不要急,因为捕捉到得帧是YUV颜色通道的,这种颜色通道无法通过以上函数转换,RGBA颜色通道才可以成功转换,所以,先需要把视频帧的输出格式设置一下:

[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];

 

使用UIWebView加载gif动态图

    //使用UIWebView加载gif动态图
    UIWebView *webView=[[UIWebView alloc] initWithFrame:self.view.frame];
    //读取图片
    NSString *retinaPath = [[NSBundle mainBundle] pathForResource:@"ker" ofType:@"gif"];
    //图片转换为data
    NSData *data = [NSData dataWithContentsOfFile:retinaPath];
    [webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
    [self.view addSubview:webView];

 

实现图片(UIImage)圆角

/**
 设置图片圆角方法
 @param image 原图片
 @param radius 圆角度数
 @param rect 新图片frame
 @return 返回圆角图片
 */
-(UIImage *)makeRoundedImage:(UIImage *) image radius: (float) radius cgRect:(CGRect)rect;
{
    CALayer *imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
    imageLayer.contents = (id) image.CGImage;
    imageLayer.masksToBounds = YES;
    imageLayer.cornerRadius = radius;
    UIGraphicsBeginImageContext(rect.size);
    [imageLayer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return roundedImage;
}

 

 

图片加印章图

#pragma mark - 加图片印章(可以用半透明图片形成水印效果)
- (UIImage *)imageWithTransImage:(UIImage *)useImage addtransparentImage:(UIImage *)transparentimg
{
    UIGraphicsBeginImageContext(useImage.size);
    [useImage drawInRect:CGRectMake(0, 0, useImage.size.width, useImage.size.height)];
    //印章图片位置大小
    [transparentimg drawInRect:CGRectMake(useImage.size.width - useImage.size.width*0.18 - 10, 10, useImage.size.width*0.18, useImage.size.height*0.26)];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;
}

 

图片压缩到指定大小

#pragma mark -压缩图片到指定大小(单位KB)
- (NSData *)compressImage:(UIImage *)image toMaxFileSize:(NSInteger)maxFileSize{
    CGFloat compression = 0.9f;
    CGFloat maxCompression = 0.1f;
    NSData *imageData = UIImageJPEGRepresentation(image, compression);
    while ([imageData length] / 1000 > maxFileSize && compression > maxCompression) {
        compression -= 0.1;
        imageData = UIImageJPEGRepresentation(image, compression);
    }
    return imageData;
}

 

图片黑白处理

/**
 @param anImage 原图
 @param type 图片处理类型(1:黑白处理,2:黄昏做旧处理,3:胶片化处理,其他直接返回原图)
 @return 处理后的图片
 */
- (UIImage*)grayscale:(UIImage*)anImage type:(int)type {
    if (anImage == nil) {
        return nil;
    }
    CGImageRef imageRef = anImage.CGImage;
    CGFloat scale = anImage.scale;
    size_t width  = CGImageGetWidth(imageRef);
    size_t height = CGImageGetHeight(imageRef);
    size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
    size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
    size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef);
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    bool shouldInterpolate = CGImageGetShouldInterpolate(imageRef);
    CGColorRenderingIntent intent = CGImageGetRenderingIntent(imageRef);
    CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef);
    CFDataRef data = CGDataProviderCopyData(dataProvider);
    UInt8 *buffer = (UInt8*)CFDataGetBytePtr(data);
    NSUInteger x, y;
    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            UInt8 *tmp;
            tmp = buffer + y * bytesPerRow + x * 4;
            UInt8 red,green,blue;
            red = *(tmp + 0);
            green = *(tmp + 1);
            blue = *(tmp + 2);
            UInt8 brightness;
            switch (type) {
                case 1:
                    brightness = (77 * red + 28 * green + 151 * blue) / 255;
                    *(tmp + 0) = brightness;
                    *(tmp + 1) = brightness;
                    *(tmp + 2) = brightness;
                    break;
                case 2:
                    *(tmp + 0) = red;
                    *(tmp + 1) = green * 0.7;
                    *(tmp + 2) = blue * 0.4;
                    break;
                case 3:
                    *(tmp + 0) = 255 - red;
                    *(tmp + 1) = 255 - green;
                    *(tmp + 2) = 255 - blue;
                    break;
                default:
//                    *(tmp + 0) = red;
//                    *(tmp + 1) = green;
//                    *(tmp + 2) = blue;
                    return anImage;
                    break;
            }
        }
    }
    CFDataRef effectedData = CFDataCreate(NULL, buffer, CFDataGetLength(data));
    CGDataProviderRef effectedDataProvider = CGDataProviderCreateWithCFData(effectedData);
    CGImageRef effectedCgImage = CGImageCreate(width,height,bitsPerComponent,bitsPerPixel,bytesPerRow,colorSpace,bitmapInfo, effectedDataProvider,NULL,shouldInterpolate,intent);
    UIImage *effectedImage = [[UIImage alloc] initWithCGImage:effectedCgImage scale:scale orientation:UIImageOrientationUp];
    CGImageRelease(effectedCgImage);
    CFRelease(effectedDataProvider);
    CFRelease(effectedData);
    CFRelease(data);
    return effectedImage;
}

 

 保存网页长图到相册

//保存网页长图到相册
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    UIScrollView *scroll = self.webView.subviews.firstObject;
    
    scroll.frame = scroll.superview.frame;
    CGRect frm = scroll.frame;
    frm.size.height = self.webView.scrollView.contentSize.height;
    scroll.frame = frm;
    [scroll.superview layoutIfNeeded];
    // 执行截图
    [self screenView:scroll];
}

/// 截图
- (void)screenView:(UIScrollView *)view
{
    // 设置截图大小
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(view.frame.size.width,view.frame.size.height), YES, 0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGImageRef imageRef = viewImage.CGImage;
    UIImage *sendImage = [[UIImage alloc] initWithCGImage:imageRef];
    NSLog(@"sendImage==%@",sendImage);
    //保存图片到照片库 (iOS10 以上记得在info.plist添加相册访问权限,否则可能崩溃)
    UIImageWriteToSavedPhotosAlbum(sendImage, nil, nil, nil);
}