UIImage的擴充套件方法——裁剪圖片和等比列縮放圖片-翻轉-圓形等
阿新 • • 發佈:2019-02-13
@interface UIImage (extend) //按比例改變圖片大小 -(UIImage*)changeImageSizeWithOriginalImage:(UIImage*)image percent:(float)percent; //圓形 -(UIImage*)circleImage:(UIImage*)image; //擷取部分影象 -(UIImage*)getSubImage:(CGRect)rect; //等比例縮放 -(UIImage*)scaleToSize:(CGSize)size; -(UIImage *)rotateImage:(UIImage *)aImage with:(UIImageOrientation)theorient; -(UIImage *)fixOrientation:(UIImage *)aImage; @end
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM(context, ovalWidth, ovalHeight); fw = CGRectGetWidth(rect) / ovalWidth; fh = CGRectGetHeight(rect) / ovalHeight; CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right CGContextClosePath(context); CGContextRestoreGState(context); } @implementation UIImage (extend) //按比例改變圖片大小 -(UIImage*)changeImageSizeWithOriginalImage:(UIImage*)image percent:(float)percent { // change the image size UIImage *changedImage=nil; float iwidth=image.size.width*percent; float iheight=image.size.height*percent; if (image.size.width != iwidth && image.size.height != iheight) { CGSize itemSize = CGSizeMake(iwidth, iheight); UIGraphicsBeginImageContext(itemSize); CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height); [image drawInRect:imageRect]; changedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } else { changedImage = image; } return changedImage; } //圓角 -(UIImage *) createRoundedRectImage:(UIImage*)image size:(CGSize)size roundSize:(CGSize)roundSize { // the size of CGContextRef int w = size.width; int h = size.height; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); CGRect rect = CGRectMake(0, 0, w, h); CGContextBeginPath(context); addRoundedRectToPath(context, rect, roundSize.width, roundSize.height); CGContextClosePath(context); CGContextClip(context); CGContextDrawImage(context, CGRectMake(0, 0, w, h), image.CGImage); CGImageRef imageMasked = CGBitmapContextCreateImage(context); CGContextRelease(context); CGColorSpaceRelease(colorSpace); UIImage *image2 = [UIImage imageWithCGImage:imageMasked]; CGImageRelease(imageMasked); return image2; } //圓形 -(UIImage*)circleImage:(UIImage*)image { CGFloat inset = 0.1f; UIGraphicsBeginImageContext(image.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(context, 2); CGContextSetStrokeColorWithColor(context, [UIColor clearColor].CGColor); CGRect rect = CGRectMake(inset, inset, image.size.width - inset * 2.0f, image.size.height - inset * 2.0f); CGContextAddEllipseInRect(context, rect); CGContextClip(context); [image drawInRect:rect]; CGContextAddEllipseInRect(context, rect); CGContextStrokePath(context); UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newimg; } //將image按照theSize大小等比縮放並裁剪 -(UIImage*)autoImage:(UIImage*)image size:(CGSize)theSize { if (image == nil) { return nil; } CGSize imgSize = image.size; if (imgSize.height == 0 || imgSize.width == 0 || theSize.width == 0 || theSize.height == 0) { return nil; } CGFloat nx = 0.0f; CGFloat ny = 0.0f; CGFloat nw = 0.0f; CGFloat nh = 0.0f; UIImage *autoImg = image; if (imgSize.width/imgSize.height >= theSize.width/theSize.height) { autoImg = [self changeImageSizeWithOriginalImage:image percent:theSize.height/imgSize.height]; nw = theSize.width; nh = autoImg.size.height; ny = 0; nx = ABS(autoImg.size.width - theSize.width)/2; } else { autoImg = [self changeImageSizeWithOriginalImage:image percent:theSize.width/imgSize.width]; nh = theSize.height; nw = autoImg.size.width; nx = 0; ny = ABS(autoImg.size.height - theSize.height)/2; } CGRect rect = CGRectMake(nx, ny, nw, nh); CGImageRef subImageRef = CGImageCreateWithImageInRect(autoImg.CGImage, rect); CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef)); UIGraphicsBeginImageContext(smallBounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextDrawImage(context, smallBounds, subImageRef); UIImage* smallImage = [UIImage imageWithCGImage:subImageRef]; UIGraphicsEndImageContext(); CGImageRelease(subImageRef); return smallImage; } //擷取部分影象 -(UIImage*)getSubImage:(CGRect)rect { CGImageRef subImageRef = CGImageCreateWithImageInRect(self.CGImage, rect); CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef)); UIGraphicsBeginImageContext(smallBounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextDrawImage(context, smallBounds, subImageRef); UIImage* smallImage = [UIImage imageWithCGImage:subImageRef]; UIGraphicsEndImageContext(); return smallImage; } //等比例縮放 -(UIImage*)scaleToSize:(CGSize)size { CGFloat width = CGImageGetWidth(self.CGImage); CGFloat height = CGImageGetHeight(self.CGImage); float verticalRadio = size.height*1.0/height; float horizontalRadio = size.width*1.0/width; float radio = 1; if(verticalRadio>1 && horizontalRadio>1) { radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio; } else { radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio; } width = width*radio; height = height*radio; int xPos = (size.width - width)/2; int yPos = (size.height-height)/2; // 建立一個bitmap的context // 並把它設定成為當前正在使用的context UIGraphicsBeginImageContext(size); // 繪製改變大小的圖片 [self drawInRect:CGRectMake(xPos, yPos, width, height)]; // 從當前context中建立一個改變大小後的圖片 UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); // 使當前的context出堆疊 UIGraphicsEndImageContext(); // 返回新的改變大小後的圖片 return scaledImage; } //方向旋轉 水平:UIImageOrientationUpMirrored -(UIImage *)rotateImage:(UIImage *)aImage with:(UIImageOrientation)theorient { CGImageRef imgRef = aImage.CGImage; CGFloat width = CGImageGetWidth(imgRef); CGFloat height = CGImageGetHeight(imgRef); CGAffineTransform transform = CGAffineTransformIdentity; CGRect bounds = CGRectMake(0, 0, width, height); CGFloat scaleRatio = 1; CGFloat boundHeight; UIImageOrientation orient = theorient;//aImage.imageOrientation; switch(orient) { case UIImageOrientationUp: //EXIF = 1 transform = CGAffineTransformIdentity; break; case UIImageOrientationUpMirrored: //EXIF = 2 transform = CGAffineTransformMakeTranslation(width, 0.0); transform = CGAffineTransformScale(transform, -1.0, 1.0); break; case UIImageOrientationDown: //EXIF = 3 transform = CGAffineTransformMakeTranslation(width, height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationDownMirrored: //EXIF = 4 transform = CGAffineTransformMakeTranslation(0.0, height); transform = CGAffineTransformScale(transform, 1.0, -1.0); break; case UIImageOrientationLeftMirrored: //EXIF = 5 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(height, width); transform = CGAffineTransformScale(transform, -1.0, 1.0); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationLeft: //EXIF = 6 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(0.0, width); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationRightMirrored: //EXIF = 7 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeScale(-1.0, 1.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; case UIImageOrientationRight: //EXIF = 8 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(height, 0.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; default: [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; } UIGraphicsBeginImageContext(bounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { CGContextScaleCTM(context, -scaleRatio, scaleRatio); CGContextTranslateCTM(context, -height, 0); } else { CGContextScaleCTM(context, scaleRatio, -scaleRatio); CGContextTranslateCTM(context, 0, -height); } CGContextConcatCTM(context, transform); CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return imageCopy; } //方向 -(UIImage *)fixOrientation:(UIImage *)aImage { // No-op if the orientation is already correct if (aImage.imageOrientation == UIImageOrientationUp) return aImage; // We need to calculate the proper transformation to make the image upright. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. CGAffineTransform transform = CGAffineTransformIdentity; switch (aImage.imageOrientation) { case UIImageOrientationDown: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, aImage.size.width, 0); transform = CGAffineTransformRotate(transform, M_PI_2); break; case UIImageOrientationRight: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, 0, aImage.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; default: break; } switch (aImage.imageOrientation) { case UIImageOrientationUpMirrored: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, aImage.size.width, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationLeftMirrored: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, aImage.size.height, 0); transform = CGAffineTransformScale(transform, -1, 1); break; default: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height, CGImageGetBitsPerComponent(aImage.CGImage), 0, CGImageGetColorSpace(aImage.CGImage), CGImageGetBitmapInfo(aImage.CGImage)); CGContextConcatCTM(ctx, transform); switch (aImage.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage); break; } // And now we just create a new UIImage from the drawing context CGImageRef cgimg = CGBitmapContextCreateImage(ctx); UIImage *img = [UIImage imageWithCGImage:cgimg]; CGContextRelease(ctx); CGImageRelease(cgimg); return img; } @end
其他:
Combine two UIImages To add two UIImages together you need to make use of Graphics Context. view plaincopy to clipboardprint? - (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; }
Save UIImage to Photo Album
This is just a one-liner:
UIImageWriteToSavedPhotosAlbum(image, self, @selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), context);
And to know if the save was successful:
view plaincopy to clipboardprint?
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSString *message;
NSString *title;
if (!error) {
title = NSLocalizedString(@"SaveSuccessTitle", @"");
message = NSLocalizedString(@"SaveSuccessMessage", @"");
} else {
title = NSLocalizedString(@"SaveFailedTitle", @"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:NSLocalizedString(@"ButtonOK", @"")
otherButtonTitles:nil];
[alert show];
[alert release];
}
//UIImage轉為灰度圖
-(UIImage*)getGrayImage:(UIImage*)sourceImage
{
int width = sourceImage.size.width;
int height = sourceImage.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate (nil,width,height,8,0,colorSpace,kCGImageAlphaNone);
CGColorSpaceRelease(colorSpace);
if (context == NULL) {
return nil;
}
CGContextDrawImage(context,CGRectMake(0, 0, width, height), sourceImage.CGImage);
UIImage *grayImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGContextRelease(context);
return grayImage;
}
// 檢視抖動動畫
+ (void)shakeView:(UIView *)view
{
float fDuration = 1.2f;
if (view && (fDuration >= 0.1f))
{
CABasicAnimation* shake = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
//設定抖動幅度
shake.fromValue = [NSNumber numberWithFloat:-0.3];
shake.toValue = [NSNumber numberWithFloat:+0.3];
shake.duration = 0.1f;
shake.repeatCount = fDuration/4/0.1f;
shake.autoreverses = YES;
[view.layer addAnimation:shake forKey:@"shakeView"];
}else{}
}
// 對指定檢視進行截圖
+ (UIImage *)screenShotView:(UIView *)view
{
UIImage *imageRet = nil;
if (view)
{
if(UIGraphicsBeginImageContextWithOptions != NULL)
{
UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
}
else
{
UIGraphicsBeginImageContext(view.frame.size);
}
//獲取影象
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
imageRet = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(imageRet, nil, nil, nil);
}else{APP_ASSERT_STOP}
return imageRet;
}
//將gif圖片解析成image陣列
+ (NSMutableArray *)praseGIFDataToImageArray:(NSData *)data;
{
NSMutableArray *frames = [[NSMutableArray alloc] init];
CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)data, NULL);
CGFloat animationTime = 0.f;
if (src) {
size_t l = CGImageSourceGetCount(src);
frames = [NSMutableArray arrayWithCapacity:l];
for (size_t i = 0; i < l; i++) {
CGImageRef img = CGImageSourceCreateImageAtIndex(src, i, NULL);
NSDictionary *properties = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(src, i, NULL);
NSDictionary *frameProperties = [properties objectForKey:(NSString *)kCGImagePropertyGIFDictionary];
NSNumber *delayTime = [frameProperties objectForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
animationTime += [delayTime floatValue];
if (img) {
[frames addObject:[UIImage imageWithCGImage:img]];
CGImageRelease(img);
}
}
CFRelease(src);
}
return frames;
}