我想拉伸上图的左右两边,中间的箭头不拉伸。我怎样才能做到这一点?
6 回答
如果你不想打扰 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;
}
使用 Photoshop 或其他图像编辑工具将图像分成两部分:边缘和中心。边缘图像可以是一个像素宽,用于左右边缘;然而,中心是捕获箭头的许多像素宽。然后,您可以将三个UIImageView
实例彼此相邻放置:左边缘、中心和右边缘。左右边缘调整为所需宽度,而中心保持其原始尺寸。
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
}
- 您只需要提供具有所需新宽度的图像,它就会为您进行水平拉伸。
(没有多大帮助,但有相反的支持:拉伸图像的中心并保持边缘部分的大小相同:请参阅在保留角的同时拉伸 UIImage。)
要编写自己的解决方案,您可以创建一个包含三个部分的组件:左图、中心图、右图。然后,您可以通过确保中心部分保持相同的宽度来处理组件的大小更改,而左/右组件(图像)会拉伸。
替代策略:创建一个组件,将两个图像堆叠在一起。下图是扁条钻头(没有三角形),水平拉伸以填充可用空间。上图为三角形中心部分,以可用空间为中心。这将给出您正在寻找的效果。
此外,还有一个应用程序(不是免费的!)可以帮助您创建具有可拉伸特性的漂亮组件:PaintCode。
基于@Arashk 的回答,一个带有参数的 SwiftUIImage
扩展。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
}
}
我们可以使用下面的代码拉伸图像:- 这里我们需要箭头标记部分必须是相同的大小,所以我们拉伸箭头标记开始下方的中间部分(假设它将是 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