Обрезка UIImage

У меня есть некоторый код, который изменяет размер изображения, чтобы я мог получить масштабированный кусок центра изображения - я использую это, чтобы взять UIImage и вернуть небольшое квадратное представление изображения, похожее на то, что видно в виде альбома приложения "Фотографии". (Я знаю, что мог бы использовать UIImageView и отрегулируйте режим кадрирования для достижения тех же результатов, но эти изображения иногда отображаются в UIWebViews).

Я начал замечать некоторые сбои в этом коде, и я немного озадачен. У меня есть две разные теории, и мне интересно, есть ли одна из них на основе.

Теория 1) Я достигаю обрезки, рисуя в контексте закадрового изображения моего целевого размера. Так как я хочу центральную часть изображения, я установил CGRect аргумент передан drawInRect к чему-то, что больше, чем границы моего контекста изображения. Я надеялся, что это было кошерно, но вместо этого я пытаюсь привлечь другое воспоминание, которого я не должен касаться?

Теория 2) Я делаю все это в фоновом потоке. Я знаю, что есть части UIKit, которые ограничены основным потоком. Я предполагал / надеялся, что рисование за пределами экрана не было одним из них. Я ошибся?

(О, как я скучаю NSImage's drawInRect:fromRect:operation:fraction: Метод.)

26 ответов

Обновление 2014-05-28: я написал это, когда iOS 3 или около того была новинкой, я уверен, что к настоящему времени есть лучшие способы сделать это, возможно, встроенные. Как уже упоминали многие люди, этот метод не учитывает ротацию; Прочитайте некоторые дополнительные ответы и распространите любовь, чтобы ответы на этот вопрос были полезны для всех.

Оригинальный ответ:

Я собираюсь скопировать / вставить свой ответ на тот же вопрос в другом месте:

Для этого нет простого метода класса, но есть функция, которую вы можете использовать для получения желаемых результатов: CGImageCreateWithImageInRect(CGImageRef, CGRect) поможет вам.

Вот краткий пример его использования:

CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
// or use the UIImage wherever you like
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]]; 
CGImageRelease(imageRef);

Чтобы обрезать изображения сетчатки, сохраняя тот же масштаб и ориентацию, используйте следующий метод в категории UIImage (iOS 4.0 и выше):

- (UIImage *)crop:(CGRect)rect {
    if (self.scale > 1.0f) {
        rect = CGRectMake(rect.origin.x * self.scale,
                          rect.origin.y * self.scale,
                          rect.size.width * self.scale,
                          rect.size.height * self.scale);
    }

    CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
    CGImageRelease(imageRef);
    return result;
}

Вы можете создать категорию UIImage и использовать ее там, где вам нужно. Основано на ответах HitScans и комментариях ниже.

@implementation UIImage (Crop)

- (UIImage *)crop:(CGRect)rect {

    rect = CGRectMake(rect.origin.x*self.scale, 
                      rect.origin.y*self.scale, 
                      rect.size.width*self.scale, 
                      rect.size.height*self.scale);       

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
    UIImage *result = [UIImage imageWithCGImage:imageRef 
                                          scale:self.scale 
                                    orientation:self.imageOrientation]; 
    CGImageRelease(imageRef);
    return result;
}

@end

Вы можете использовать это так:

UIImage *imageToCrop = <yourImageToCrop>;
CGRect cropRect = <areaYouWantToCrop>;   

//for example
//CGRectMake(0, 40, 320, 100);

UIImage *croppedImage = [imageToCrop crop:cropRect];

Версия Swift 3

func cropImage(imageToCrop:UIImage, toRect rect:CGRect) -> UIImage{

    let imageRef:CGImage = imageToCrop.cgImage!.cropping(to: rect)!
    let cropped:UIImage = UIImage(cgImage:imageRef)
    return cropped
}


let imageTop:UIImage  = UIImage(named:"one.jpg")! // add validation

с помощью этой функции моста CGRectMake -> CGRect (кредиты на этот ответ ответил @rob mayoff):

 func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
    return CGRect(x: x, y: y, width: width, height: height)
}

Использование:

if var image:UIImage  = UIImage(named:"one.jpg"){
   let  croppedImage = cropImage(imageToCrop: image, toRect: CGRectMake(
        image.size.width/4,
        0,
        image.size.width/2,
        image.size.height)
    )
}

Выход:

Вот моя реализация обрезки UIImage, которая подчиняется свойству imageOrientation. Все ориентации были тщательно проверены.

inline double rad(double deg)
{
    return deg / 180.0 * M_PI;
}

UIImage* UIImageCrop(UIImage* img, CGRect rect)
{
    CGAffineTransform rectTransform;
    switch (img.imageOrientation)
    {
        case UIImageOrientationLeft:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -img.size.height);
            break;
        case UIImageOrientationRight:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -img.size.width, 0);
            break;
        case UIImageOrientationDown:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -img.size.width, -img.size.height);
            break;
        default:
            rectTransform = CGAffineTransformIdentity;
    };
    rectTransform = CGAffineTransformScale(rectTransform, img.scale, img.scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([img CGImage], CGRectApplyAffineTransform(rect, rectTransform));
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:img.scale orientation:img.imageOrientation];
    CGImageRelease(imageRef);
    return result;
}

Heads up: все эти ответы предполагают CGImageобъект изображения.

image.CGImage может вернуть ноль, если UIImage поддерживается CIImage, что было бы в случае, если вы создали это изображение с помощью CIFilter,

В этом случае вам, возможно, придется нарисовать изображение в новом контексте и вернуть это изображение (медленно).

UIImage* crop(UIImage *image, rect) {
    UIGraphicsBeginImageContextWithOptions(rect.size, false, [image scale]);
    [image drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)];
    cropped_image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return cropped_image;
}

Ни один из ответов здесь не обрабатывает все проблемы масштаба и вращения на 100% правильно. Вот обобщение всего, что было сказано до сих пор, начиная с iOS7/8. Он предназначен для включения в качестве метода в категорию на UIImage.

- (UIImage *)croppedImageInRect:(CGRect)rect
{
    double (^rad)(double) = ^(double deg) {
        return deg / 180.0 * M_PI;
    };

    CGAffineTransform rectTransform;
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -self.size.height);
            break;
        case UIImageOrientationRight:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -self.size.width, 0);
            break;
        case UIImageOrientationDown:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -self.size.width, -self.size.height);
            break;
        default:
            rectTransform = CGAffineTransformIdentity;
    };
    rectTransform = CGAffineTransformScale(rectTransform, self.scale, self.scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], CGRectApplyAffineTransform(rect, rectTransform));
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
    CGImageRelease(imageRef);

    return result;
}

Свифт версия awolfответ, который работал для меня:

public extension UIImage {
    func croppedImage(inRect rect: CGRect) -> UIImage {
        let rad: (Double) -> CGFloat = { deg in
            return CGFloat(deg / 180.0 * .pi)
        }
        var rectTransform: CGAffineTransform
        switch imageOrientation {
        case .left:
            let rotation = CGAffineTransform(rotationAngle: rad(90))
            rectTransform = rotation.translatedBy(x: 0, y: -size.height)
        case .right:
            let rotation = CGAffineTransform(rotationAngle: rad(-90))
            rectTransform = rotation.translatedBy(x: -size.width, y: 0)
        case .down:
            let rotation = CGAffineTransform(rotationAngle: rad(-180))
            rectTransform = rotation.translatedBy(x: -size.width, y: -size.height)
        default:
            rectTransform = .identity
        }
        rectTransform = rectTransform.scaledBy(x: scale, y: scale)
        let transformedRect = rect.applying(rectTransform)
        let imageRef = cgImage!.cropping(to: transformedRect)!
        let result = UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
        return result
    }
}

swift3

extension UIImage {
    func crop(rect: CGRect) -> UIImage? {
        var scaledRect = rect
        scaledRect.origin.x *= scale
        scaledRect.origin.y *= scale
        scaledRect.size.width *= scale
        scaledRect.size.height *= scale
        guard let imageRef: CGImage = cgImage?.cropping(to: scaledRect) else {
            return nil
        }
        return UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
    }
}
CGSize size = [originalImage size];
int padding = 20;
int pictureSize = 300;
int startCroppingPosition = 100;
if (size.height > size.width) {
    pictureSize = size.width - (2.0 * padding);
    startCroppingPosition = (size.height - pictureSize) / 2.0; 
} else {
    pictureSize = size.height - (2.0 * padding);
    startCroppingPosition = (size.width - pictureSize) / 2.0;
}
// WTF: Don't forget that the CGImageCreateWithImageInRect believes that 
// the image is 180 rotated, so x and y are inverted, same for height and width.
CGRect cropRect = CGRectMake(startCroppingPosition, padding, pictureSize, pictureSize);
CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], cropRect);
UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:originalImage.imageOrientation];
[m_photoView setImage:newImage];
CGImageRelease(imageRef);

Большинство ответов, которые я видел, касается только позиции (0, 0) для (x, y). Хорошо, это один случай, но я бы хотел, чтобы моя операция кадрирования была сосредоточена. Мне потребовалось некоторое время, чтобы понять, какая строка стоит после комментария WTF.

Давайте возьмем случай изображения, захваченного с портретной ориентацией:

  1. Высота исходного изображения превышает ширину (пока ничего удивительного!)
  2. Изображение, которое метод CGImageCreateWithImageInRect представляет в своем собственном мире, на самом деле не портрет, а пейзаж (поэтому также, если вы не используете аргумент ориентации в конструкторе imageWithCGImage, он будет отображаться как повернутый на 180).
  3. Итак, вы должны представить, что это пейзаж, позиция (0, 0) - верхний правый угол изображения.

Надеюсь, это имеет смысл! Если этого не произойдет, попробуйте другие значения, и вы увидите, что логика инвертируется, когда дело доходит до выбора правильных значений x, y, width и height для вашего cropRect.

Быстрое расширение

extension UIImage {
    func crop(var rect: CGRect) -> UIImage {
        rect.origin.x*=self.scale
        rect.origin.y*=self.scale
        rect.size.width*=self.scale
        rect.size.height*=self.scale

        let imageRef = CGImageCreateWithImageInRect(self.CGImage, rect)
        let image = UIImage(CGImage: imageRef, scale: self.scale, orientation: self.imageOrientation)!
        return image
    }
}

Ниже может помочь фрагмент кода.

import UIKit

extension UIImage {
    func cropImage(toRect rect: CGRect) -> UIImage? {
        if let imageRef = self.cgImage?.cropping(to: rect) {
            return UIImage(cgImage: imageRef)
        }
        return nil
    }
}

Лучшее решение для обрезки UIImage в Swift, с точки зрения точности, масштабирования пикселей...:

private func squareCropImageToSideLength(let sourceImage: UIImage,
    let sideLength: CGFloat) -> UIImage {
        // input size comes from image
        let inputSize: CGSize = sourceImage.size

        // round up side length to avoid fractional output size
        let sideLength: CGFloat = ceil(sideLength)

        // output size has sideLength for both dimensions
        let outputSize: CGSize = CGSizeMake(sideLength, sideLength)

        // calculate scale so that smaller dimension fits sideLength
        let scale: CGFloat = max(sideLength / inputSize.width,
            sideLength / inputSize.height)

        // scaling the image with this scale results in this output size
        let scaledInputSize: CGSize = CGSizeMake(inputSize.width * scale,
            inputSize.height * scale)

        // determine point in center of "canvas"
        let center: CGPoint = CGPointMake(outputSize.width/2.0,
            outputSize.height/2.0)

        // calculate drawing rect relative to output Size
        let outputRect: CGRect = CGRectMake(center.x - scaledInputSize.width/2.0,
            center.y - scaledInputSize.height/2.0,
            scaledInputSize.width,
            scaledInputSize.height)

        // begin a new bitmap context, scale 0 takes display scale
        UIGraphicsBeginImageContextWithOptions(outputSize, true, 0)

        // optional: set the interpolation quality.
        // For this you need to grab the underlying CGContext
        let ctx: CGContextRef = UIGraphicsGetCurrentContext()
        CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh)

        // draw the source image into the calculated rect
        sourceImage.drawInRect(outputRect)

        // create new image from bitmap context
        let outImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()

        // clean up
        UIGraphicsEndImageContext()

        // pass back new image
        return outImage
}

Инструкции, используемые для вызова этой функции:

let image: UIImage = UIImage(named: "Image.jpg")!
let squareImage: UIImage = self.squareCropImageToSideLength(image, sideLength: 320)
self.myUIImageView.image = squareImage

Примечание: исходное вдохновение исходного кода, написанное в Objective-C, было найдено в блоге "Cocoanetics".

Выглядит немного странно, но прекрасно работает и учитывает ориентацию изображения:

var image:UIImage = ...

let img = CIImage(image: image)!.imageByCroppingToRect(rect)
image = UIImage(CIImage: img, scale: 1, orientation: image.imageOrientation)

Swift 5:

extension UIImage {
    func cropped(rect: CGRect) -> UIImage? {
        guard let cgImage = cgImage else { return nil }

        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        let context = UIGraphicsGetCurrentContext()

        context?.translateBy(x: 0.0, y: self.size.height)
        context?.scaleBy(x: 1.0, y: -1.0)
        context?.draw(cgImage, in: CGRect(x: rect.minX, y: rect.minY, width: self.size.width, height: self.size.height), byTiling: false)


        let croppedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return croppedImage
    }
}

На iOS9.2SDK я использую метод ниже, чтобы преобразовать кадр из UIView в UIImage

-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
  CGSize cropSize = rect.size;
  CGFloat widthScale = image.size.width/self.imageViewOriginal.bounds.size.width;
  CGFloat heightScale = image.size.height/self.imageViewOriginal.bounds.size.height;
  cropSize = CGSizeMake(rect.size.width*widthScale, 
              rect.size.height*heightScale);
  CGPoint pointCrop = CGPointMake(rect.origin.x*widthScale,
             rect.origin.y*heightScale);
  rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, cropSize.height);
  CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
  UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
  CGImageRelease(subImage);

  return croppedImage;
}

Следуй за ответом @Arne. Я просто фиксирую функцию категории. положить его в категорию UIImage.

-(UIImage*)cropImage:(CGRect)rect{

    UIGraphicsBeginImageContextWithOptions(rect.size, false, [self scale]);
    [self drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)];
    UIImage* cropped_image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return cropped_image;
}

Обновление Swift 2.0 ( CIImage совместимость)

Расширение от ответа Максима, но работает, если ваше изображение CIImage на основе, а также.

public extension UIImage {
    func imageByCroppingToRect(rect: CGRect) -> UIImage? {
        if let image = CGImageCreateWithImageInRect(self.CGImage, rect) {
            return UIImage(CGImage: image)
        } else if let image = (self.CIImage)?.imageByCroppingToRect(rect) {
            return UIImage(CIImage: image)
        }
       return nil
   }
}
 (UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    double ratio;
    double delta;
    CGPoint offset;

    //make a new square size, that is the resized imaged width
    CGSize sz = CGSizeMake(newSize.width, newSize.width);

    //figure out if the picture is landscape or portrait, then
    //calculate scale factor and offset
    if (image.size.width > image.size.height) {
        ratio = newSize.width / image.size.width;
        delta = (ratio*image.size.width - ratio*image.size.height);
        offset = CGPointMake(delta/2, 0);
    } else {
        ratio = newSize.width / image.size.height;
        delta = (ratio*image.size.height - ratio*image.size.width);
        offset = CGPointMake(0, delta/2);
    }

    //make the final clipping rect based on the calculated values
    CGRect clipRect = CGRectMake(-offset.x, -offset.y,
                                 (ratio * image.size.width) + delta,
                                 (ratio * image.size.height) + delta);


    //start a new context, with scale factor 0.0 so retina displays get
    //high quality image
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
    } else {
        UIGraphicsBeginImageContext(sz);
    }
    UIRectClip(clipRect);
    [image drawInRect:clipRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Вот обновленная версия Swift 3, основанная на ответе Лапши

func cropping(to rect: CGRect) -> UIImage? {

    if let cgCrop = cgImage?.cropping(to: rect) {
        return UIImage(cgImage: cgCrop)
    }
    else if let ciCrop = ciImage?.cropping(to: rect) {
        return UIImage(ciImage: ciCrop)
    }

    return nil
}
- (UIImage *)getSubImage:(CGRect) rect{
    CGImageRef subImageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
    CGRect smallBounds = CGRectMake(rect.origin.x, rect.origin.y, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));

    UIGraphicsBeginImageContext(smallBounds.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, smallBounds, subImageRef);
    UIImage* smallImg = [UIImage imageWithCGImage:subImageRef];
    UIGraphicsEndImageContext();

    return smallImg;
}

Для Swift 5 я использовал следующее решение (мне нужно было обрезанное изображение по центру)

      public extension UIImage {
func cropped(rect: CGRect) -> UIImage? {
    if let image = self.cgImage?.cropping(to: rect) {
        return UIImage(cgImage: image, scale:self.scale, orientation:self.imageOrientation)
    }
    return nil
}

}

И где-то в вашем коде у вас есть «изображение» в виде UIImage:

          let baseSize = image.size
    let delta = abs(baseSize.height - baseSize.width)/2.0

    let croppedFrame = baseSize.height > baseSize.width ? CGRect(x: 0, y: delta, width: baseSize.width, height: baseSize.width) :
                                                          CGRect(x: delta, y: 0, width: baseSize.height, height: baseSize.height)
    
    guard let croppedImage = image.cropped(rect: croppedFrame) else {
        return
    }

Я не был удовлетворен другими решениями, потому что они либо рисуют несколько раз (используя больше энергии, чем необходимо), либо имеют проблемы с ориентацией. Вот то, что я использовал для масштабированного квадратного обрезанного изображения из изображения UIImage *.

CGFloat minimumSide = fminf(image.size.width, image.size.height);
CGFloat finalSquareSize = 600.;

//create new drawing context for right size
CGRect rect = CGRectMake(0, 0, finalSquareSize, finalSquareSize);
CGFloat scalingRatio = 640.0/minimumSide;
UIGraphicsBeginImageContext(rect.size);

//draw
[image drawInRect:CGRectMake((minimumSide - photo.size.width)*scalingRatio/2., (minimumSide - photo.size.height)*scalingRatio/2., photo.size.width*scalingRatio, photo.size.height*scalingRatio)];

UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

Обновление Свифт 5.0

      public extension UIImage {
    func cropped(rect: CGRect) -> UIImage? {
        if let image = self.cgImage!.cropping(to: rect) {
            return UIImage(cgImage: image)
        } else if let image = (self.ciImage)?.cropped(to: rect) {
            return UIImage(ciImage: image)
        }
       return nil
   }
}

Посмотрите на https://github.com/vvbogdan/BVCropPhoto

- (UIImage *) croppedImage {CGFloat scale = self.sourceImage.size.width / self.scrollView.contentSize.width; UIImage * finalImage = nil; CGRect targetFrame = CGRectMake ((self.scrollView.contentInset.left + self.scrollView.contentOffset.x) * scale, (self.scrollView.contentInset.top + self.scrollView.contentOffset.y) * scale, self.cropSize.width * scale, self.cropSize.height * scale); CGImageRef contextImage = CGImageCreateWithImageInRect ([[self imageWithRotation: self.sourceImage] CGImage], targetFrame); if (contextImage! = NULL) {finalImage = [UIImage imageWithCGImage: contextImage scale: self.sourceImage.scale direction:UIImageOrientationUp];

        CGImageRelease(contextImage);
    }

    return finalImage;
}


- (UIImage *)imageWithRotation:(UIImage *)image {


    if (image.imageOrientation == UIImageOrientationUp) вернуть изображение;
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (image.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
            transform = CGAffineTransformRotate(transform, M_PI); перерыв;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2); перерыв;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, image.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2); перерыв;
        case UIImageOrientationUp:
        case UIImageOrientationUpMirrored:
            break;
    }

    switch (image.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1); перерыв;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1); перерыв;
        case UIImageOrientationUp:
        case UIImageOrientationDown:
        case UIImageOrientationLeft:
        case UIImageOrientationRight:
            break;
    }

    // Теперь мы рисуем базовый CGImage в новом контексте, применяя преобразование, // вычисленное выше.
    CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
            CGImageGetBitsPerComponent(image.CGImage), 0,
            CGImageGetColorSpace(image.CGImage),
            CGImageGetBitCmapInfo() CGContextConcatCTM(ctx, transform);
    switch (image.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0, 0), image.ize, image.ize. CGImage); перерыв; по умолчанию:
            CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage); перерыв; } // А теперь мы просто создаем новый UIImage из контекста рисования CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(CTX);
    CGImageRelease(cgimg); вернуть img;

}

Я использую метод ниже.

  -(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
  {
    CGSize cropSize = rect.size;
    CGFloat widthScale =  
    image.size.width/self.imageViewOriginal.bounds.size.width;
    CGFloat heightScale = 
    image.size.height/self.imageViewOriginal.bounds.size.height;
    cropSize = CGSizeMake(rect.size.width*widthScale,  
    rect.size.height*heightScale);
    CGPoint  pointCrop = CGPointMake(rect.origin.x*widthScale, 
    rect.origin.y*heightScale);
    rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, 
    cropSize.height);
    CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
    UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
    CGImageRelease(subImage);
    return croppedImage;

}

Другие вопросы по тегам