博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UIGraphicsBeginImageContext
阅读量:7116 次
发布时间:2019-06-28

本文共 11646 字,大约阅读时间需要 38 分钟。

hot3.png

UIGraphicsBeginImageContext系列知识

收藏人:
2015-05-14 | 阅:  转:  

 |   

16123623_BDpo.gif

16123623_bQFH.gif

  |  分享  16123623_asob.gif

- (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{

//大图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();

return resultingImage;

}

三) 捕捉屏幕截图

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(CGSize size)创建一个基于位图的上下文(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*)imageWithImage INCLUDEPICTURE "http://www.61ic.com/Mobile/UploadFiles_9667/201103/20110309123315372.gif" \* MERGEFORMATINET UIImage*)sourceImage scaledToSizeWithSameAspectRatio 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;

}

转载于:https://my.oschina.net/HeroOneHY/blog/638433

你可能感兴趣的文章
跟随我在oracle学习php(7)
查看>>
Objective-C Runtime 运行时之一:类与对象
查看>>
RAC环境修改参数生效测试
查看>>
浏览器兼容性问题
查看>>
Mongodb学习笔记一
查看>>
urllib模块中parse函数中的urlencode和quote_plus方法
查看>>
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session
查看>>
一个优秀的.net程序员必须要学会的技能 【转】
查看>>
[Python3网络爬虫开发实战] 1.1-Python3的安装
查看>>
一般过去时
查看>>
为了python准备一些软件
查看>>
1180 中位数
查看>>
PHP 真正多线程的使用
查看>>
hibernate-release-5.2.9.Final
查看>>
在几何画板中切割三棱锥的方法
查看>>
AutoResetEvent和ManualResetEvent用法
查看>>
简单排序
查看>>
python SMTP 发送邮件
查看>>
windows 安装zookeeper
查看>>
最大流问题
查看>>