photo credit: crunklygill swifts up high via photopin (license)
画像から正方形のサムネイルを作る方法を紹介する。
手順は次の通り。
- 画像をリサイズする
1-1. リサイズの目標サイズを計算する
1-2. 目標サイズへリサイズした画像を生成する - リサイズ画像をクロッピングする
2-1. サムネイルの目標サイズに合わせて、クロッピングする形を計算する
2-2. リサイズ画像をクロッピングしてサムネイルを作成する
最終的なコード全体は最下部。
GitHub で見るにはこちら。
1. 画像をリサイズする
1-1. リサイズの目標サイズを計算する
func calculateResizedWidth(sourceImage: UIImage, objectiveLengthOfShortSide: CGFloat) -> CGFloat {
let width: CGFloat = sourceImage.size.width
let height: CGFloat = sourceImage.size.height
let resizedWidth: CGFloat = width <= height ? objectiveLengthOfShortSide : objectiveLengthOfShortSide * width / height
return resizedWidth
}
上記のcalculateResizedWidth
関数を用いて、リサイズ後画像の幅をいくらにすべきかを計算する。
次の変数があるとして、
let sourceImage: UIImage = もともとのUIImage
let objectiveEdgeLength: CGFloat = サムネイルの一辺の長さとしたい値(サムネイルは正方形と仮定しています)
次のコードでリサイズ後画像の幅resizedWidth
が得られる。
let resizedWidth: CGFloat = calculateResizedWidth(sourceImage: sourceImage, objectiveLengthOfShortSide: objectiveEdgeLength)
1-2. 目標サイズへリサイズした画像を生成する
func resizeImage(sourceImage: UIImage, objectiveWidth: CGFloat) -> UIImage {
let aspectScale: CGFloat = sourceImage.size.height / sourceImage.size.width
let resizedSize: CGSize = CGSize(width: objectiveWidth, height: objectiveWidth * aspectScale)
// リサイズ後のUIImageを生成して返却
UIGraphicsBeginImageContext(resizedSize)
sourceImage.draw(in: CGRect(x: 0, y: 0, width: resizedSize.width, height: resizedSize.height))
let resizedImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resizedImage!
}
上記のresizeImage
関数に、1-1 で得たresizedWidth
を引数として渡してやることでリサイズされた画像が得られる。
let resizedImage: UIImage = resizeImage(sourceImage: sourceImage, objectiveWidth: resizedWidth)
let thumbnailSize: CGSize = CGSize(width: objectiveEdgeLength, height: objectiveEdgeLength)
2. リサイズ画像をクロッピングする
2-1. サムネイルの目標サイズに合わせて、クロッピングする形を計算する
func calulateCroppingRect(imgae: UIImage, objectiveSize: CGSize) -> CGRect {
let croppingRect: CGRect = CGRect.init(x: (imgae.size.width - objectiveSize.width) / 2, y: (imgae.size.height - objectiveSize.height) / 2, width: objectiveSize.width, height: objectiveSize.height)
return croppingRect
}
1-2 で得たresizedImage
と上記のcalulateCroppingRect
を用いて、クロッピングする形を計算する。
let thumbnailSize: CGSize = CGSize(width: objectiveEdgeLength, height: objectiveEdgeLength)
let croppingRect: CGRect = calulateCroppingRect(imgae: resizedImage, objectiveSize: thumbnailSize)
2-2. リサイズ画像をクロッピングしてサムネイルを作成する
func cropImage(image: UIImage, croppingRect: CGRect) -> UIImage {
let croppingRef: CGImage? = image.cgImage!.cropping(to: croppingRect)
let croppedImage: UIImage = UIImage(cgImage: croppingRef!)
return croppedImage
}
1-2 で得たresizedImage
と 2-1 で得たcroppingRect
を上記のcropImage
関数に渡してやることで、サムネイルを得る。
let croppedImage: UIImage = cropImage(image: resizedImage, croppingRect: croppingRect)
コード全体
generateThumbnail
関数を呼び出してやれば、サムネイルが返ってくる。
func generateThumbnail(sourceImage: UIImage, objectiveEdgeLength: CGFloat) -> UIImage {
let resizedWidth: CGFloat = calculateResizedWidth(sourceImage: sourceImage, objectiveLengthOfShortSide: objectiveEdgeLength)
let resizedImage: UIImage = resizeImage(sourceImage: sourceImage, objectiveWidth: resizedWidth)
let thumbnailSize: CGSize = CGSize(width: objectiveEdgeLength, height: objectiveEdgeLength)
let croppingRect: CGRect = calulateCroppingRect(imgae: resizedImage, objectiveSize: thumbnailSize)
let croppedImage: UIImage = cropImage(image: resizedImage, croppingRect: croppingRect)
return croppedImage
}
func calculateResizedWidth(sourceImage: UIImage, objectiveLengthOfShortSide: CGFloat) -> CGFloat {
let width: CGFloat = sourceImage.size.width
let height: CGFloat = sourceImage.size.height
let resizedWidth: CGFloat = width <= height ? objectiveLengthOfShortSide : objectiveLengthOfShortSide * width / height
return resizedWidth
}
func resizeImage(sourceImage: UIImage, objectiveWidth: CGFloat) -> UIImage {
let aspectScale: CGFloat = sourceImage.size.height / sourceImage.size.width
let resizedSize: CGSize = CGSize(width: objectiveWidth, height: objectiveWidth * aspectScale)
// リサイズ後のUIImageを生成して返却
UIGraphicsBeginImageContext(resizedSize)
sourceImage.draw(in: CGRect(x: 0, y: 0, width: resizedSize.width, height: resizedSize.height))
let resizedImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resizedImage!
}
func calulateCroppingRect(imgae: UIImage, objectiveSize: CGSize) -> CGRect {
let croppingRect: CGRect = CGRect.init(x: (imgae.size.width - objectiveSize.width) / 2, y: (imgae.size.height - objectiveSize.height) / 2, width: objectiveSize.width, height: objectiveSize.height)
return croppingRect
}
func cropImage(image: UIImage, croppingRect: CGRect) -> UIImage {
let croppingRef: CGImage? = image.cgImage!.cropping(to: croppingRect)
let croppedImage: UIImage = UIImage(cgImage: croppingRef!)
return croppedImage
}
0件のコメント