从几张图片中剖析ImageView
profile ImageView from several images
我需要实现个人资料 imageView 以便与一些成员聊天。
它应该看起来像这样:
因此,根据成员的数量,图像视图应拆分为适当的部分,其中应包含每个聊天成员的适当照片。
upd: 我找到了一些解决方案(见下文)并且有效,但有些图像被拉伸了,因为它们的实际比例是 1:1。
如何按比例拉伸 UIImage
(使用 1:1 比例)以适合矩形大小?
class ProfileImageHelper {
class func collageImage (rect:CGRect, images:[UIImage]) -> UIImage {
let maxImagesPerRow = 2
let maxSide = rect.width / CGFloat(maxImagesPerRow)
var index = 0
var currentRow = 1
var xtransform:CGFloat = 0.0
let transformOffset:CGFloat = 1.5
var ytransform:CGFloat = 0.0
var smallRect:CGRect = CGRect.zero
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)//UIScreen.main.scale)
for img in images {
index += 1
let x = index % maxImagesPerRow //row should change when modulus is 0
//row changes when modulus of counter returns zero @ maxImagesPerRow
if x == 0 {
//last column of current row
//xtransform += CGFloat(maxSide)
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
//reset for new row
currentRow += 1
xtransform = 0.0
ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset
} else {
//not a new row
if xtransform == 0 {
//this is first column
//draw rect at 0,ytransform
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
xtransform += CGFloat(maxSide) + transformOffset
} else {
//not the first column so translate x, ytransform to be reset for new rows only
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
xtransform += CGFloat(maxSide) + transformOffset
}
}
//draw in rect
img.draw(in: smallRect)
}
let outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage!
}
}
有什么建议吗?
下面的代码应该允许您将一个图像粘贴到另一个图像之上。您可以使用 x/y 位置相应地移动图像。然后您可以将最终图像裁剪成圆形。
UIImage *backrgoundImage = [[UIImage alloc] init];
backrgoundImage = image1;
UIImage *foregroundImage = [[UIImage alloc] init];
foregroundImage = image2;
UIGraphicsBeginImageContextWithOptions(backrgoundImage.size, FALSE, 0.0);
[backrgoundImage drawInRect:CGRectMake( 0, 0, backrgoundImage.size.width, backrgoundImage.size.height)];
[foregroundImage drawInRect:CGRectMake(backrgoundImage.size.width/2, backrgoundImage.size.height/2, foregroundImage.size.width, foregroundImage.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[imageView setImage:newImage];
// Crop the final image to a circle
CALayer *imageLayer = imageView.layer;
[imageLayer setCornerRadius:imageView.frame.size.width/2];
[imageLayer setBorderWidth:1];
[imageLayer setMasksToBounds:YES];
imageLayer.borderColor = (__bridge CGColorRef _Nullable)([UIColor clearColor]);
[self.view addSubview:imageView];
我用这个解决了我的问题:
class ProfileImageHelper {
class func collageImage (size:CGSize, images:[UIImage]) -> UIImage {
let maxImagesPerRow = 2
let maxSide = size.width / CGFloat(maxImagesPerRow)
var index = 0
var currentRow = 1
var xtransform:CGFloat = 0.0
let transformOffset:CGFloat = 0.5
var ytransform:CGFloat = 0.0
var smallRect:CGRect = CGRect.zero
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
for img in images {
index += 1
if index == 5 { break }
let x = index % maxImagesPerRow //row should change when modulus is 0
//row changes when modulus of counter returns zero @ maxImagesPerRow
if x == 0 {
//last column of current row
//get small image for two rows column
if Int(images.count / 2) > 1 {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height / 2) - transformOffset)
img.draw(in: smallRect)
//fit image to vertical column
} else {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height)
if let newImage = img.cropImageByMiddle() {
newImage.draw(in: smallRect)
}
}
//reset for new row
currentRow += 1
xtransform = 0.0
ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset
} else {
//not a new row
if xtransform == 0 {
//this is first column
//draw rect at 0,ytransform
if images.count == 2 {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height)
if let newImage = img.cropImageByMiddle() {
newImage.draw(in: smallRect)
}
} else {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height / 2) - transformOffset)
img.draw(in: smallRect)
}
xtransform += CGFloat(maxSide) + transformOffset
}
}
}
let outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage!
}
}
我裁剪图像,让中间部分适合垂直列。
为此,我为 UIImage
:
写了扩展
extension UIImage {
func cropImageByMiddle() -> UIImage? {
let cropRect = CGRect(x: self.size.width / 4, y: 0, width: self.size.width / 2, height: self.size.height)
if let cgImg = self.cgImage {
if let new = cgImg.cropping(to: cropRect) {
return UIImage(cgImage: new)
}
}
return nil
}
}
我需要实现个人资料 imageView 以便与一些成员聊天。
它应该看起来像这样:
因此,根据成员的数量,图像视图应拆分为适当的部分,其中应包含每个聊天成员的适当照片。
upd: 我找到了一些解决方案(见下文)并且有效,但有些图像被拉伸了,因为它们的实际比例是 1:1。
如何按比例拉伸 UIImage
(使用 1:1 比例)以适合矩形大小?
class ProfileImageHelper {
class func collageImage (rect:CGRect, images:[UIImage]) -> UIImage {
let maxImagesPerRow = 2
let maxSide = rect.width / CGFloat(maxImagesPerRow)
var index = 0
var currentRow = 1
var xtransform:CGFloat = 0.0
let transformOffset:CGFloat = 1.5
var ytransform:CGFloat = 0.0
var smallRect:CGRect = CGRect.zero
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)//UIScreen.main.scale)
for img in images {
index += 1
let x = index % maxImagesPerRow //row should change when modulus is 0
//row changes when modulus of counter returns zero @ maxImagesPerRow
if x == 0 {
//last column of current row
//xtransform += CGFloat(maxSide)
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
//reset for new row
currentRow += 1
xtransform = 0.0
ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset
} else {
//not a new row
if xtransform == 0 {
//this is first column
//draw rect at 0,ytransform
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
xtransform += CGFloat(maxSide) + transformOffset
} else {
//not the first column so translate x, ytransform to be reset for new rows only
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
xtransform += CGFloat(maxSide) + transformOffset
}
}
//draw in rect
img.draw(in: smallRect)
}
let outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage!
}
}
有什么建议吗?
下面的代码应该允许您将一个图像粘贴到另一个图像之上。您可以使用 x/y 位置相应地移动图像。然后您可以将最终图像裁剪成圆形。
UIImage *backrgoundImage = [[UIImage alloc] init];
backrgoundImage = image1;
UIImage *foregroundImage = [[UIImage alloc] init];
foregroundImage = image2;
UIGraphicsBeginImageContextWithOptions(backrgoundImage.size, FALSE, 0.0);
[backrgoundImage drawInRect:CGRectMake( 0, 0, backrgoundImage.size.width, backrgoundImage.size.height)];
[foregroundImage drawInRect:CGRectMake(backrgoundImage.size.width/2, backrgoundImage.size.height/2, foregroundImage.size.width, foregroundImage.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[imageView setImage:newImage];
// Crop the final image to a circle
CALayer *imageLayer = imageView.layer;
[imageLayer setCornerRadius:imageView.frame.size.width/2];
[imageLayer setBorderWidth:1];
[imageLayer setMasksToBounds:YES];
imageLayer.borderColor = (__bridge CGColorRef _Nullable)([UIColor clearColor]);
[self.view addSubview:imageView];
我用这个解决了我的问题:
class ProfileImageHelper {
class func collageImage (size:CGSize, images:[UIImage]) -> UIImage {
let maxImagesPerRow = 2
let maxSide = size.width / CGFloat(maxImagesPerRow)
var index = 0
var currentRow = 1
var xtransform:CGFloat = 0.0
let transformOffset:CGFloat = 0.5
var ytransform:CGFloat = 0.0
var smallRect:CGRect = CGRect.zero
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
for img in images {
index += 1
if index == 5 { break }
let x = index % maxImagesPerRow //row should change when modulus is 0
//row changes when modulus of counter returns zero @ maxImagesPerRow
if x == 0 {
//last column of current row
//get small image for two rows column
if Int(images.count / 2) > 1 {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height / 2) - transformOffset)
img.draw(in: smallRect)
//fit image to vertical column
} else {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height)
if let newImage = img.cropImageByMiddle() {
newImage.draw(in: smallRect)
}
}
//reset for new row
currentRow += 1
xtransform = 0.0
ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset
} else {
//not a new row
if xtransform == 0 {
//this is first column
//draw rect at 0,ytransform
if images.count == 2 {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height)
if let newImage = img.cropImageByMiddle() {
newImage.draw(in: smallRect)
}
} else {
smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height / 2) - transformOffset)
img.draw(in: smallRect)
}
xtransform += CGFloat(maxSide) + transformOffset
}
}
}
let outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage!
}
}
我裁剪图像,让中间部分适合垂直列。
为此,我为 UIImage
:
extension UIImage {
func cropImageByMiddle() -> UIImage? {
let cropRect = CGRect(x: self.size.width / 4, y: 0, width: self.size.width / 2, height: self.size.height)
if let cgImg = self.cgImage {
if let new = cgImg.cropping(to: cropRect) {
return UIImage(cgImage: new)
}
}
return nil
}
}