MonkeyBonkey
MonkeyBonkey

Reputation: 47871

how to crop to letterbox in iOS

In IOS How can I crop a rectangular image to square letterbox so that it maintains the original aspect ratio and the remaining spaces are filled with black. E.g. the "pad" strategy that transloadit uses to crop/resize their images.

http://transloadit.com/docs/image-resize

Upvotes: 0

Views: 1038

Answers (3)

Lyck
Lyck

Reputation: 728

Just for convenience - heres a swift rewrite of @Dima's answer:

import UIKit

extension UIImage
{
    func letterboxImage() -> UIImage
    { 
        let width = self.size.width
        let height = self.size.height

        // no letterboxing needed, already a square
        if(width == height)
        {
            return self
        }

        // find the larger side
        let squareSize = max(width, height)

        UIGraphicsBeginImageContext(CGSizeMake(squareSize, squareSize))

        // draw black background
        let context = UIGraphicsGetCurrentContext()
        CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0)
        CGContextFillRect(context, CGRectMake(0, 0, squareSize, squareSize))

        // draw image in the middle
        self.drawInRect(CGRectMake((squareSize-width) / 2, (squareSize - height) / 2, width, height))

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}

Upvotes: 1

Dima
Dima

Reputation: 23634

For anyone who stumbles onto this question and many more like it without a clear answer, I have written a neat little category that accomplishes this at the model level by modifying the UIImage directly rather than just modifying the view. Simply use this method the returned image will be letterboxed to a square shape, regardless of which side is longer.

- (UIImage *) letterboxedImageIfNecessary
{
    CGFloat width = self.size.width;
    CGFloat height = self.size.height;

    // no letterboxing needed, already a square
    if(width == height)
    {
        return self;
    }

    // find the larger side
    CGFloat squareSize = MAX(width,height);

    UIGraphicsBeginImageContext(CGSizeMake(squareSize, squareSize));

    // draw black background
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
    CGContextFillRect(context, CGRectMake(0, 0, squareSize, squareSize));

    // draw image in the middle
    [self drawInRect:CGRectMake((squareSize - width) / 2, (squareSize - height) / 2, width, height)];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

Upvotes: 2

nhahtdh
nhahtdh

Reputation: 56809

You have to set contentMode of the UIImageView with UIViewContentModeScaleAspectFit. You can also find this option for UIImageView if you use storyboard.

The set the backgroundColor of UIImageView to black (or other color of your choice).

Upvotes: 0

Related Questions