title: How to improve sharpness when resizing UIImage?
body: <p>In my app I need to upload photos on server, so before that, I want to resize and compress them to acceptable size. I tried to resize them in two ways, and the first way is:</p>
  
  <pre><code>    // image is an instance of original UIImage that I want to resize
      let width : Int = 640
      let height : Int = 640
      let bitsPerComponent = CGImageGetBitsPerComponent(image.CGImage)
      let bytesPerRow = CGImageGetBytesPerRow(image.CGImage)
      let colorSpace = CGImageGetColorSpace(image.CGImage)
      let bitmapInfo = CGImageGetBitmapInfo(image.CGImage)
  
      let context = CGBitmapContextCreate(nil, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo)
      CGContextSetInterpolationQuality(context, kCGInterpolationHigh)
      CGContextDrawImage(context, CGRect(origin: CGPointZero, size: CGSize(width: CGFloat(width), height: CGFloat(height))), image.CGImage)
  
      image = UIImage(CGImage: CGBitmapContextCreateImage(context))
  </code></pre>
  
  <p>The other way:</p>
  
  <pre><code>image = RBResizeImage(image, targetSize: CGSizeMake(640, 640))
  
  func RBResizeImage(image: UIImage?, targetSize: CGSize) -&gt; UIImage? {
          if let image = image {
              let size = image.size
  
              let widthRatio  = targetSize.width  / image.size.width
              let heightRatio = targetSize.height / image.size.height
  
              // Figure out what our orientation is, and use that to form the rectangle
              var newSize: CGSize
              if(widthRatio &gt; heightRatio) {
                  newSize = CGSizeMake(size.width  heightRatio, size.height  heightRatio)
              } else {
                  newSize = CGSizeMake(size.width  widthRatio,  size.height  widthRatio)
              }
  
              // This is the rect that we've calculated out and this is what is actually used below
              let rect = CGRectMake(0, 0, newSize.width, newSize.height)
  
              // Actually do the resizing to the rect using the ImageContext stuff
              UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
              image.drawInRect(rect)
              let newImage = UIGraphicsGetImageFromCurrentImageContext()
              UIGraphicsEndImageContext()
  
              return newImage
          } else {
              return nil
          }
      }
  </code></pre>
  
  <p>After that, I use <code>UIImageJPEGRepresentation</code> to compress UIImage, but even if <code>compressionQuality</code> is 1, photo is still blurry (that's visible on object edges mostly, maybe it's not a big deal, but photo is three to five times larger than same photo from Instagram, e.g. but doesn't have same sharpness). For 0.5 is even worse, of course, and photo is still larger (in KB) than same photo from Instagram.</p>
  
  <p><img src="https://i.stack.imgur.com/bGH8Q.jpg" alt="Photo from my app, compressionQuality is 1, edges are blurry, and size is 341 KB">
  <strong>Photo from my app, compressionQuality is 1, edges are blurry, and size is 341 KB</strong></p>
  
  <p><img src="https://i.stack.imgur.com/tyZvV.jpg" alt="Photo from Instagram, edges are sharp, and size is 136 KB">
  <strong>Photo from Instagram, edges are sharp, and size is 136 KB</strong></p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Ok, but I'm little confused right now, I'm not sure what to do, to maintain aspect ratio? This is how I crop image (scrollView has UIImageView, so I can move and zoom image, and on the end, I'm able to crop visible part of scrollView which is sqare). Anyway, image from above was originally 2048x2048, but it's still blurry.</p>
  
  <pre><code> var scale  = 1/scrollView.zoomScale
   var visibleRect : CGRect = CGRect()
  
   visibleRect.origin.x = scrollView.contentOffset.x * scale
   visibleRect.origin.y = scrollView.contentOffset.y * scale
   visibleRect.size.width = scrollView.bounds.size.width * scale
   visibleRect.size.height = scrollView.bounds.size.height * scale
   image = crop(image!, rect: visibleRect)
  
  
  func crop(srcImage : UIImage, rect : CGRect) -&gt; UIImage? {
       var imageRef = CGImageCreateWithImageInRect(srcImage.CGImage, rect)
       var cropped = UIImage(CGImage: imageRef)
  
       return cropped
  }
  </code></pre>