美文网首页图片
UIGraphicsBeginImageContext系列知识

UIGraphicsBeginImageContext系列知识

作者: 宋进锋 | 来源:发表于2017-04-05 16:14 被阅读135次

    UIGraphicsBeginImageContext

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

    voidUIGraphicsBeginImageContext(CGSize size);

    参数size为新创建的位图上下文的大小。它同时是由UIGraphicsGetImageFromCurrentImageContext函数返回的图形大小。

    该函数的功能同UIGraphicsBeginImageContextWithOptions的功能相同,相当与UIGraphicsBeginImageContextWithOptions的opaque参数为NO,scale因子为1.0。

    UIGraphicsBeginImageContextWithOptions

    函数原型为:

    voidUIGraphicsBeginImageContextWithOptions(CGSize size,BOOLopaque, CGFloat scale);

    size——同UIGraphicsBeginImageContext

    opaque—透明开关,如果图形完全不用透明,设置为YES以优化位图的存储。

    scale—–缩放因子

    默认创建一个透明的位图上下

    UIImageC处理

    1、等比缩放

    C代码

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

    returnscaledImage;

    }

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

    returnreSizeImage;

    }

    3、处理某个特定的view

    只要是继承UIView的object 都可以处理

    必须先import QuzrtzCore.framework

    代码

    -(UIImage*) captureView:(UIView *)theView

    {

    CGRect rect = theView.frame;

    UIGraphicsBeginImageContext(rect.size);

    CGContextRef context =UIGraphicsGetCurrentContext();

    [theView.layer renderInContext:context];

    UIImage *img =UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    returnimg;

    }

    4、存储图片

    4.1、存储到app的文件里

    把要处理的图片以image.png的名字存储到app

    home地下的Document目录中

    代码

    NSString *path =[[NSHomeDirectory()stringByAppendingPathComponent:@"Documents"]stringByAppendingPathComponent:@"image.png"];

    [UIImagePNGRepresentation(image)writeToFile:pathatomically:YES];

    4.2、存储到手机的图片库中

    代码

    CGImageRef screen =

    UIGetScreenImage();

    UIImage* image = [UIImage

    imageWithCGImage:screen];

    CGImageRelease(screen);

    UIImageWriteToSavedPhotosAlbum(image, self, nil,nil);

    获取当前app的名称和版本号

    代码

    NSDictionary *infoDictionary = [[NSBundle

    mainBundle] infoDictionary];

    //app名称

    NSString *name = [infoDictionaryobjectForKey:@"CFBundleDisplayName"];

    //app版本

    NSString *version = [infoDictionaryobjectForKey:@"CFBundleShortVersionString"];

    // app build版本

    NSString *build = [infoDictionaryobjectForKey:@"CFBundleVersion"];

    UILabel根据text自动调整大小

    代码

    label.text = @"**********";

    CGRect frame = label.frame;

    frame.size.height = 10000;// 设置一个很大的高度

    label.frame = frame;

    [label sizeToFit];

    frame.size.height = label.frame.size.height;

    label.frame = frame;

    直接拨打有分机号的电话

    代码

    [[UIApplication sharedApplication] openURL:[NSURL

    URLWithString:@"tel://01011112222,3333"]];

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

    - (UIImage *)rescaleImage:(UIImage *)img ToSize:(CGSize)size;//图片缩放裁剪

    - (UIImage*)transformWidth:(CGFloat)widthheight:(CGFloat)height; //改变大小

    + (UIImage *)addImage:(UIImage *)image1 toImage:(UIImage*)image2; //合并图片

    + (UIImage *)imageFromImage:(UIImage *)imageinRect:(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{

    //大图bigImage

    //定义myImageRect,截图的区域

    CGRect myImageRect = CGRectMake(10.0, 10.0, 57.0, 57.0);

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

    returnresultingImage;

    }

    三) 捕捉屏幕截图

    CALayer实例使用Core

    Graphics的renderInContext方法可以将视图绘制到图像上下文中以便转化为其他UIImage实例。前提先#import


    + (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(CGSizesize)创建一个基于位图的上下文(context),并将其设置为当前上下文。函数功能与UIGraphicsBeginImageContextWithOptions相同,相当于该方法的opaque参数为NO,scale因子为1.0。而UIGraphicsEndImageContext()方法是移除栈顶的基于当前位图的图形上下文。

    视图添加倒影效果


    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

    INCLUDEPICTURE

    "http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif"

    \* MERGEFORMATINET UIImage*)image scaledToSize INCLUDEPICTURE

    "http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif"

    \* MERGEFORMATINET 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

    INCLUDEPICTURE

    "http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif"

    \* MERGEFORMATINET UIImage*)sourceImage scaledToSize INCLUDEPICTURE

    "http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif"

    \* MERGEFORMATINET 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*)imageWithImageINCLUDEPICTURE"http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif"\* MERGEFORMATINET UIImage*)sourceImagescaledToSizeWithSameAspectRatio INCLUDEPICTURE"http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif"\* MERGEFORMATINET 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;

    }

    相关文章

      网友评论

        本文标题:UIGraphicsBeginImageContext系列知识

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