15

在此处输入图像描述

我想拉伸上图的左右两边,中间的箭头不拉伸。我怎样才能做到这一点?

4

6 回答 6

8

如果你不想打扰 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;
}
于 2013-03-15T23:15:16.903 回答
7

使用 Photoshop 或其他图像编辑工具将图像分成两部分:边缘和中心。边缘图像可以是一个像素宽,用于左右边缘;然而,中心是捕获箭头的许多像素宽。然后,您可以将三个UIImageView实例彼此相邻放置:左边缘、中心和右边缘。左右边缘调整为所需宽度,而中心保持其原始尺寸。

于 2013-03-15T08:01:20.017 回答
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
}
  • 您只需要提供具有所需新宽度的图像,它就会为您进行水平拉伸。
于 2017-01-29T18:59:30.973 回答
1

(没有多大帮助,但有相反的支持:拉伸图像的中心并保持边缘部分的大小相同:请参阅在保留角的同时拉伸 UIImage。)

要编写自己的解决方案,您可以创建一个包含三个部分的组件:左图、中心图、右图。然后,您可以通过确保中心部分保持相同的宽度来处理组件的大小更改,而左/右组件(图像)会拉伸。

替代策略:创建一个组件,将两个图像堆叠在一起。下图是扁条钻头(没有三角形),水平拉伸以填充可用空间。上图为三角形中心部分,以可用空间为中心。这将给出您正在寻找的效果。

此外,还有一个应用程序(不是免费的!)可以帮助您创建具有可拉伸特性的漂亮组件:PaintCode

于 2013-03-15T08:01:51.007 回答
0

基于@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
  }
}
于 2020-05-21T23:37:41.073 回答
-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
于 2013-06-11T09:01:18.610 回答