3

I want to write a function in Swift that takes an image and crops out everything except a thin horizontal like in the middle. I don't want to preserve the aspect ratio.

This is what I have so far but it doesn't work the way I want it to. I want to only preserve the pixels from y=276 to y=299.

func cropImageToBars(image: UIImage) -> UIImage {

  let rect = CGRectMake(0, 200, image.size.width, 23)

  UIGraphicsBeginImageContextWithOptions(rect.size, false, 1.0)
  image.drawInRect(rect)
  let newImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()

  return newImage

}

mawnch
  • 385
  • 2
  • 4
  • 13

2 Answers2

1

How about this

func cropImageToBars(image: UIImage) -> UIImage {

    let rect = CGRectMake(0, 200, image.size.width, 23)

    UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
    defer{
      UIGraphicsEndImageContext()
    }
   flipContextVertically(rect.size)

   let cgImage = CGImageCreateWithImageInRect(image.CGImage, rect)!
   return UIImage(CGImage: cgImage) 
}

func flipContextVertically(contentSize:CGSize){
    var transform = CGAffineTransformIdentity
    transform = CGAffineTransformScale(transform, 1, -1)
    transform = CGAffineTransformTranslate(transform, 0, -contentSize.height)

    CGContextConcatCTM(UIGraphicsGetCurrentContext(), transform)
}

EDIT Flipped the CG coordinate to match UIKit.

Jans
  • 11,064
  • 3
  • 37
  • 45
  • I tried this but it returned an image with the wrong rotation. Is there a way to rotate it to its original orientation? – mawnch Sep 02 '16 at 00:38
  • Yes, It's actually a change in context coordinate. – Jans Sep 02 '16 at 00:49
  • I tried your edited response but the image was still flipped, just flipped the other way. How do I rotate it just 90 degrees? – mawnch Sep 03 '16 at 18:11
  • The snapshot crop the image in it actual orientation, if you're still seeing it in the wrong orientation maybe it was that way before the crop. – Jans Sep 04 '16 at 16:53
1

Your code does this backwards. The UIImage drawInRect() method draws the whole image into the target rectangle. Think of it as a film enlarger or slide projector. You adjust the size and shape of the box it renders the image into. You set up an image context that's like a piece of film that captures a bit of the image.

You typically want to render the image into a rectangle that's the full size of the image, with it's origin shifted so that an image context with an origin at 0 captures the desired bit of the image.

I have a demo project called CropImg that shows how to crop portions of an image. It has a UI that lets the user select a section of the image. Your case is simpler, but it should give you the idea.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Hello do you think to make your demo project available for Swift 3, as it refers to 2 years ago :/ – Hayra Feb 20 '17 at 08:54
  • 1
    @Hayra, I just updated my project for Swift 3, and also added the code and info.plist key needed to request permission to the new PHPhotoLibrary framework. – Duncan C Feb 20 '17 at 15:25