2010年9月25日星期六

uiimage 扩展

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;   //图片缩放裁剪


- (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;  //保存图片到媒体库


UIImageExtrasUIImageExtra




关于图片缩放的线程安全和非线程安全操作.


线程安全的操作只能在主线程中进行操作,对于大图片的处理肯定会消耗大量的时间,如下面的方法


方法 1 使用 UIKit


+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(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:(UIImage*)sourceImage scaledToSize:(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:(UIImage*)sourceImage scaledToSizeWithSameAspectRatio:(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;


}

发表评论