【问题标题】:Resize UIImage to 200x200pt/px将 UIImage 调整为 200x200pt/px
【发布时间】:2015-11-05 03:52:01
【问题描述】:

我一直在努力调整图像的大小。 基本上我偶然发现: How to scale down a UIImage and make it crispy / sharp at the same time instead of blurry?

这似乎是一个合法的解决方案,但不知何故它无法正常工作。

我的应用适用于相机胶卷中的照片。这张照片应该调整到大约 200x200,而宽度很重要,而不是高度。

很遗憾,我没有示例代码,因为我在对无效解决方案的愤怒中丢弃了它,抱歉。

【问题讨论】:

  • 究竟是什么不能正常工作?你期待什么结果,你得到了什么结果?
  • 我希望图像的宽度为 200,在这个比例下高度为 x。我仍然得到像 1920x 这样的原始图像....随便

标签: ios swift uiimage


【解决方案1】:

这是我的代码。图片宽度为 850 像素而不是 200 像素:

 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)

}

【讨论】:

  • 为了摆脱swift 3中的错误,stackoverflow.com/a/37948158/1404324中提供的信息可能会有所帮助
  • 在 swift 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! }
【解决方案2】:

根据 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
}

【讨论】:

  • 如果要在视网膜显示中保存质量并保存透明,请使用:UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0)
  • 这将我的图像从 18MB 减少到小于 1 MB!我在 iPad 9.7" 上使用:resizeImage(image: (info[UIImagePickerControllerOriginalImage] as?UIImage)!, newWidth: 200)。图像取自 imagePickerController。使用 swift 3.0
【解决方案3】:

如果您正在处理包含透明胶片的 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
    }
}

【讨论】:

  • 惊人.. 内存占用从 200mb 以下减少到 18 :D
  • 您还应该考虑屏幕比例,将 UIImage init 替换为:let scale = UIScreen.main.scale let newImage = UIImage(cgImage: context.makeImage()!, scale: scale, orientation: .up)
  • %30 的用户在此功能上崩溃.. 在行 context.draw(self.cgImage!, in: newRect)... 崩溃:com.apple.root.utility-qos 0x1001500a8 专用 UI​​Image .scaleImage(toSize : CGSize) -> UIImage?
  • 谢谢@CanAksoy,我删除了强制选项,这应该会有所帮助。
【解决方案4】:

对于 Swift 3.0

只需将此 sn-p 作为扩展名添加到 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!
    } }

【讨论】:

  • 试过这个代码。它确实会产生一个小的;;er 图像,但它会留下巨大的内存打印——在堆上分配了一些额外的 100-200MB ((
【解决方案5】:

斯威夫特 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
}

【讨论】:

    【解决方案6】:

    此代码使用 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 我的代码更短,通过扩展完成并且有我的性能数据。
    • 虽然我真的很喜欢这个答案(因为使用现代工具、快速简洁的编码),但我必须指出我遇到的意外行为。如果原始 UIImage 是从相机中裁剪出来的,并且有一定的尺寸(比如 1180x850)并且我要求代码将其“缩小”到 newWidth:800,它实际上是图像尺寸的三倍——因为我的设备是视网膜的 3 倍! !必须提供具有所需比例的 UIGraphicsImageRendererFormat !!!谨防。我们得到了巨大的图像而不是更小的图像。
    【解决方案7】:

    此函数将返回您指定的 width 图像:

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

    【讨论】:

      【解决方案8】:

      在 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))
              }
          }
      }
      

      【讨论】:

        【解决方案9】:

        此代码在方形图像上效果很好,不会失去质量

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

        答案来自: Resize Image without losing quality

        【讨论】:

          【解决方案10】:
          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) ")
          

          【讨论】:

            【解决方案11】:

            如果您在项目中使用 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的回答

          • 【讨论】:

              【解决方案12】:

              这是@Christoph R 为 Swift 3.0 发布的答案的延续。 此代码适用于 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))
              

              【讨论】:

                【解决方案13】:

                图片大小减少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
                        }
                
                    }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-02-06
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-01-19
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-03-17
                  相关资源
                  最近更新 更多