美文网首页
UIImage学习笔记

UIImage学习笔记

作者: 寻心_0a46 | 来源:发表于2019-06-19 21:49 被阅读0次

UIImage

UIImage派生自NSObject,是用于管理应用程序中图像数据的对象。可以使用image对象来表示各种图像数据,UIImage类能够管理底层平台支持的所有图像格式的数据。图像对象是不可变的,因此总是从现有的图像数据(如磁盘上的图像文件或以编程方式创建的图像数据)创建它们。图像对象可以包含要在动画中使用的单个图像或图像序列。

可以用几种不同的方式使用图像对象:

  • 1.将图像分配给UIImageView对象以在界面中显示该图像。
  • 2.使用图像可自定义系统控件,如按钮、滑块和分段控件。
  • 3.将图像直接绘制到视图或其他图形上下文中。
  • 4.将图像传递给可能需要图像数据的其他API。

虽然图像对象支持所有平台原生图像格式,但建议对应用程序中的大多数图像使用PNG或JPEG文件。图像对象针对读取和显示这两种格式进行了优化,这些格式提供了比大多数其他图像格式更好的性能。因为PNG格式是无损的,所以特别推荐在应用程序界面中使用的图像。

常用属性

@property(nonatomic,readonly) CGFloat scale API_AVAILABLE(ios(4.0));

属性描述 : 图像的比例因子。如果从一个名为@2x修饰符的文件中加载图片,比例设置为2.0。还可以在从核心图形图像初始化图像时指定显式的缩放因子。假设所有其他图像的比例因子为1.0。如果将图像的逻辑大小(存储在size属性中)乘以该属性中的值,就会得到图像的尺寸(以像素为单位)。

@property(nonatomic,readonly) CGFloat scale API_AVAILABLE(ios(4.0));

常用函数

+ (nullable UIImage *)imageNamed:(NSString *)name;

函数描述 : 从指定的命名的资源创建一个image对象。在搜索资源目录时,此方法优先选择包含符号图像的资源,而不是包含位图图像的同名资源。因为只有iOS 13及更高版本才支持符号图像,因此可以在同一个资产目录中包含这两种类型的资产。系统会自动恢复到iOS早期版本上的位图图像。不能使用此方法加载系统符号图像,需要使用systemImageNamed:方法代替。此方法检查具有指定名称的图像对象的系统缓存,并返回最适合主屏幕的图像变量。如果匹配的图像对象尚未在缓存中,则此方法从可用的资源目录创建图像或从磁盘加载它。系统可以随时清除缓存的图像数据以释放内存,但仅对缓存中当前未使用的映像进行清除。在iOS9及更高版本中,此方法是线程安全的。

参数 :

name :图像资源或文件的名称。对于资源目录中的图像,指定图像资源的名称。对于PNG图像,可以省略文件扩展名。对于所有其他文件格式,请始终包含文件扩展名。

返回值:包含未配置版本的图像的对象,如果方法找不到指定的图像,则为nil。

+ (nullable UIImage *)imageNamed:(NSString *)name;  

+ (UIImage *)imageWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation API_AVAILABLE(ios(4.0));

函数描述 : 创建并返回具有指定缩放因子和方向的图像对象。此方法不缓存图像对象。可以使用CoreGraphics.framework的方法创建一个Quartz图像引用。

参数 :

cgImage :Quartz图像对象。

scale : 解释图像数据时使用的比例因子。将比例因子指定为1.0将得到一个大小与基于像素的图像尺寸匹配的图像。应用不同的比例因子将改变由size属性报告的图像大小。

orientation :图像数据的方向。可以使用此参数指定应用于图像的任何旋转因子。

+ (UIImage *)imageWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation API_AVAILABLE(ios(4.0));

UIImageOrientation的枚举值如下:

typedef NS_ENUM(NSInteger, UIImageOrientation) {
    UIImageOrientationUp,            // 默认方向
    UIImageOrientationDown,          // 180度旋转
    UIImageOrientationLeft,          // 逆时针90度
    UIImageOrientationRight,         // 顺时针90度
    UIImageOrientationUpMirrored,    // 同上,但图像沿另一个轴镜像。水平翻转
    UIImageOrientationDownMirrored,  // 水平翻转
    UIImageOrientationLeftMirrored,  // 垂直翻转
    UIImageOrientationRightMirrored, // 垂直翻转
};

例如 :

- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    if(section == 0){
        //初始化要显示的标签富文本
        NSMutableAttributedString *newAttributedString = [[NSMutableAttributedString alloc]initWithString:@"   好友砍价榜   "];
        //创建Image的富文本格式
        NSTextAttachment *leftAttach = [[NSTextAttachment alloc] init];
        //这个-7.5是为了调整下标签跟文字的位置
        leftAttach.bounds = CGRectMake(0, -7.5, 26, 26);
        //设置图片
        leftAttach.image = [UIImage imageNamed:@"friends_bargaining"];
        //添加到富文本对象里
        NSAttributedString * leftImageStr = [NSAttributedString attributedStringWithAttachment:leftAttach];
        //加入文字前面
        [newAttributedString insertAttributedString:leftImageStr atIndex:0];
        
        //创建Image的富文本格式
        NSTextAttachment *rightAttach = [[NSTextAttachment alloc] init];
        //这个-7.5是为了调整下标签跟文字的位置
        rightAttach.bounds = CGRectMake(0, -7.5, 26, 26);
        //设置图片
        rightAttach.image = [UIImage imageWithCGImage:[UIImage imageNamed:@"friends_bargaining"].CGImage scale:[UIImage imageNamed:@"friends_bargaining"].scale orientation:UIImageOrientationDown];
        //添加到富文本对象里
        NSAttributedString * rightImageStr = [NSAttributedString attributedStringWithAttachment:rightAttach];
        //加入文字前面
        [newAttributedString insertAttributedString:rightImageStr atIndex:newAttributedString.length];
        
        //初始化要显示的标签
        UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectZero];
        //设置文本字体
        titleLabel.font = [UIFont boldSystemFontOfSize:15];
        //设置文本颜色
        titleLabel.textColor = HEXCOLOR(0xFB4E09);
        //设置文本对齐方式
        titleLabel.textAlignment = NSTextAlignmentCenter;
        //设置富文本
        titleLabel.attributedText = newAttributedString;
        //返回标签
        return titleLabel;
    }
    return nil;
}

效果如图:

截屏2020-12-12上午11.01.49.png

对图片操作的方法记录

根据网址获取图片的大小

可以获取路径类似http://timp.oss-cn-beijing.aliyuncs.com/images/746/system/config/bonus/m_bonus_img1.jpg格式的图片大小,编码格式的获取不到。
一般后台直接返回的URL不会有问题,而返回字符串路径的话,有时需要处理一下,如果路径格式不对的话,会报错NSURLConnection finished with error - code -1002。如果路径错误会报错HTTP load failed,NSURLConnection finished with error - code -1003。
例如我遇到的则是请求时未报错,但也没有拿到图片大小,后来发现返回的路径在进行拼接处理后,路径中多出一条/,例如这样也会失败:

屏幕快照 2019-08-17 上午11.00.14.png
- (CGSize)getImageSizeWithURL:(id)URL{
    NSURL * url = nil;
    if ([URL isKindOfClass:[NSURL class]]) {
        url = URL;
    }
    if ([URL isKindOfClass:[NSString class]]) {
        url = [NSURL URLWithString:URL];
    }
    if (!URL) {
        return CGSizeZero;
    }
    CGImageSourceRef imageSourceRef = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
    CGFloat width = 0, height = 0;
    if (imageSourceRef) {
        CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef, 0, NULL);
        if (imageProperties != NULL) {
            CFNumberRef widthNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
            if (widthNumberRef != NULL) {
                CFNumberGetValue(widthNumberRef, kCFNumberFloat64Type, &width);
            }
            CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
            if (heightNumberRef != NULL) {
                CFNumberGetValue(heightNumberRef, kCFNumberFloat64Type, &height);
            }
            CFRelease(imageProperties);
        }
        CFRelease(imageSourceRef);
    }
    return CGSizeMake(width, height);
}
删除URL的多余斜线,例如:
- (void)viewDidLoad {

    [super viewDidLoad];
    NSLog(@"%@",[self removeExtraSlashOfUrl:@"http://www.baidu.com/images/746//shop/144/images/2019/07/18/15634382435520.png"]);

}

- (NSString *)removeExtraSlashOfUrl:(NSString *)url {
    if (!url || url.length == 0) {
        return url;
    }
    NSString *pattern = @"(?<!(http:|https:))/+";
    NSRegularExpression *expression = [[NSRegularExpression alloc]initWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    return [expression stringByReplacingMatchesInString:url options:0 range:NSMakeRange(0, url.length) withTemplate:@"/"];
}

执行结果:

屏幕快照 2019-08-17 下午2.20.06.png
图片等宽屏幕,高度自适应的计算
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIImageView *imageView1 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"test"]];
    [self.view addSubview:imageView1];
    [imageView1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.top.equalTo(self.view).offset(44);
    }];
    
    UIImageView *imageView2 = [[UIImageView alloc]initWithFrame:CGRectZero];
    UIImage *image = [UIImage imageNamed:@"test"];
    CGSize newImageSize = resizeForScreen(image.size);
    [imageView2 setImage:image];
    [self.view addSubview:imageView2];
    [imageView2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.bottom.equalTo(self.view);
        make.size.mas_equalTo(newImageSize);
        
    }];
    
}

//等宽屏幕,高度自适应
CGSize resizeForScreen(CGSize size) {
    
    if (CGSizeEqualToSize(size, CGSizeZero)) {
        return CGSizeZero;
    }
    CGFloat const displayWidth = [UIScreen mainScreen].bounds.size.width;
    
    CGFloat const ratio = size.width / size.height;   //  宽高比
    
    CGSize displaySize = CGSizeZero;
    if (!isnan(ratio)) {
        CGFloat const displayHeight = displayWidth / ratio;
        displaySize = CGSizeMake(displayWidth, displayHeight);
    }
    
    return displaySize;
}

@end

显示结果: 屏幕快照 2019-08-19 下午10.23.34.png
更改纯色图片颜色
//UIImage(TintColor).h
//UIImage扩展类
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface UIImage(TintColor)
- (UIImage *)imageWithTintTheColor:(UIColor *)tintColor;
@end
//UIImage(TintColor).m
#import "UIImage(TintColor).h"

@implementation UIImage(TintColor)

- (UIImage *)imageWithTintTheColor:(UIColor *)tintColor {
    ///UIGraphicsBeginImageContextWithOptions()创建一个临时渲染上下文,在这上面绘制原始图片。第一个参数,size,是缩放图片的尺寸,第二个参数,isOpaque 是用来决定透明通道是否被渲染。对没有透明度的图片设置这个参数为NO,可能导致图片有粉红色调。第三个参数scale是显示缩放系数。当设置成0.0,主屏幕的缩放系数将被使用,对视网膜屏显示是2.0或者更高(在iPhone6 Plus 上是 3.0)
    ///UIScreen对象定义了基于硬件显示的相关属性,用这个类来获取每一个设备显示屏幕的对象
    ///UIScreen.mainScreen.scale:计算屏幕分辨率
    UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
    ///一个不透明类型的Quartz 2D绘画环境,相当于一个画布,你可以在上面任意绘画
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGRect area = {0, 0, self.size};
    
    CGContextScaleCTM(context, 1.0, -1.0);///坐标系X,Y缩放
    
    CGContextTranslateCTM(context, 0, -area.size.height);///坐标系平移
    
    CGContextSaveGState(context);///压栈操作,保存一份当前图形上下文
    ///CGImage:是用来重绘图形,它们在应用时是按照图像的像素矩阵来绘制图片的
    ///CGContextClipToMask:裁剪的区域,第一个参数表示context的指针,第二个参数表示裁剪到context的区域,也就是mask图片映射到context的区域,第三个参数表示mask的图片,对于裁剪区域Rect中的点是否变化取决于mask图中的alpha值,若alpha为0,则对应裁剪Rect中的点为透明,若alpha为1,则对应裁剪Rect中的点无变化
    CGContextClipToMask(context, area, self.CGImage);
    
    [tintColor set];
    
    CGContextFillRect(context, area);///  填充指定的矩形
    
    CGContextRestoreGState(context);///在没有保存之前,用这个函数还原blend mode.
    
    CGContextSetBlendMode(context, kCGBlendModeDestinationOver);///设置blend mode.
    ///CGContextDrawImage允许在制定的尺寸和位置上画图,允许在特定边缘或者适应一组图片特征比如faces,裁剪图片。
    CGContextDrawImage(context, area, self.CGImage);
    ///从当前环境当中得到重绘的图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();///关闭当前环境
    ///设置图片的渲染模式:始终绘制图片原始状态
    return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

@end

测试代码:

//ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

//ViewController.m
#import "ViewController.h"
#import "UIImage(TintColor).h"

@interface ViewController ()
//@property (nonatomic,strong) UIImage *image;
@property (nonatomic,strong) UIImageView *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect screen = [[UIScreen mainScreen]bounds];
    CGFloat oldImageViewWidth = 50;
    CGFloat oldImageViewHeigth = 50;
    CGFloat oldViewTopSpacing = 200;
    UIImageView *oldImageView = [[UIImageView alloc]initWithFrame:CGRectMake((screen.size.width - oldImageViewWidth)/2, oldViewTopSpacing, oldImageViewWidth, oldImageViewHeigth)];
    UIImage *oimage = [UIImage imageNamed:@"ic_often_courier"];
    [oldImageView setImage:oimage];
    [self.view addSubview:oldImageView];
    
    CGFloat newImageViewWidth = 50;
    CGFloat newImageViewHeigth = 50;
    CGFloat newViewTopSpacing = 400;
    UIImageView *newImageView = [[UIImageView alloc]initWithFrame:CGRectMake((screen.size.width - newImageViewWidth)/2, newViewTopSpacing, newImageViewWidth, newImageViewHeigth)];
    UIImage *nImage = [UIImage imageNamed:@"ic_often_courier"];
    UIImage *newImage = [nImage imageWithTintTheColor:[UIColor greenColor]];
    [newImageView setImage:newImage];
    [self.view addSubview:newImageView];
}
@end

显示结果:


屏幕快照 2019-03-13 上午12.04.07.png
按大小缩放图片
- (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
    UIGraphicsBeginImageContextWithOptions(size, NO, [[UIScreen mainScreen] scale]);
    [img drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

测试代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.WeiXinButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.WeiXinButton setImage:[UIImage imageNamed:@"ic_wechat"] forState:UIControlStateNormal];
    [self.WeiXinButton setTitle:@"微信支付" forState:UIControlStateNormal];
    [self.WeiXinButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    self.WeiXinButton.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 10);
    self.WeiXinButton.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
    self.WeiXinButton.layer.cornerRadius = 22.0f;
    self.WeiXinButton.layer.masksToBounds = YES;
    self.WeiXinButton.layer.borderColor = [UIColor blackColor].CGColor;
    self.WeiXinButton.layer.borderWidth = 0.6;
    
    [self.view addSubview:self.WeiXinButton];
    [self.WeiXinButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.view).offset(- 44);
        make.left.equalTo(self.view.mas_left).offset(10);
        make.right.equalTo(self.view.mas_right).offset(- 10);
        make.height.mas_equalTo(44);
    }];
    
    self.WeiXinButton2 = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.WeiXinButton2 setImage:[self scaleToSize:[UIImage imageNamed:@"ic_wechat"] size:CGSizeMake(25, 25)] forState:UIControlStateNormal];
    [self.WeiXinButton2 setTitle:@"微信支付" forState:UIControlStateNormal];
    [self.WeiXinButton2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    self.WeiXinButton2.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 10);
    self.WeiXinButton2.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
    self.WeiXinButton2.layer.cornerRadius = 22.0f;
    self.WeiXinButton2.layer.masksToBounds = YES;
    self.WeiXinButton2.layer.borderColor = [UIColor blackColor].CGColor;
    self.WeiXinButton2.layer.borderWidth = 0.6;
    
    [self.view addSubview:self.WeiXinButton2];
    [self.WeiXinButton2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.view).offset(44);
        make.left.equalTo(self.view.mas_left).offset(10);
        make.right.equalTo(self.view.mas_right).offset(- 10);
        make.height.mas_equalTo(44);
    }];
}

显示结果:

屏幕快照 2019-10-17 下午11.05.45.png
图片添加圆角
- (UIImage *)createRoundedImageWithImage:(UIImage *)image cornerRadius:(CGFloat)cornerRadius {
    
    CGRect frame = CGRectMake(0, 0, image.size.width, image.size.height);
    // 开始一个Image的上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 1.0);
    // 添加圆角
    [[UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:cornerRadius] addClip];
    // 绘制图片
    [image drawInRect:frame];
    // 接受绘制成功的图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

显示结果:

调用方法前: 屏幕快照 2019-07-10 下午10.52.05.png 调用方法后: 屏幕快照 2019-07-10 下午10.53.40.png
返回横向虚线image的方法
- (UIImage *)drawDashLineWithImageView:(UIImageView *)imageView {
    
    UIGraphicsBeginImageContext(CGSizeMake(SCREEN_WIDTH, 4.0)); //开始画线 划线的frame
    [imageView.image drawInRect:CGRectMake(0, 0, SCREEN_WIDTH, 4.0)];
    //设置线条终点形状
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapSquare);
    CGFloat lengths[] = {3.0, 3.0};
    CGContextRef line = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(line, [UIColor blackColor].CGColor);
    CGContextSetLineDash(line, 4, lengths, 2);
    CGContextMoveToPoint(line, 4.0, 4.0); //开始画线
    CGContextAddLineToPoint(line, SCREEN_WIDTH, 4.0);
    CGContextStrokePath(line);
    return UIGraphicsGetImageFromCurrentImageContext();
}

测试代码 :

- (void)viewDidLoad {
    
    [super viewDidLoad];
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectZero];
    [imageView setImage:[self drawDashLineWithImageView:imageView]];
    [self.view addSubview:imageView];
    [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.view);
        make.left.equalTo(self.view.mas_left).offset(10);
        make.right.equalTo(self.view.mas_right).offset(-10);
        make.height.mas_equalTo(1);
    }];
    
}

显示结果 :

截屏2020-01-14下午11.35.44.png

相关文章

网友评论

      本文标题:UIImage学习笔记

      本文链接:https://www.haomeiwen.com/subject/zxwlqctx.html