Last active
April 3, 2018 18:06
-
-
Save mxl/8d3018996468b8c48d57 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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