我想在我的 IOS 应用程序中使用 9-patch 图像。可能吗?
问问题
34341 次
4 回答
20
查看 UIImage 的方法resizableImageWithCapInsets:(UIEdgeInsets)capInsets
。
于 2012-07-12T08:21:47.937 回答
4
你可以试试这个简单的实现: 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 中查看示例项目。
于 2014-07-10T15:59:39.600 回答
1
最可能的结果是 https://github.com/andylanddev/Tortuga22-NinePatch 9-patch 库已经使用了波纹管方法 resizableImageWithCapInsets:(UIEdgeInsets)insets
于 2014-03-19T02:18:39.030 回答
0
您可以使用图像裁剪和图像拉伸。
图像裁剪
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 }
于 2022-01-18T19:26:22.593 回答