Skip to content

Instantly share code, notes, and snippets.

@mxl
Last active April 3, 2018 18:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mxl/8d3018996468b8c48d57 to your computer and use it in GitHub Desktop.
Save mxl/8d3018996468b8c48d57 to your computer and use it in GitHub Desktop.
import UIKit
import XCPlayground
enum UIImageAlignment {
case Center, Left, Top, Right, Bottom, TopLeft, BottomRight, BottomLeft, TopRight
}
enum UIImageScaleMode {
case Fill,
AspectFill,
AspectFit(UIImageAlignment)
}
let trimColor = UIColor(red:1.00, green:0.79, blue:0.52, alpha:1.00)
extension UIImage {
func imageWithSize(size: CGSize, scaleMode: UIImageScaleMode = .AspectFit(.Center), trim: Bool = false) -> UIImage {
return scaleImage(width: size.width, height: size.height, scaleMode: scaleMode, trim: trim)
}
func scaleImage(width width: CGFloat? = nil, height: CGFloat? = nil, scaleMode: UIImageScaleMode = .AspectFit(.Center), trim: Bool = false) -> UIImage {
let preWidthScale = width.map { $0 / size.width }
let preHeightScale = height.map { $0 / size.height }
var widthScale = preWidthScale ?? preHeightScale ?? 1
var heightScale = preHeightScale ?? widthScale
switch scaleMode {
case .AspectFit(_):
let scale = min(widthScale, heightScale)
widthScale = scale
heightScale = scale
case .AspectFill:
let scale = max(widthScale, heightScale)
widthScale = scale
heightScale = scale
default:
break
}
let newWidth = size.width * widthScale
let newHeight = size.height * heightScale
let canvasWidth = trim ? newWidth : (width ?? newWidth)
let canvasHeight = trim ? newHeight : (height ?? newHeight)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(canvasWidth, canvasHeight), false, 0)
// Start: remove these lines
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, trimColor.CGColor)
CGContextFillRect(context, CGRectMake(0, 0, width ?? newWidth, height ?? newHeight))
// End: remove these lines
var originX: CGFloat = 0
var originY: CGFloat = 0
switch scaleMode {
case .AspectFit(let alignment):
switch alignment {
case .Center:
originX = (canvasWidth - newWidth) / 2
originY = (canvasHeight - newHeight) / 2
case .Top:
originX = (canvasWidth - newWidth) / 2
case .Left:
originY = (canvasHeight - newHeight) / 2
case .Bottom:
originX = (canvasWidth - newWidth) / 2
originY = canvasHeight - newHeight
case .Right:
originX = canvasWidth - newWidth
originY = (canvasHeight - newHeight) / 2
case .TopLeft:
break
case .TopRight:
originX = canvasWidth - newWidth
case .BottomLeft:
originY = canvasHeight - newHeight
case .BottomRight:
originX = canvasWidth - newWidth
originY = canvasHeight - newHeight
}
default:
break
}
self.drawInRect(CGRectMake(originX, originY, newWidth, newHeight))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
let foregroundColor = UIColor(red:0.13, green:0.60, blue:0.95, alpha:1.00)
let foregroundColor2 = UIColor(red:0.56, green:0.80, blue:0.97, alpha:1.00)
let backgroundColor = UIColor(red:0.88, green:0.88, blue:0.88, alpha:1.00)
func createTestImageWithSize(size: CGSize) -> UIImage {
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, foregroundColor2.CGColor)
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height))
CGContextSetFillColorWithColor(context, foregroundColor.CGColor)
let circleDiameter = min(size.width, size.height)
let horizontalCircleCount = Int(size.width/circleDiameter)
let verticalCircleCount = Int(size.height/circleDiameter)
for i in 0..<horizontalCircleCount {
for j in 0..<verticalCircleCount {
CGContextFillEllipseInRect(context, CGRectMake(
size.width/2 + (CGFloat(i) - CGFloat(horizontalCircleCount)/2) * circleDiameter,
size.height/2 + (CGFloat(j) - CGFloat(verticalCircleCount)/2) * circleDiameter,
circleDiameter, circleDiameter))
}
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
func aspectFit1() {
let view = UIImageView(frame: CGRectMake(0, 0, 128, 64))
view.contentMode = .Center
view.backgroundColor = backgroundColor
let image = createTestImageWithSize(CGSizeMake(24, 48))
view.image = image
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 1 (before resize)")
view.image = image.imageWithSize(view.frame.size)
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 1 (after resize)")
}
func aspectFit2() {
let view = UIImageView(frame: CGRectMake(0, 0, 128, 64))
view.contentMode = .Center
view.backgroundColor = backgroundColor
let image = createTestImageWithSize(CGSizeMake(72, 16))
view.image = image
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 2 (before resize)")
view.image = image.imageWithSize(view.frame.size)
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 2 (after resize)")
}
func aspectFit3() {
let view = UIImageView(frame: CGRectMake(0, 0, 64, 128))
view.contentMode = .Center
view.backgroundColor = backgroundColor
let image = createTestImageWithSize(CGSizeMake(48, 24))
view.image = image
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 3 (before resize)")
view.image = image.imageWithSize(view.frame.size, scaleMode: .AspectFit(.Top))
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 3 (after resize)")
}
func aspectFit4() {
let view = UIImageView(frame: CGRectMake(0, 0, 64, 128))
view.contentMode = .Center
view.backgroundColor = backgroundColor
let image = createTestImageWithSize(CGSizeMake(16, 72))
view.image = image
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 4 (before resize)")
view.image = image.imageWithSize(view.frame.size)
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fit 4 (after resize)")
}
func aspectFill() {
let view = UIImageView(frame: CGRectMake(0, 0, 96, 64))
view.contentMode = .Center
view.backgroundColor = backgroundColor
let image = createTestImageWithSize(CGSizeMake(32, 48))
view.image = image
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fill (before resize)")
view.image = image.scaleImage(width: view.frame.size.width, scaleMode: .AspectFill)
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Aspect fill (after resize)")
}
func fill() {
let view = UIImageView(frame: CGRectMake(0, 0, 96, 64))
view.contentMode = .Center
view.backgroundColor = backgroundColor
let image = createTestImageWithSize(CGSizeMake(32, 48))
view.image = image
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Fill (before resize)")
view.image = image.scaleImage(width: view.frame.size.width, height: view.frame.size.height, scaleMode: .Fill)
XCPlaygroundPage.currentPage.captureValue(view, withIdentifier: "Fill (after resize)")
}
aspectFit1()
aspectFit2()
aspectFit3()
aspectFit4()
aspectFill()
fill()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment