[ios] UIImage 자르기

이미지 크기를 조정하는 코드가있어 이미지 중심의 스케일 된 덩어리를 얻을 수 있습니다.이 이미지를 사용하여 이미지 UIImage의 작은 사각형 이미지 를 가져와 사진 앱. (a를 사용 UIImageView하고 자르기 모드를 조정하여 동일한 결과를 얻을 수는 있지만 이러한 이미지는 때때로에 표시됩니다 UIWebViews).

이 코드에서 충돌이 발생하기 시작했으며 약간 혼란 스러웠습니다. 나는 두 가지 다른 이론을 가지고 있으며 어느 쪽이 기초인지 궁금합니다.

이론 1) 대상 크기의 오프 스크린 이미지 컨텍스트를 그려 자르기를 수행합니다. 이미지의 중앙 부분을 원하기 때문에 CGRect인수를 drawInRect이미지 컨텍스트의 경계보다 큰 것으로 전달했습니다 . 나는 이것이 코셔 (Kosher)라고 기대했지만 대신 만져서는 안되는 다른 메모리를 가져 오려고합니까?

이론 2) 나는이 모든 것을 백그라운드 스레드에서하고 있습니다. 기본 스레드로 제한된 UIKit 부분이 있다는 것을 알고 있습니다. 오프 스크린보기로 그리는 것이 이것들 중 하나가 아니라고 가정 / 기대하고있었습니다. 내가 잘못?

(오, 방법이 그리워요 NSImage's drawInRect:fromRect:operation:fraction:.)



답변

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];


답변

스위프트 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)
    )
}

산출:

여기에 이미지 설명을 입력하십시오


답변

다음은 imageOrientation 속성을 따르는 UIImage 자르기 구현입니다. 모든 오리엔테이션을 철저히 테스트했습니다.

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;
}


답변

헤딩 :이 모든 답변은 백업 CGImage이미지 객체를 가정 합니다.

image.CGImage이 경우, nil을 반환 할 수 있습니다 UIImagea로 백업됩니다 CIImage당신은을 사용하여 이미지를 만든 경우 경우가 것이다, CIFilter.

이 경우 새 컨텍스트에서 이미지를 그리고 해당 이미지를 반환해야합니다 ( slow ).

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;
}