UIGraphicsBeginImageContext系列知识

UIGraphicsBeginImageContext

创建一个基于位图的上下文(context),并将其设置为当前上下文(context)。方法声明如下:

void UIGraphicsBeginImageContext(CGSize size);

参数size为新创建的位图上下文的大小。它同时是由UIGraphicsGetImageFromCurrentImageContext函数返回的图形大小。
该函数的功能同UIGraphicsBeginImageCont
extWithOptions的功能相同,相当与UIGraphicsBeginImageContextWithOptions的opaque参数为NO,scale因子为1.0。UIGraphicsBeginImageContextWithOptions
函数原型为:

void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);

size——同UIGraphicsBeginImageContext
opaque—透明开关,如果图形完全不用透明,设置为YES以优化位图的存储。
scale—–缩放因子


UIImage处理

1、等比绽放

- (UIImage *) scaleImage:(UIImage *)image toScale:(float)scaleSize {
    UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scaleSize, image.size.height * scaleSize);
    [image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height * scaleSize)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

2、自定义大小
- (UIImage *) reSizeImage:(UIImage *)image toSize:(CGSize)reSize {
    UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
    [image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
    UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return reSizeImage;
}

3、处理某个特定的view
-(UIImage*) captureView:(UIView *)theView {
    CGRect rect = theView.frame;
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [theView.layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

4、存储图片

    4.1、存储到app的文件里

    把要处理的图片以image.png的名字存储到app home地下的Document目录中

        NSString *path = [[NSHomeDirectory()stringByAppendingPathComponent:@"Documents"]stringByAppendingPathComponent:@"image.png"];
        [UIImagePNGRepresentation(image) writeToFile:pathatomically:YES];</span>

4.2、存储到手机的图片库中
        CGImageRef screen = UIGetScreenImage();
        UIImage* image = [UIImage imageWithCGImage:screen];
        CGImageRelease(screen);
        UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);</span>

一些有关图像处理的代码片断

- (UIImage *)rescaleImage:(UIImage *)img  ToSize:(CGSize)size;   //图片缩放裁剪
- (UIImage*)transformWidth:(CGFloat)width   height:(CGFloat)height; //改变大小
+ (UIImage *)addImage:(UIImage *)image1 toImage:(UIImage *)image2; //合并图片
+ (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect; //裁剪部分图片
+ (void)imageSavedToPhotosAlbum:(UIImage *)image
didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;  //保存图片到媒体库

零)重新设置图片的尺寸

- (UIImage *)rescaleImage:(UIImage *)img  ToSize:(CGSize)size {

    CGRect rect = CGRectMake(0.0, 0.0, size.width, size.height);

    UIGraphicsBeginImageContext(rect.size);
    [img drawInRect:rect];  // scales image to rect
    UIImage *resImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return resImage;

}

-)根据给定得图片,从其指定区域截取一张新得图片
-(UIImage *)getImageFromImage{

    //定义myImageRect,截图的区域
    CGRect myImageRect = CGRectMake(10.0, 10.0, 57.0, 57.0);

    //大图bigImage
    UIImage* bigImage= [UIImage imageNamed:@"k00030.jpg"];

    CGImageRef imageRef = bigImage.CGImage;
    CGImageRef subImageRef = CGImageCreateWithImageInRect(imageRef, myImageRect);
    CGSize size;
    size.width = 57.0;
    size.height = 57.0;

    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, myImageRect, subImageRef);
    UIImage* smallImage = [UIImage imageWithCGImage:subImageRef];
    UIGraphicsEndImageContext();

    return smallImage;
}

二) 合并两张图片

- (UIImage *)addImage:(UIImage *)image1 toImage:(UIImage *)image2 {   

    UIGraphicsBeginImageContext(image1.size);   

    // Draw image1    
    [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];   

    // Draw image2    
    [image2 drawInRect:CGRectMake(0, 0, image2.size.width, image2.size.height)];   

    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();   

    return  resultingImage;   

}

三) 捕捉屏幕截图

CALayer实例使用Core Graphics的renderInContext方法可以将视图绘制到图像上下文中以便转化为其他UIImage实例。前提先#import <QuartzCore/QuartzCore.h>

 

+ (UIImage *) imageFromView: (UIView *)theView {
    // draw a view's contents into an image context
    UIGraphicsBeginImageContext(theView.frame.size);
    CGContextRef  context = UIGraphicsGetCurrentContext();

    [theView.layer  renderInContext:context];
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext(); 
    return theImage;
}
注:UIGraphicsBeginImageContext(CGSize size)创建一个基于位图的上下文(context),并将其设置为当前上下文。函数功能与UIGraphicsBeginImageContextWithOptions相同,相当于该方法的opaque参数为NO,scale因子为1.0。而UIGraphicsEndImageContext()方法是移除栈顶的基于当前位图的图形上下文。

 
 
 
 
 

五) 视图添加倒影效果

<pre name="code" class="objc">const CGFloat kReflectPercent = -0.25f;
const CGFloat kReflectOpacity = 0.3f;
const CGFloat kReflectDistance = 10.0f;

+ (void)addSimpleReflectionToView:(UIView *)theView
{
    CALayer *reflectionLayer = [CALayer layer];
    reflectionLayer.contents = [theView layer].contents;
    reflectionLayer.opacity = kReflectOpacity;
    reflectionLayer.frame = CGRectMake(0.0f,0.0f,theView.frame.size.width,theView.frame.size.height*kReflectPercent);  //倒影层框架设置,其中高度是原视图的百分比    CATransform3D stransform = CATransform3DMakeScale(1.0f,-1.0f,1.0f);
    CATransform3D transform = CATransform3DTranslate(stransform,0.0f,-(kReflectDistance + theView.frame.size.height),0.0f);
    reflectionLayer.transform = transform;
    reflectionLayer.sublayerTransform = reflectionLayer.transform;
    [[theView layer] addSublayer:reflectionLayer];
}

另一:使用Core Graphics创建倒影
+ (CGImageRef) createGradientImage:(CGSize)size
{
    CGFloat colors[] = {0.0,1.0,1.0,1.0};
    //在灰色设备色彩上建立一渐变     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef context = CGBitmapContextCreate(nil,size.width,size.height,8,0,colorSpace,kCGImageAlphaNone);
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,colors,NULL,2);
    CGColorSpaceRelease(colorSpace);

    //绘制线性渐变     CGPoint p1 = CGPointZero;
    CGPoint p2 = CGPointMake(0,size.height);
    CGContextDrawLinearGradient(context,gradient,p1,p2,kCGGradientDrawsAfterEndLocation);

    //Return the CGImage
    CGImageRef theCGImage = CGBitmapContextCreateImage(context);
    CFRelease(gradient);
    CGContextRelease(context);
    return theCGImage;
}

 

//Create a shrunken frame for the reflection

+ (UIImage *) reflectionOfView:(UIView *)theView WithPercent:(CGFloat) percent
{
    //Retain the width but shrink the height
    CGSize size = CGSizeMake(theView.frame.size.width, theView.frame.size.height * percent);

    //Shrink the View
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [theView.layer renderInContext:context];
    UIImage *partialimg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //build the mask
    CGImageRef mask = [ImageHelper createGradientImage:size];
    CGImageRef ref = CGImageCreateWithMask(partialimg.CGImage,mask);
    UIImage *theImage = [UIImage imageWithCGImage:ref];
    CGImageRelease(ref);
    CGImageRelease(mask);
    return theImage;
}

const CGFloat kReflectDistance = 10.0f;
+ (void) addReflectionToView: (UIView *)theView
{
    theView.clipsToBounds = NO;
    UIImageView *reflection = [[UIImageView alloc] initWithImage:[ImageHelper reflectionOfView:theView withPercent:0.45f]];
    CGRect frame = reflection.frame;
    frame.origin = CGPointMake(0.0f, theView.frame.size.height + kReflectDistance);
    reflection.frame = frame;

    //add the reflection as a simple subview
    [theView addSubView:reflection];
    [reflection release];
}


关于图片缩放的线程安全和非线程安全操作.
非线程安全的操作只能在主线程中进行操作,对于大图片的处理肯定会消耗大量的时间,如下面的方法

方法 1: 使用 UIKit

+ (UIImage*)imageWithImage(UIImage*)image scaledToSize(CGSize)newSize;
{
    // Create a graphics image context
    UIGraphicsBeginImageContext(newSize);
     
    // Tell the old image to draw in this new context, with the desired
    // new size
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
     
    // Get the new image from the context
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
     
    // End the context
    UIGraphicsEndImageContext();
     
    // Return the new image.
    return newImage;
}
此方法很简单, 但是,这种方法不是线程安全的情况下.

方法 2: 使用 CoreGraphics
+ (UIImage*)imageWithImage(UIImage*)sourceImage scaledToSize(CGSize)newSize
{
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
     
    CGImageRef imageRef = [sourceImage CGImage];
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
     
    if (bitmapInfo == kCGImageAlphaNone) {
    bitmapInfo = kCGImageAlphaNoneSkipLast;
    }
 
    CGContextRef bitmap;
     
    if (sourceImage.imageOrientation == UIImageOrientationUp ||sourceImage.imageOrientation == UIImageOrientationDown) {
    bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    } else {
    bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    }
     
    if (sourceImage.imageOrientation == UIImageOrientationLeft) {
    CGContextRotateCTM (bitmap, radians(90));
    CGContextTranslateCTM (bitmap, 0, -targetHeight);
    } else if (sourceImage.imageOrientation ==UIImageOrientationRight) {
    CGContextRotateCTM (bitmap, radians(-90));
    CGContextTranslateCTM (bitmap, -targetWidth, 0);
    } else if (sourceImage.imageOrientation == UIImageOrientationUp) {
    // NOTHING
    } else if (sourceImage.imageOrientation == UIImageOrientationDown){
    CGContextTranslateCTM (bitmap, targetWidth, targetHeight);
    CGContextRotateCTM (bitmap, radians(-180.));
    }
     
    CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth,targetHeight), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];
     
    CGContextRelease(bitmap);
    CGImageRelease(ref);
     
    return newImage;
}
这种方法的好处是它是线程安全,加上它负责的 (使用正确的颜色空间和位图信息,处理图像方向) 的小东西,UIKit 版本不会。
如何调整和保持长宽比 (如 AspectFill 选项)?
它是非常类似于上述,方法,它看起来像这样:

+ (UIImage*)imageWithImage(UIImage*)sourceImage scaledToSizeWithSameAspectRatio(CGSize)targetSize;
{
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
     
    if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
    CGFloat widthFactor = targetWidth / width;
    CGFloat heightFactor = targetHeight / height;
     
    if (widthFactor > heightFactor) {
    scaleFactor = widthFactor; // scale to fit height
    } else {
    scaleFactor = heightFactor; // scale to fit width
    }
     
    scaledWidth  = width * scaleFactor;
    scaledHeight = height * scaleFactor;
     
    // center the image
    if (widthFactor > heightFactor) {
    thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
    } else if (widthFactor < heightFactor) {
    thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    }
    }
     
    CGImageRef imageRef = [sourceImage CGImage];
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
     
    if (bitmapInfo == kCGImageAlphaNone) {
    bitmapInfo = kCGImageAlphaNoneSkipLast;
    }
     
    CGContextRef bitmap;
     
    if (sourceImage.imageOrientation == UIImageOrientationUp ||sourceImage.imageOrientation == UIImageOrientationDown) {
    bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    } else {
    bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    }
     
    // In the right or left cases, we need to switch scaledWidth and scaledHeight,
    // and also the thumbnail point
    if (sourceImage.imageOrientation == UIImageOrientationLeft) {
    thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);
    CGFloat oldScaledWidth = scaledWidth;
    scaledWidth = scaledHeight;
    scaledHeight = oldScaledWidth;
     
    CGContextRotateCTM (bitmap, radians(90));
    CGContextTranslateCTM (bitmap, 0, -targetHeight);
     
    } else if (sourceImage.imageOrientation ==UIImageOrientationRight) {
    thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);
    CGFloat oldScaledWidth = scaledWidth;
    scaledWidth = scaledHeight;
    scaledHeight = oldScaledWidth;
     
    CGContextRotateCTM (bitmap, radians(-90));
    CGContextTranslateCTM (bitmap, -targetWidth, 0);
    } else if (sourceImage.imageOrientation == UIImageOrientationUp) {
    // NOTHING
    } else if (sourceImage.imageOrientation == UIImageOrientationDown){
    CGContextTranslateCTM (bitmap, targetWidth, targetHeight);
    CGContextRotateCTM (bitmap, radians(-180.));
    }
     
    CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x,thumbnailPoint.y, scaledWidth, scaledHeight), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];
     
    CGContextRelease(bitmap);
    CGImageRelease(ref);
     
    return newImage;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值