iOS 截屏以及相关扩展(UIImage的绘制和渲染)
来源:互联网 发布:天龙物流软件 编辑:程序博客网 时间:2024/06/02 05:29
1.截取当前屏幕
CGSize windowSize = behandView.bounds.size;
UIGraphicsBeginImageContextWithOptions(windowSize, YES, 2.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[behandView.window.layer renderInContext:context];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
2.截屏-scrollview
- (UIImage *)captureScrollView:(UIScrollView *)scrollView{
UIImage* image = nil;
UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, NO, 2.0f);
{
CGPoint savedContentOffset = scrollView.contentOffset;
CGRect savedFrame = scrollView.frame;
scrollView.contentOffset = CGPointZero;
scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
[scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
scrollView.contentOffset = savedContentOffset;
scrollView.frame = savedFrame;
}
UIGraphicsEndImageContext();
if (image != nil)
{
return image;
}
3.扩展知识,UIImage的绘制和渲染
UIGraphicsBeginImageContext系列知识
UIGraphicsBeginImageContext
创建一个基于位图的上下文(context),并将其设置为当前上下文(context)。方法声明如下:
void UIGraphicsBeginImageContext(CGSize size);
参数size为新创建的位图上下文的大小。它同时是由UIGraphicsGetImageFromCurrentImageContext函数返回的图形大小。
该函数的功能同UIGraphicsBeginImageContextWithOptions的功能相同,相当与UIGraphicsBeginImageContextWithOptions的opaque参数为NO,scale因子为1.0。
UIGraphicsBeginImageContextWithOptions
函数原型为:
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, 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();
- return scaledImage;
- }
2、自定义大小
C代码
- - (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
只要是继承UIView的object都可以处理
必须先import QuzrtzCore.framework
C代码
- -(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的名字存储到apphome地下的Document目录中
C代码
- 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 = [infoDictionary objectForKey:@"CFBundleDisplayName"];
- // app版本
- NSString *version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
- // app build版本
- NSString *build = [infoDictionary objectForKey:@"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 *)imgToSize:(CGSize)size; //图片缩放裁剪
- (UIImage*)transformWidth:(CGFloat)width height:(CGFloat)height;//改变大小
+ (UIImage *)addImage:(UIImage *)image1 toImage:(UIImage*)image2; //合并图片
+ (UIImage *)imageFromImage:(UIImage *)imageinRect:(CGRect)rect; //裁剪部分图片
+ (void)imageSavedToPhotosAlbum:(UIImage *)image
didFinishSavingWithError:(NSError *)errorcontextInfo:(void *)contextInfo; //保存图片到媒体库
零重新设置图片的尺寸
- (UIImage *)rescaleImage:(UIImage *)imgToSize:(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= [UIImageimageNamed:@"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();
returnresultingImage;
}
三) 捕捉屏幕截图
CALayer实例使用CoreGraphics的renderInContext方法可以将视图绘制到图像上下文中以便转化为其他UIImage实例。前提先#import
+ (UIImage *) imageFromView: (UIView *)theView{ // draw a view's contents into animage 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; constCGFloat 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; [[theViewlayer] 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 *)theViewWithPercent:(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 = [ImageHelpercreateGradientImage:size]; CGImageRef ref = CGImageCreateWithMask(partialimg.CGImage,mask); UIImage *theImage = [UIImageimageWithCGImage:ref]; CGImageRelease(ref); CGImageRelease(mask); returntheImage; } const CGFloatkReflectDistance = 10.0f; + (void) addReflectionToView: (UIView *)theView{ theView.clipsToBounds = NO; UIImageView *reflection = [[UIImageViewalloc] 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 simplesubview [theViewaddSubView:reflection]; [reflectionrelease]; }
关于图片缩放的线程安全和非线程安全操作.
非线程安全的操作只能在主线程中进行操作,对于大图片的处理肯定会消耗大量的时间,如下面的方法
方法 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, withthe desired
// new size
[imagedrawInRect: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;
}
- iOS 截屏以及相关扩展(UIImage的绘制和渲染)
- 【iOS沉思录】UIImage圆角矩形的‘离屏渲染’和‘在屏渲染’实现方法
- 【iOS沉思录】UIImage圆角矩形的‘离屏渲染’和‘当前屏幕渲染’实现方法
- iOS设置UIImage的渲染模式:UIImage.renderingMode
- iOS UIImage渲染模式 imageWithRenderingMode:
- iOS UIImage渲染模式 imageWithRenderingMode:
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- 设置UIImage的渲染模式:UIImage.renderingMode
- iOS UIImage类扩展(按照位置和大小截图图片中部分图片)
- MySQL查询今天,最近7天,最近30天,本月,上个月的数据
- css3创建一个动态的立体的导航栏
- Hibernate-hql语法总结.
- RadioButton 设置selector熟悉实现Tab功能
- Qt之实现360安全卫士主界面(四)
- iOS 截屏以及相关扩展(UIImage的绘制和渲染)
- ireport 的一些技巧
- PHP Blitz模板
- Quick-Coco2d-x开发环境搭建
- 使用MyEclipse
- uva 108 Maximum Sum
- Android 如何在sd卡下创建指定的多层文件夹
- AndroidWear官方文档总结02 - 开发环境搭建
- 关于取List中的前几条数据