IOS应用开发:iOS使用矢量图
安安 2017-10-25 来源 :网络 阅读 669 评论 0

摘要:本篇IOS应用开发教程将为大家讲解iOS使用矢量图,看完这篇文章会让你对IOS编程的知识点有更加清晰的理解和运用。

本篇IOS应用开发教程将为大家讲解iOS使用矢量图,看完这篇文章会让你对IOS编程的知识点有更加清晰的理解和运用。

 

iOS 图标通常用 PNG 格式的图片。PNG 图片放大到超过自身的大小就会模糊。可以使用 PDF 格式的矢量图,优点是任意改变图片大小并且保持清晰度。

简单使用

与 PNG 格式的图片一样,在 Xcode 中把 PDF 格式的矢量图拖进 *.xcassets (默认是 Assets.xcassets) 文件夹中,然后用不带后缀(.pdf)的文件名生成 UIImage

imageView.image = [UIImage imageNamed:@"Vector"];

注意,如果以上代码用 "Vector.pdf",无法得到 UIImage。

这样做的话,Xcode 会在编译时根据 PDF 图的大小生成 @1x、@2x、@3x 的 PNG 图片,与使用 PNG 图片的显示效果相同。如果把图片放大到超过 PNG 图片的大小,则会显示模糊的图片。没有发挥矢量图可以任意调整大小的优点。

改变矢量图大小

如果需要改变矢量图大小并且保持清晰度,那就要解析 PDF 源文件,把矢量图绘制成所需大小的位图(Bitmap)。YHPDFImageLoader 库就实现了这个功能,并且可以选择拉伸图片时是否保持原图宽高比,还添加了内存和磁盘缓存。解析 PDF 并绘制位图的代码在 YHPDFImageDraw.m 文件的 drawImageWithURL:size:canStretched:page: 方法中。但是那些代码有 bug,在保持原图宽高比的时候,绘制出的位图不居中。这里参照那些代码,写了 UIImage 的 Category,用于解析 PDF 源文件,绘制指定大小的位图;可以选择拉伸图片时是否保持原图宽高比;拉伸时保持图片居中。注意,这里的 PDF 文件放在工程目录中,与 *.m、*.h 文件一样,不能放在 *.xcassets 里。

#import "UIImage+Vector.h"

@implementation UIImage (Vector)

 

+ (UIImage *)vectorImageWithName:(NSString *)name size:(CGSize)size {

    // 默认保持原图宽高比

    return [self vectorImageWithName:name size:size stretch:NO];

}

 

+ (UIImage *)vectorImageWithName:(NSString *)name size:(CGSize)size stretch:(BOOL)stretch {

    // PDF 文件路径

    NSString *path = [NSBundle.mainBundle pathForResource:name ofType:@"pdf"];

    NSAssert(path, @"Vector image file path should NOT be nil");

    if (!path) return nil;

    return [self vectorImageWithURL:[NSURL fileURLWithPath:path] size:size stretch:stretch page:1];

}

// url: PDF 文件 URL// size: 所需绘制图片大小;如果需要绘制原图大小,用 CGSizeZero// stretch: 是否拉伸;YES,拉伸图片,忽略原图宽高比;NO,保持原图宽高比

+ (UIImage *)vectorImageWithURL:(NSURL *)url size:(CGSize)size stretch:(BOOL)stretch page:(NSUInteger)page {

    

    CGFloat screenScale = UIScreen.mainScreen.scale;

    // PDF 源文件

    CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((__bridge CFURLRef)url);

    // PDF 中的一页

    CGPDFPageRef imagePage = CGPDFDocumentGetPage(pdfRef, page);

    // PDF 这一页显示出来的 CGRect

    CGRect pdfRect = CGPDFPageGetBoxRect(imagePage, kCGPDFCropBox);

    // 传入的大小如果为零,使用 PDF 原图大小

    CGSize contextSize = (size.width <= 0 || size.height <= 0) ? pdfRect.size : size;

    // RGB 颜色空间

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // 位图上下文

    CGContextRef context = CGBitmapContextCreate(NULL,

                                                 contextSize.width * screenScale,

                                                 contextSize.height * screenScale,

                                                 8,

                                                 0,

                                                 colorSpace,

                                                 kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);

    // 坐标缩放,增加清晰度

    CGContextScaleCTM(context, screenScale, screenScale);

    

    if (size.width > 0 && size.height > 0) {

        // 指定图片大小,需要缩放图片

        // 计算宽高缩放比

        CGFloat widthScale = size.width / pdfRect.size.width;

        CGFloat heightScale = size.height / pdfRect.size.height;

        

        if (!stretch) {

            // 保持原图宽高比,使用宽高缩放比中的最小值

            heightScale = MIN(widthScale, heightScale);

            widthScale = heightScale;

            // 坐标平移,使图片居中

            CGFloat currentRatio = size.width / size.height;

            CGFloat realRatio = pdfRect.size.width / pdfRect.size.height;

            if (currentRatio < realRatio) {

                CGContextTranslateCTM(context, 0, (size.height - size.width / realRatio) / 2);

            } else {

                CGContextTranslateCTM(context, (size.width - size.height * realRatio) / 2, 0);

            }

        }

        // 用以上宽高缩放比缩放坐标

        CGContextScaleCTM(context, widthScale, heightScale);

        

    } else {

        // 使用原图大小

        // 获取原图坐标转换矩阵,用于位图上下文

        CGAffineTransform drawingTransform = CGPDFPageGetDrawingTransform(imagePage, kCGPDFCropBox, pdfRect, 0, true);

        CGContextConcatCTM(context, drawingTransform);

    }

    // 把 PDF 中的一页绘制到位图

    CGContextDrawPDFPage(context, imagePage);

    CGPDFDocumentRelease(pdfRef);

    // 创建 UIImage

    CGImageRef image = CGBitmapContextCreateImage(context);

    UIImage *pdfImage = [[UIImage alloc] initWithCGImage:image scale:screenScale orientation:UIImageOrientationUp];

    // 释放资源

    CGImageRelease(image);

    CGContextRelease(context);

    CGColorSpaceRelease(colorSpace);

    

    return pdfImage;

}

@end

使用方法

// 保持原图宽高比

imageView.image = [UIImage vectorImageWithName:@"Vector" size:CGSizeMake(50, 50)];// 拉伸图片,忽略原图宽高比

imageView.image = [UIImage vectorImageWithName:@"Vector"

                                          size:CGSizeMake(50, 50)

                                       stretch:YES];

参考

//lugede.cn/ios-use-vector-pdf-image

https://github.com/jiisd/YHPDFImageLoader

希望这篇文章可以帮助到你。总之,同学们,你想要的职坐标IOS频道都能找到!


本文由 @安安 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程