如何裁剪UIImage?
我开发了一个应用程序,使用它的像素处理图像,但是在image processing中花费了很多时间。 所以我想裁剪UIImage(只有图像的中间部分,即去除/裁剪图像的边缘部分)。我有开发代码是,
- (NSInteger) processImage1: (UIImage*) image { CGFloat width = image.size.width; CGFloat height = image.size.height; struct pixel* pixels = (struct pixel*) calloc(1, image.size.width * image.size.height * sizeof(struct pixel)); if (pixels != nil) { // Create a new bitmap CGContextRef context = CGBitmapContextCreate( (void*) pixels, image.size.width, image.size.height, 8, image.size.width * 4, CGImageGetColorSpace(image.CGImage), kCGImageAlphaPremultipliedLast ); if (context != NULL) { // Draw the image in the bitmap CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, image.size.width, image.size.height), image.CGImage); NSUInteger numberOfPixels = image.size.width * image.size.height; NSMutableArray *numberOfPixelsArray = [[[NSMutableArray alloc] initWithCapacity:numberOfPixelsArray] autorelease]; }
我如何采取(裁剪外边)UIImage的中间部分?????????
尝试这样的事情:
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect); image = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef);
注意:cropRect是较小的矩形,图像的中间部分…
我正在寻找一种方法来获取UIImage的任意矩形裁剪(即,子图像)。
如果图像的方向不是UIImageOrientationUp,我尝试的大多数解决scheme都不起作用。
例如:
http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/
通常情况下,如果你使用iPhone摄像头,你将有其他的方向像UIImageOrientationLeft,你不会得到正确的作物与上述。 这是因为使用了CGImageRef / CGContextDrawImage,它们在坐标系统上与UIImage不同。
下面的代码使用UI *方法(没有CGImageRef),我已经testing了上/下/左/右导向的图像,它似乎很好。
// get sub image - (UIImage*) getSubImageFrom: (UIImage*) img WithRect: (CGRect) rect { UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); // translated rectangle for drawing sub image CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height); // clip to the bounds of the image context // not strictly necessary as it will get clipped anyway? CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height)); // draw image [img drawInRect:drawRect]; // grab image UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return subImage; }
// get sub image - (UIImage*) getSubImageFrom: (UIImage*) img WithRect: (CGRect) rect { UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); // translated rectangle for drawing sub image CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height); // clip to the bounds of the image context // not strictly necessary as it will get clipped anyway? CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height)); // draw image [img drawInRect:drawRect]; // grab image UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return subImage; }
如果不仅可以设置UIImageView的图像,而且可以设置在该UIImage中显示的左上angular的偏移量,它最终会更快,从精灵地图集创build的图像要less得多。 也许这是可能的。 这肯定会消除很多努力!
同时,我在我的应用程序中使用的实用程序类中创build了这些有用的function。 它从另一个UIImage的一部分创buildUIImage,并使用标准的UIImageOrientation值来指定旋转,缩放和翻转选项。 像素缩放从原始图像保留。
我的应用程序在初始化过程中创build了很多UIImage,这一定需要时间。 但是select某个标签之前,一些图像是不需要的。 为了给出更快的加载外观,我可以在启动时产生的一个单独的线程中创build它们,然后等待该选项卡被选中时完成。
此代码也以最高效的方式发布在iOS中绘制图像的一部分
+ (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)aperture { return [ChordCalcController imageByCropping:imageToCrop toRect:aperture withOrientation:UIImageOrientationUp]; } // Draw a full image into a crop-sized area and offset to produce a cropped, rotated image + (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)aperture withOrientation:(UIImageOrientation)orientation { // convert y coordinate to origin bottom-left CGFloat orgY = aperture.origin.y + aperture.size.height - imageToCrop.size.height, orgX = -aperture.origin.x, scaleX = 1.0, scaleY = 1.0, rot = 0.0; CGSize size; switch (orientation) { case UIImageOrientationRight: case UIImageOrientationRightMirrored: case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: size = CGSizeMake(aperture.size.height, aperture.size.width); break; case UIImageOrientationDown: case UIImageOrientationDownMirrored: case UIImageOrientationUp: case UIImageOrientationUpMirrored: size = aperture.size; break; default: assert(NO); return nil; } switch (orientation) { case UIImageOrientationRight: rot = 1.0 * M_PI / 2.0; orgY -= aperture.size.height; break; case UIImageOrientationRightMirrored: rot = 1.0 * M_PI / 2.0; scaleY = -1.0; break; case UIImageOrientationDown: scaleX = scaleY = -1.0; orgX -= aperture.size.width; orgY -= aperture.size.height; break; case UIImageOrientationDownMirrored: orgY -= aperture.size.height; scaleY = -1.0; break; case UIImageOrientationLeft: rot = 3.0 * M_PI / 2.0; orgX -= aperture.size.height; break; case UIImageOrientationLeftMirrored: rot = 3.0 * M_PI / 2.0; orgY -= aperture.size.height; orgX -= aperture.size.width; scaleY = -1.0; break; case UIImageOrientationUp: break; case UIImageOrientationUpMirrored: orgX -= aperture.size.width; scaleX = -1.0; break; } // set the draw rect to pan the image to the right spot CGRect drawRect = CGRectMake(orgX, orgY, imageToCrop.size.width, imageToCrop.size.height); // create a context for the new image UIGraphicsBeginImageContextWithOptions(size, NO, imageToCrop.scale); CGContextRef gc = UIGraphicsGetCurrentContext(); // apply rotation and scaling CGContextRotateCTM(gc, rot); CGContextScaleCTM(gc, scaleX, scaleY); // draw the image to our clipped context using the offset rect CGContextDrawImage(gc, drawRect, imageToCrop.CGImage); // pull the image from our cropped context UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext(); // pop the context to get back to the default UIGraphicsEndImageContext(); // Note: this is autoreleased return cropped; }
如果你想让一张肖像在每张照片的中心都下来。
使用@MV解决scheme,并replacecropRect。
CGFloat height = imageTaken.size.height; CGFloat width = imageTaken.size.width; CGFloat newWidth = height * 9 / 16; CGFloat newX = abs((width - newWidth)) / 2; CGRect cropRect = CGRectMake(newX,0, newWidth ,height);
我希望能够根据纵横比从一个区域裁剪,并根据外边界范围缩放到一个尺寸。 这是我的变化:
import AVFoundation import ImageIO class Image { class func crop(image:UIImage, source:CGRect, aspect:CGSize, outputExtent:CGSize) -> UIImage { let sourceRect = AVMakeRectWithAspectRatioInsideRect(aspect, source) let targetRect = AVMakeRectWithAspectRatioInsideRect(aspect, CGRect(origin: CGPointZero, size: outputExtent)) let opaque = true, deviceScale:CGFloat = 0.0 // use scale of device's main screen UIGraphicsBeginImageContextWithOptions(targetRect.size, opaque, deviceScale) let scale = max( targetRect.size.width / sourceRect.size.width, targetRect.size.height / sourceRect.size.height) let drawRect = CGRect(origin: -sourceRect.origin * scale, size: image.size * scale) image.drawInRect(drawRect) let scaledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return scaledImage } }
我发现有些东西让我感到困惑,即种植和resize的各种担忧。 裁剪与您传递给drawInRect的矩形的原点一起处理,缩放由大小部分处理。 在我的情况下,我需要将源代码中裁剪矩的大小与相同纵横比的输出矩形相关联。 比例因子是输出/input,这需要应用到drawRect(传递给drawInRect)。
一个警告是,这种方法有效地假定你正在绘制的图像比图像上下文更大。 我没有testing过这个,但是我认为你可以使用这个代码来处理裁剪/缩放,但是明确地定义缩放参数是前述的缩放参数。 默认情况下,UIKit会根据屏幕分辨率应用一个乘数。
最后,应该指出的是,这个UIKit方法比CoreGraphics / Quartz和Core Image方法更高级,似乎可以处理图像方向问题。 另外值得一提的是,这是相当快的,第二ImageIO,根据这个职位在这里: http : //nshipster.com/image-resizing/