我正在尝试划分图像以从中创建 16 个图像(在矩阵中)。我正在使用 swift 2.1。这是代码:
let cellSize = Int(originalImage.size.height) / 4
for i in 0...4 {
for p in 0...4 {
let tmpImgRef: CGImage = originalImage.CGImage!
let rect: CGImage = CGImageCreateWithImageInRect(tmpImgRef, CGRectMake(CGFloat(i * cellSize), CGFloat(p * cellSize), CGFloat(cellSize), CGFloat(cellSize)))!
gameCells.append(cell)
}
}
这可行,但返回的图像只是原始图像的一部分。我一直在搜索,我知道那是因为当我创建 CGImage 时它的大小与 UIImage 不同,但我不知道如何修复它。如果我可以使用 CGImage 的高度而不是 UIImage 来创建变量 cellSize,我想我会修复它,但我无法获得 CGImage 的高度。
感谢您的帮助!
最佳答案
根本问题是 UIImage
和 CGImage
如何解释它们的大小
之间的差异。 UIImage
使用“点”,CGImage
使用像素。转换因子是 scale
.
例如,如果 UIImage
的 scale
为 3,则 UIImage
任何给定方向上的每个“点”,都有三个底层 CGImage
中那个方向的像素。因此,对于 scale
为 3 且 size
为 100x100 点的 UIImage
,底层 CGImage
有一个大小为 300x300 像素。
返回一个由 n x n 切片的简单图像数组(例如,如果 n 为三,则将有九张图像数组),您可以在 Swift 3 中执行类似以下操作:
/// Slice image into array of tiles
///
/// - Parameters:
/// - image: The original image.
/// - howMany: How many rows/columns to slice the image up into.
///
/// - Returns: An array of images.
///
/// - Note: The order of the images that are returned will correspond
/// to the `imageOrientation` of the image. If the image's
/// `imageOrientation` is not `.up`, take care interpreting
/// the order in which the tiled images are returned.
func slice(image: UIImage, into howMany: Int) -> [UIImage] {
let width: CGFloat
let height: CGFloat
switch image.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
width = image.size.height
height = image.size.width
default:
width = image.size.width
height = image.size.height
}
let tileWidth = Int(width / CGFloat(howMany))
let tileHeight = Int(height / CGFloat(howMany))
let scale = Int(image.scale)
var images = [UIImage]()
let cgImage = image.cgImage!
var adjustedHeight = tileHeight
var y = 0
for row in 0 ..< howMany {
if row == (howMany - 1) {
adjustedHeight = Int(height) - y
}
var adjustedWidth = tileWidth
var x = 0
for column in 0 ..< howMany {
if column == (howMany - 1) {
adjustedWidth = Int(width) - x
}
let origin = CGPoint(x: x * scale, y: y * scale)
let size = CGSize(width: adjustedWidth * scale, height: adjustedHeight * scale)
let tileCgImage = cgImage.cropping(to: CGRect(origin: origin, size: size))!
images.append(UIImage(cgImage: tileCgImage, scale: image.scale, orientation: image.imageOrientation))
x += tileWidth
}
y += tileHeight
}
return images
}
或者,在 Swift 2.3 中:
func slice(image image: UIImage, into howMany: Int) -> [UIImage] {
let width: CGFloat
let height: CGFloat
switch image.imageOrientation {
case .Left, .LeftMirrored, .Right, .RightMirrored:
width = image.size.height
height = image.size.width
default:
width = image.size.width
height = image.size.height
}
let tileWidth = Int(width / CGFloat(howMany))
let tileHeight = Int(height / CGFloat(howMany))
let scale = Int(image.scale)
var images = [UIImage]()
let cgImage = image.CGImage!
var adjustedHeight = tileHeight
var y = 0
for row in 0 ..< howMany {
if row == (howMany - 1) {
adjustedHeight = Int(height) - y
}
var adjustedWidth = tileWidth
var x = 0
for column in 0 ..< howMany {
if column == (howMany - 1) {
adjustedWidth = Int(width) - x
}
let origin = CGPoint(x: x * scale, y: y * scale)
let size = CGSize(width: adjustedWidth * scale, height: adjustedHeight * scale)
let tileCgImage = CGImageCreateWithImageInRect(cgImage, CGRect(origin: origin, size: size))!
images.append(UIImage(CGImage: tileCgImage, scale: image.scale, orientation: image.imageOrientation))
x += tileWidth
}
y += tileHeight
}
return images
}
这确保生成的图像在正确的 scale
中(这就是为什么上面以“点”跨越图像并乘以在 CGImage 中获得正确像素的原因
)。同样,如果以“点”为单位测量的尺寸不能被 n 整除,它将分别弥补最后一张图像中该行或该列的差异。例如。当你为一个高度为 736 点的图像制作三个图 block 时,前两个将是 245 点,但最后一个将是 246 点)。
有一个异常(exception),这并没有(完全)优雅地处理。即,如果 UIImage
的 imageOrientation
不是 .up
,则检索图像的顺序对应于该方向,而不是在您查看图像时显示在图像的左上角。
关于ios - 用swift将图像划分为图像数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43008098/