【问题标题】:How to use 9-patch images in IOS?如何在 IOS 中使用 9-patch 镜像?
【发布时间】:2012-07-12 07:36:01
【问题描述】:

我想在我的 IOS 应用中使用 9-patch 图像。有可能吗?

【问题讨论】:

标签: ios nine-patch


【解决方案1】:

【讨论】:

  • 你是对的,resizableImageWithCapInsets: 很棒。但它不是 9 补丁。它将允许您应用一些关于如何调整图像大小的规则。但它不会复制 9 补丁。
  • 是的,上面的答案是正确的,但是 9 补丁是比它更好的选择
【解决方案2】:

你可以试试这个简单的实现: https://github.com/shiami/SWNinePatchImageFactory

这个概念很简单,描述如下:

该技术只是将 9-patch PNG 图像转换为 iOS 兼容、可调整大小的 UIImage 对象。 有关更多信息,请参阅 UIImage 的方法 resizableImageWithCapInsets:(UIEdgeInsets)insets。 所以它只支持在水平和垂直两侧拉伸一段补丁标记。

+ (UIImage*)createResizableImageFromNinePatchImage:(UIImage*)ninePatchImage
{
    NSArray* rgbaImage = [self getRGBAsFromImage:ninePatchImage atX:0 andY:0 count:ninePatchImage.size.width * ninePatchImage.size.height];
    NSArray* topBarRgba = [rgbaImage subarrayWithRange:NSMakeRange(1, ninePatchImage.size.width - 2)];
    NSMutableArray* leftBarRgba = [NSMutableArray arrayWithCapacity:0];
    int count = [rgbaImage count];
    for (int i = 0; i < count; i += ninePatchImage.size.width) {
        [leftBarRgba addObject:rgbaImage[i]];
    }

    int top = -1, left = -1, bottom = -1, right = -1;
    count = [topBarRgba count];
    for (int i = 0; i <= count - 1; i++) {
        NSArray* aColor = topBarRgba[i];
        if ([aColor[3] floatValue] == 1) {
            left = i;
            break;
        }
    }
    NSAssert(left != -1, @"The 9-patch PNG format is not correct.");
    for (int i = count - 1; i >= 0; i--) {
        NSArray* aColor = topBarRgba[i];
        if ([aColor[3] floatValue] == 1) {
            right = i;
            break;
        }
    }
    NSAssert(right != -1, @"The 9-patch PNG format is not correct.");
    for (int i = left + 1; i <= right - 1; i++) {
        NSArray* aColor = topBarRgba[i];
        if ([aColor[3] floatValue] < 1) {
            NSAssert(NO, @"The 9-patch PNG format is not support.");
        }
    }
    count = [leftBarRgba count];
    for (int i = 0; i <= count - 1; i++) {
        NSArray* aColor = leftBarRgba[i];
        if ([aColor[3] floatValue] == 1) {
            top = i;
            break;
        }
    }
    NSAssert(top != -1, @"The 9-patch PNG format is not correct.");
    for (int i = count - 1; i >= 0; i--) {
        NSArray* aColor = leftBarRgba[i];
        if ([aColor[3] floatValue] == 1) {
            bottom = i;
            break;
        }
    }
    NSAssert(bottom != -1, @"The 9-patch PNG format is not correct.");
    for (int i = top + 1; i <= bottom - 1; i++) {
        NSArray* aColor = leftBarRgba[i];
        if ([aColor[3] floatValue] == 0) {
            NSAssert(NO, @"The 9-patch PNG format is not support.");
        }
    }

    UIImage* cropImage = [ninePatchImage crop:CGRectMake(1, 1, ninePatchImage.size.width - 2, ninePatchImage.size.height - 2)];

    return [cropImage resizableImageWithCapInsets:UIEdgeInsetsMake(top, left, bottom, right)];
}

SWNinePatchImageView 还提供了 Nib 或 Storyboard 用法。 您可以在 repo 中查看示例项目。

【讨论】:

    【解决方案3】:

    最可能的结果是 https://github.com/andylanddev/Tortuga22-NinePatch 9-patch 库已经使用了波纹管方法 resizableImageWithCapInsets:(UIEdgeInsets)insets

    【讨论】:

      【解决方案4】:

      您可以使用图像裁剪和图像拉伸。

      图像裁剪

             func crop(img: UIImage, with rect: CGRect) -> UIImage? {
                  guard let cgImg = img.cgImage else { return nil }
                  // Create bitmap image from context using the rect
                  if let imageRef: CGImage = cgImg.cropping(to: rect){
                      // Create a new image based on the imageRef and rotate back to the original orientation
                      let image: UIImage = UIImage(cgImage: imageRef, scale: img.scale, orientation: img.imageOrientation)
                      return image
                  }
                  else{
                      return nil
                  }
              }
      

      图像拉伸

      func stretch(image: UIImage, newWidth: CGFloat) -> UIImage? {
              guard image.size.width < newWidth else {
                  return image
              }
      
              let originalWidth = image.size.width
              let offset: CGFloat = 1
              // crop left first
              let left = crop(img: image, with: CGRect(x: 0, y: 0, width: originalWidth/2, height: image.size.height))
              // crop right first
              let right = crop(img: image, with: CGRect(x: originalWidth/2, y: 0, width: originalWidth/2, height: image.size.height))
      
              UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: image.size.height),
                                                     false, image.scale)
      
              let lhsResizable = left?.resizableImage(withCapInsets: UIEdgeInsets(top: 0,
                                                                                        left: originalWidth/2 - offset,
                                                                                        bottom: 0,
                                                                                        right: 0),
                                                        resizingMode: .stretch)
              // draw left stretched first
              lhsResizable?.draw(in: CGRect(x: 0, y: 0, width: newWidth/2, height: image.size.height))
              
              let rhsResizable = right?.resizableImage(withCapInsets: UIEdgeInsets(top: 0,
                                                                                        left: 0,
                                                                                        bottom: 0,
                                                                                        right: originalWidth/2 - offset),
                                                        resizingMode: .stretch)
              // then , draw right stretched
              rhsResizable?.draw(in: CGRect(x: newWidth/2, y: 0, width: newWidth/2, height: image.size.height))
      
              let fullImage = UIGraphicsGetImageFromCurrentImageContext()
              UIGraphicsEndImageContext()
      
              return fullImage
          }
      

      这是一个例子:

      • 原始图像:

      礼物.9

      • 处理后的图像

      • 示例代码:

              view.backgroundColor = UIColor.white
              let imgViewWidth: CGFloat = 300
              let imgView = UIImageView(frame: CGRect(origin: CGPoint(x: 50, y: 250), size: CGSize(width: imgViewWidth, height: 100)))
              view.addSubview(imgView)
              if let image = UIImage(named: "gift.9"), let img = stretch(image: image, newWidth: imgViewWidth){
                  imgView.image = img
              }
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-21
        • 2016-11-18
        相关资源
        最近更新 更多