UIImage를 200x200pt / px로 크기 조정


82

이미지 크기를 조정하는 데 어려움을 겪고 있습니다. 기본적으로 나는 난처했다 : UIImage를 축소하고 흐리게하는 대신 동시에 파삭 파삭하고 선명하게 만드는 방법?

이것은 합법적 인 해결책으로 보이지만 어떻게 든 제대로 작동하지 않습니다.

내 앱은 카메라 롤의 사진과 함께 작동합니다. 이 사진은 높이가 아니라 너비가 중요하지만 약 200x200 크기로 조정되어야합니다.

불행히도 작동하지 않는 솔루션에 대한 분노로 폐기했기 때문에 샘플 코드가 없습니다. 죄송합니다.


정확히 제대로 작동하지 않는 것은 무엇입니까? 어떤 결과를 기대하고 어떤 결과를 얻었습니까?
ifau 2015-08-12

너비가 200 이고이 비율에서 높이가 x 인 이미지를 기대합니다. 나는 아직도 .... 1920x처럼 원본 이미지를 얻고 무엇이든지
swift_dan

답변:


149

다음은 내 코드입니다. 이미지의 너비는 200 픽셀이 아니라 850 픽셀입니다.

 func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage {

    let scale = newWidth / image.size.width
    let newHeight = image.size.height * scale
    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
    image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}


@IBAction func chooseImage(sender: AnyObject) {


    var myPickerController = UIImagePickerController()
    myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    myPickerController.delegate = self;
    self.presentViewController(myPickerController, animated: true, completion: nil)


}

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])

{
    var imagenow = info[UIImagePickerControllerOriginalImage] as? UIImage

    imageImage.image = resizeImage(imagenow!, newWidth: 200)



    pimg2 = imageImage.image!

    cidnew2 = textFieldCID!.text!
    pname2 = textFieldName!.text
    pmanu2 = textFieldMan!.text
    pnick2 = textFieldNick!.text
    podate2 = textFieldPODate!.text
    pno2 = textFieldArtNo!.text



    self.dismissViewControllerAnimated(true, completion: nil)

}

1
빠른 3 오류 오프를 제거하려면에 제공된 정보 stackoverflow.com/a/37948158/1404324은 도움이 될 수
파 루크

3
빠른 4 일 : func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage { let scale = newWidth / image.size.width let newHeight = image.size.height * scale UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight)) image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }
mikey9

65

swift_dan의 답변에 따라 Swift 3 업데이트

func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? {

    let scale = newWidth / image.size.width
    let newHeight = image.size.height * scale
    UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
    image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}

2
당신은 망막 디스플레이의 품질을 저장하고 투명한 사용 저장하려면 다음 UIGraphicsBeginImageContextWithOptions (CGSize (폭 : newWidth, 높이 : newHeight), 거짓, 0)
예프 게니 카레 프

이것은 내 이미지를 18MB에서 1MB 미만으로 줄였습니다! 나는 다음을 사용했다 : resizeImage (image : (info [UIImagePickerControllerOriginalImage] as? UIImage) !, newWidth : 200) on an iPad 9.7 ". imagePickerController에서 가져온 이미지. swift 3.0 사용
Brian

43

투명 필름이 포함 된 PNG 이미지를 다루는 경우 허용 된 답변 함수는 실제로 투명 영역을 검은 색으로 변환합니다.

투명 필름의 크기를 조정하고 제자리에 유지하려면 다음 기능을 사용해보십시오.

SWIFT 4

extension UIImage {
    func scaleImage(toSize newSize: CGSize) -> UIImage? {
        var newImage: UIImage?
        let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
        if let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage {
            context.interpolationQuality = .high
            let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height)
            context.concatenate(flipVertical)
            context.draw(cgImage, in: newRect)
            if let img = context.makeImage() {
                newImage = UIImage(cgImage: img)
            }
            UIGraphicsEndImageContext()
        }
        return newImage
    }
}

1
Amazing .. 200mb 미만에서 18 : D로 메모리 사용량 감소
Tom

3
: 당신은 또한 함께있는 UIImage 초기화를 대체하여 고려 화면 크기를해야let scale = UIScreen.main.scale let newImage = UIImage(cgImage: context.makeImage()!, scale: scale, orientation: .up)
picciano

1
% 30의 사용자가이 함수에서 충돌합니다 .. 줄 context.draw (self.cgImage !, in : newRect) ... 충돌 : com.apple.root.utility-qos 0x1001500a8 특수 UIImage.scaleImage (toSize : CGSize)- > UIImage?
캔 AKSOY

1
@CanAksoy 감사합니다. 강제 옵션을 제거했습니다. 도움이 될 것입니다.
Travis M.

21

Swift 3.0의 경우

이 스 니펫을 확장자로 UIImage. 그러나 이미지를 정사각형 형태로 만들지는 않지만 그 형태라면 결과는 정사각형이됩니다.

extension UIImage {
    func resizeImage(newWidth: CGFloat) -> UIImage {

        let scale = newWidth / self.size.width
        let newHeight = self.size.height * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        self.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    } }

이 코드를 시도했습니다. 작은 이미지를 생성하지만 큰 메모리 인쇄를 남깁니다. 힙에 100-200MB를 추가로 할당합니다 ((
rommex

10

Swift 4.0-

투명 필름이 포함 된 이미지를 다루는 경우 허용 된 답변 함수는 실제로 투명 영역을 검은 색으로 변환합니다.

투명 필름의 크기를 조정하고 제자리에 유지하려면 다음 기능을 사용해보십시오.

func resizeImageWith(image: UIImage, newSize: CGSize) -> UIImage {

    let horizontalRatio = newSize.width / image.size.width
    let verticalRatio = newSize.height / image.size.height

    let ratio = max(horizontalRatio, verticalRatio)
    let newSize = CGSize(width: image.size.width * ratio, height: image.size.height * ratio)
    var newImage: UIImage

    if #available(iOS 10.0, *) {
        let renderFormat = UIGraphicsImageRendererFormat.default()
        renderFormat.opaque = false
        let renderer = UIGraphicsImageRenderer(size: CGSize(width: newSize.width, height: newSize.height), format: renderFormat)
        newImage = renderer.image {
            (context) in
            image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        }
    } else {
        UIGraphicsBeginImageContextWithOptions(CGSize(width: newSize.width, height: newSize.height), isOpaque, 0)
        image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
    }

    return newImage
}

8

이 코드는 iOS 10에 도입 된 UIGraphicsImageRenderer를 사용합니다 . 테스트에서 UIGraphicsBeginImageContext (Swift 4 / Xcode 9)를 사용하는 이전 샘플보다 10-40 % 더 빠릅니다.

extension UIImage {
        func renderResizedImage (newWidth: CGFloat) -> UIImage {
            let scale = newWidth / self.size.width
            let newHeight = self.size.height * scale
            let newSize = CGSize(width: newWidth, height: newHeight)

            let renderer = UIGraphicsImageRenderer(size: newSize)

            let image = renderer.image { (context) in
                self.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
            }
            return image
        }
    }

이미 이에 대한 답변이 있습니다. stackoverflow.com/a/45936836/1489885
HAS

1
@HAS 내 코드가 더 짧고 확장이 완료되었으며 성능 데이터가 있습니다.
rommex

나는이 대답을 정말 좋아했지만 (최신 도구 사용, 빠르고 간결한 코딩) 내가 경험 한 예기치 않은 동작을 지적해야합니다. 원본 UIImage가 카메라에서 잘리고 크기 (예 : 1180x850)가 있고 코드에 newWidth : 800으로 "축소"하도록 요청한 경우 실제로 이미지 크기를 트리핑했습니다. 내 장치가 3x 망막 이었기 때문입니다 !! ! 원하는 크기로 UIGraphicsImageRendererFormat을 제공해야합니다 !!! 조심하세요. 우리는 작은 대신 거대한 이미지를 얻었습니다.
Motti Shneor

7

이 함수는 지정한 너비 의 이미지를 반환 합니다.

func scaleImage(image: UIImage, maximumWidth: CGFloat) -> UIImage {
    let rect: CGRect = CGRectMake(0, 0, image.size.width, image.size.height)
    let cgImage: CGImageRef = CGImageCreateWithImageInRect(image.CGImage!, rect)!
    return UIImage(CGImage: cgImage, scale: image.size.width / maximumWidth, orientation: image.imageOrientation)
}

스위프트 3.0

func scaledImage(_ image: UIImage, maximumWidth: CGFloat) -> UIImage {
    let rect: CGRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
    let cgImage: CGImage = image.cgImage!.cropping(to: rect)!
    return UIImage(cgImage: cgImage, scale: image.size.width / maximumWidth, orientation: image.imageOrientation)
}

4

Swift 4.2에서 최대 크기를 사용하여 @rommex 의 답변을 추가로 개선했습니다 .

private extension UIImage {
    func scaled(to maxSize: CGFloat) -> UIImage? {
        let aspectRatio: CGFloat = min(maxSize / size.width, maxSize / size.height)
        let newSize = CGSize(width: size.width * aspectRatio, height: size.height * aspectRatio)
        let renderer = UIGraphicsImageRenderer(size: newSize)
        return renderer.image { context in
            draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
        }
    }
}

3

이 코드는 정사각형 이미지에서 훌륭하게 작동하며 품질을 잃지 않습니다.

extension UIImage {

func resize(targetSize: CGSize) -> UIImage {
    return UIGraphicsImageRenderer(size:targetSize).image { _ in
        self.draw(in: CGRect(origin: .zero, size: targetSize))
    }
}

}

답변 : 품질 저하없이 이미지 크기 조정


2

프로젝트에서 이미지를로드하기 위해 kingfisher lib를 사용하고 크기를 조정하려는 경우 다음과 같은 방법이 있습니다.

  • Xcode 8
  • 스위프트 3x

    let imageUrl = URL(string: "your image url")
     //Size refer to the size which you want to resize your original image
     let size = CGSize(width: 60, height: 60)
     let processImage = ResizingImageProcessor(targetSize: size, contentMode: .aspectFit)
     cell.courseTitleImage.kf.setImage(with: imageUrl! , placeholder: UIImage(named: "placeholder"), options: [.transition(ImageTransition.fade(1)), .processor(processImage)], progressBlock: nil, completionHandler: nil)
    

    또는

    로컬 이미지 크기 조정 :-@Christoph R의 답변을 참조 할 수 있습니다.


  • 1
    func getScaledDimension(width: CGFloat, height: CGFloat,new_width: CGFloat, new_height: CGFloat)->CGPoint {
    
            let widthAspect =  (width / new_width)
            let heightAspect = (height / new_height)
            if widthAspect == 0 || heightAspect == 0 {
                return CGPoint(x: width, y: height)
            }
            var width1 : CGFloat = 0
            var height1 : CGFloat =  0
            if widthAspect > heightAspect {
                width1 = (width) / heightAspect
                height1 = (height) / heightAspect
            } else {
                width1 = (width) / widthAspect
                height1 = (height) / widthAspect
            }
    
            return CGPoint(x: width1, y: height1 )
        }
    
    
    
        func ResizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
    
            let rect = CGRectMake(0, 0, targetSize.width, targetSize.height)
    
            UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
            image.drawInRect(rect)
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return newImage
        }
    
    
     let imagesize =  getScaledDimension(image.size.width, height: image.size.height , new_width: Width, new_height: Hieght)
    
            print("Image Size Scaled Dimension -> H:\(imagesize.x) W:\(imagesize.y)")
    
            let newImage = ResizeImage(image, targetSize: CGSizeMake(imagesize.x,imagesize.y))
            print("Resize Image Size -> H\(newImage.size.height) W\(newImage.size.width) ")
    

    1

    이것은 Swift 3.0에 대해 게시 된 @Christoph R의 답변에 대한 연속입니다. 이 코드는 Swift 5.0.1에서 작동합니다.

    static func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage {
    
        let scale = newWidth / image.size.width
        let newHeight = image.size.height * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    
        return newImage!
    }
    

    발신자 사이트에서

    TaskUtilties.resizeImage(image: rawImage!, newWidth: CGFloat(50))
    

    0

    이미지 크기를 1024로 줄이면 항상 서버 용량에 따라 변환 할 수 있습니다.

    func resizeImage(image: UIImage) -> UIImage {
    
            if image.size.height >= 1024 && image.size.width >= 1024 {
    
                UIGraphicsBeginImageContext(CGSize(width:1024, height:1024))
                image.draw(in: CGRect(x:0, y:0, width:1024, height:1024))
    
                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
    
                return newImage!
    
            }
            else if image.size.height >= 1024 && image.size.width < 1024
            {
    
                UIGraphicsBeginImageContext(CGSize(width:image.size.width, height:1024))
                image.draw(in: CGRect(x:0, y:0, width:image.size.width, height:1024))
    
                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
    
                return newImage!
    
            }
            else if image.size.width >= 1024 && image.size.height < 1024
            {
    
                UIGraphicsBeginImageContext(CGSize(width:1024, height:image.size.height))
                image.draw(in: CGRect(x:0, y:0, width:1024, height:image.size.height))
    
                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
    
                return newImage!
    
            }
            else
            {
                return image
            }
    
        }
    
    당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
    Licensed under cc by-sa 3.0 with attribution required.