轉自:http://blog.sina.com.cn/s/blog_5fb39f9101017n1v.html
UIGraphicsBeginImageContext
創建一個基於位圖的上下文(context),並將其設置爲當前上下文(context)。方法聲明如下:
void UIGraphicsBeginImageContext(CGSize size);
參數size爲新創建的位圖上下文的大小。它同時是由UIGraphicsGetImageFromCu
rrentImageContext函數返回的圖形大小。
該函數的功能同UIGraphicsBeginImageContextWithOptions的功能相同,相當與
UIGraphicsBeginImageContextWithOptions的opaque參數爲NO,scale因子爲1.0。
UIGraphicsBeginImageContextWithOptions
函數原型爲:
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);
size——同UIGraphicsBeginImageContext
opaque—透明開關,如果圖形完全不用透明,設置爲YES以優化位圖的存儲。
scale—–縮放因子
UIImageC處理
1、等比縮放
- - (UIImage *) scaleImage:(UIImage *)imagetoScale:(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 *)imagetoSize:(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的名字存儲到apphome地下的Document目錄中
- NSString *path =[[NSHomeDirectory()stringByAppendingPathComponent:@"Documents"]stringByAppendingPathComponent:@"image.png"];
- [UIImagePNGRepresentation(image)writeToFile:pathatomically:YES];
4.2、存儲到手機的圖片庫中
- CGImageRef screen =UIGetScreenImage();
- UIImage* image = [UIImageimageWithCGImage:screen];
- CGImageRelease(screen);
- UIImageWriteToSavedPhotosAlbum(image, self, nil,nil);
直接撥打有分機號的電話
一些有關圖像處理的代碼片段
- (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 = [UIImageimageWithCGImage: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實例使用CoreGraphics的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*)imageWithImageINCLUDEPICTURE"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 imagecontext
UIGraphicsBeginImageContext(newSize);
// Tell the old image to draw inthis new context, with the desired
// new size
[imagedrawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Get the new image from thecontext
UIImage* newImage =UIGraphicsGetImageFromCurrentImageContext();
// End the context
UIGraphicsEndImageContext();
// Return the newimage.
return newImage;
}
此方法很簡單,但是,這種方法不是線程安全的情況下.
方法2: 使用CoreGraphics
+ (UIImage*)imageWithImageINCLUDEPICTURE"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 = [sourceImageCGImage];
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 = [UIImageimageWithCGImage: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 = [sourceImageCGImage];
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, weneed to switch scaledWidth and scaledHeight,
// and also the thumbnailpoint
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 = [UIImageimageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return newImage;
}