我想拉伸上图所示的左右两侧,并保持中间箭头不拉伸。我怎么能这样做?
答案 0 :(得分:7)
使用Photoshop或其他图像编辑工具将图像分成两部分:边缘和中心。边缘图像可以是一个像素宽并用于左右边缘;然而,中心有很多像素宽,可以捕捉到箭头。然后,您可以将三个UIImageView
实例放在一起:左边缘,中间边缘和右边缘。左右边缘的大小调整为所需宽度,而中心保持原始尺寸。
答案 1 :(得分:7)
如果您不喜欢麻烦的Photoshop,并且如果图像没有通过动态调整大小,您可以在UIImage上使用我的类别方法。
名为“17maA.png”的示例图像宽度为124像素。因此,您可以轻松地创建一个300 px宽的版本:
UIImage *image = [UIImage imageNamed:@"17maA"];
UIImage *newImage = [image pbResizedImageWithWidth:300 andTiledAreaFrom:10 to:20 andFrom:124-20 to:124-10];
这是类别方法:
- (UIImage *)pbResizedImageWithWidth:(CGFloat)newWidth andTiledAreaFrom:(CGFloat)from1 to:(CGFloat)to1 andFrom:(CGFloat)from2 to:(CGFloat)to2 {
NSAssert(self.size.width < newWidth, @"Cannot scale NewWidth %f > self.size.width %f", newWidth, self.size.width);
CGFloat originalWidth = self.size.width;
CGFloat tiledAreaWidth = (newWidth - originalWidth)/2;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(originalWidth + tiledAreaWidth, self.size.height), NO, self.scale);
UIImage *firstResizable = [self resizableImageWithCapInsets:UIEdgeInsetsMake(0, from1, 0, originalWidth - to1) resizingMode:UIImageResizingModeTile];
[firstResizable drawInRect:CGRectMake(0, 0, originalWidth + tiledAreaWidth, self.size.height)];
UIImage *leftPart = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions(CGSizeMake(newWidth, self.size.height), NO, self.scale);
UIImage *secondResizable = [leftPart resizableImageWithCapInsets:UIEdgeInsetsMake(0, from2 + tiledAreaWidth, 0, originalWidth - to2) resizingMode:UIImageResizingModeTile];
[secondResizable drawInRect:CGRectMake(0, 0, newWidth, self.size.height)];
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return fullImage;
}
答案 2 :(得分:3)
Klaas的答案对我很有帮助,在Swift 3.0中也是如此:
static func stretchImageSides(image: UIImage, newWidth: CGFloat) -> UIImage? {
guard image.size.width < newWidth else {
return image
}
let originalWidth = image.size.width
let tiledAreaWidth = ceil(newWidth - originalWidth) / 2.0;
UIGraphicsBeginImageContextWithOptions(CGSize(width: originalWidth + tiledAreaWidth, height: image.size.height),
false, image.scale)
let firstResizable = image.resizableImage(withCapInsets: UIEdgeInsets(top: 0,
left: 0,
bottom: 0,
right: originalWidth - 3),
resizingMode: .stretch)
firstResizable.draw(in: CGRect(x: 0, y: 0, width: originalWidth + tiledAreaWidth, height: image.size.height))
let leftPart = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: image.size.height),
false, image.scale)
let secondResizable = leftPart?.resizableImage(withCapInsets: UIEdgeInsets(top: 0,
left: tiledAreaWidth + originalWidth - 3,
bottom: 0,
right: 0),
resizingMode: .stretch)
secondResizable?.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: image.size.height))
let fullImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return fullImage
}
答案 3 :(得分:1)
(没有多大帮助,但有相反的支持:拉伸图像的中心并保持边缘部分的大小相同:请参阅Stretching an UIImage while preserving the corners。)
要制作自己的解决方案,您可以创建一个包含三个部分的组件:左图像,中央图像,右图像。然后通过确保中心部分保持相同的宽度,同时左/右组件(图像)拉伸来处理组件的尺寸更改。
替代策略:创建一个两个图像堆叠在一起的组件。较低的图像是扁平条位(没有三角形)并且水平拉伸以填充可用空间。上图是三角形中心部分,以可用空间为中心。这会产生你正在寻找的效果。
此外,有一个应用程序(不是免费的!)可以帮助您创建具有可伸缩特性的漂亮组件:PaintCode。
答案 4 :(得分:0)
基于@Arashk的答案,它是一个带有UIImage
参数的Swift size
扩展名。
被拉伸的图像的中心仍然居中。
extension UIImage {
func strechedImageSides(newSize: CGSize) -> UIImage? {
guard size.width < newSize.width || size.height < newSize.height else {
return self
}
let originalWidth = size.width
let originalHeight = size.height
let tiledAreaWidth = ceil(newSize.width - originalWidth) / 2.0
let tiledAreaHeight = ceil(newSize.height - originalHeight) / 2.0
UIGraphicsBeginImageContextWithOptions(CGSize(width: originalWidth + tiledAreaWidth,
height: originalHeight + tiledAreaHeight),
false,
scale)
let bottomRightResizable = resizableImage(withCapInsets: UIEdgeInsets(top: 0,
left: 0,
bottom: originalHeight - 1,
right: originalWidth - 1),
resizingMode: .stretch)
bottomRightResizable.draw(in: CGRect(x: 0,
y: 0,
width: originalWidth + tiledAreaWidth,
height: originalHeight + tiledAreaHeight))
let topLefthPart = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIGraphicsBeginImageContextWithOptions(newSize,
false,
scale)
let topLeftResizable = topLefthPart?.resizableImage(withCapInsets: UIEdgeInsets(top: tiledAreaHeight + originalHeight - 1,
left: tiledAreaWidth + originalWidth - 1,
bottom: 0,
right: 0),
resizingMode: .stretch)
topLeftResizable?.draw(in: CGRect(origin: .zero, size: newSize))
let fullImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return fullImage
}
}
答案 5 :(得分:-2)
我们可以使用以下代码拉伸图像: - 在这里我们需要箭头标记部分必须是相同的大小,所以我们拉伸箭头标记开始下方的中间部分(假设它将是2 px)
UIImage *image = [UIImage imageNamed:@"img_loginButton.png"];
UIEdgeInsets edgeInsets;
edgeInsets.left = 0.0f;
edgeInsets.top = 2.0f;
edgeInsets.right = 0.0f;
edgeInsets.bottom = 0.0f;
image = [image resizableImageWithCapInsets:edgeInsets];
//Use this image as your controls image