iOS开发:图片加载@2x与@3x

一、图片格式@2x与@3x

应对非视网膜和视网膜屏,APP有时会提供不同大小的图片,1倍图和2倍图和3倍图,它们的像素与1倍数图相比相差2倍或者3倍。

命名规则:2倍图在1倍图的名字后加 @2x

  • 普通:sample.png 
  • 2倍:sample@2x.png 
  • 3倍:sample@3x.png 

系统用“sample”寻找图片的时候,会自动根据设备屏幕取对应的图片

由于retina屏幕的普及,现在工程中用得最多的是@2x和@3x图片

二、加载图片的方法

图片资源在工程的位置如下图


方法一:

-(void)setImageView1{
    UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 80, 180, 180)];
    imageView.backgroundColor = [UIColor blueColor];
//只有test@2x与test@3x图片
    //4s 5 5s 6 6s 会自动加载test@2x图片
    //6Plus 6sPlus 会自动加载test@3x图片
    imageView.image = [UIImage imageNamed:@"test"];
    [self.view addSubview:imageView];
}
PS:这种方法可以加载到逻辑路径中的资源 也可以加载到Assets.xcassets中的资源,而且会根据设备自动匹配@2x和@3x图片。

方法二:

-(void)setImageView2{
    //此处的路径是物理路径如果是逻辑路径是获取不到资源的
    //这里填写test@2x或者test@3x都可以(只要这个文件在wwwwww这个文件夹真实存在即可),主要是获得这个物理路径。
    //获得到这个路径之后 后边才会根据设备自动加载@2x图片或者@3x图片。
    NSString *path = [[NSBundle mainBundle] pathForResource:@"wwwwww/test@2x" ofType:@"png"];
    NSLog(@"path = %@",path);
    //因为www是逻辑路径,用此方法是加载不到这个文件的
     NSString *path1 = [[NSBundle mainBundle] pathForResource:@"www/test@2x" ofType:@"png"];
    //所以path1的值为null;
    NSLog(@"path1 = %@",path1);//path1 = null;
    UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 80, 180, 180)];
    imageView.backgroundColor = [UIColor blueColor];
    //4s 5 5s 6 6s 会自动加载test@2x图片
    //6Plus 6sPlus 会自动加载test@3x图片
    imageView.image = [UIImage imageWithContentsOfFile:path];
    [self.view addSubview:imageView];
}

PS1:这种方法如果加载物理路径中的资源文件需要把路径指定完全。

PS2:逻辑路径中的文件其实也可以用这中方法来加载,只不过逻辑路径中的资源文件的存储位置跟文件夹显示的路径没有关系,如下:


-(void)setImageView3{
    //从此也可以看出逻辑路径下的资源文件的路径并没有真正存在 都是在工程的 根目录下app/资源文件
    UIImageView * imageViewImage = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, 100, 100)];
    imageViewImage.backgroundColor = [UIColor blueColor];
    
    //下面两种写法都没有写成:test/inTest/inTest 这种物理路径的方式,其实写成这样是识别不到inTest.png文件的 因为路径并不存在
#if 1
    NSString * mainPath = [[NSBundle mainBundle] resourcePath];
    NSString * path = [NSString stringWithFormat:@"%@/inTest",mainPath];
#else
    NSString * path = [[NSBundle mainBundle] pathForResource:@"inTest" ofType:@"png"];
#endif
    UIImage * image = [UIImage imageWithContentsOfFile:path];
    imageViewImage.image = image;
    [self.view addSubview:imageViewImage];
}

三、imageNamed 与 imageWithContentsOfFile的区别

myImage = [UIImage imageNamed:@"icon.png"];

这种方法在一些图片很少,或者图片很小的程序里是ok的。
但是,在大量加载图片的程序里,请千万不要这样做。
为什么呢 ???????

这种方法在application bundle的顶层文件夹寻找由供应的名字的图象 。 如果找到图片,装载到iPhone系统缓存图象。那意味图片是(理论上)放在内存里作为cache的。

试想你图片多了,是什么后果``````

图片cache极有可能不会响应 memory warnings and release its objects

所以,用图片的时候一定要小心的alloc和release
推荐使用

NSString *path = [[NSBundle mainBundle] pathForResource:@”icon” ofType:@”png”];
myImage = [UIImage imageWithContentsOfFile:path];
四、用UIImage加载图像的方法很多,常用如下:

    1、用imageNamed函数

[UIImage imageNamed:ImageName];

    2、用imageWithContentsOfFile函数

[UIImage imageWithContentsOfFile:path];

    3、用NSData的方式加载,例如:

NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
NSData *image = [NSData dataWithContentsOfFile:filePath];
[UIImage imageWithData:image];

        1)用imageNamed的方式加载时,系统会把图像Cache到内存。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存,而且释放图像的 内存是一件相对来说比较麻烦的事情。例如:如果利用imageNamed的方式加载图像到一个动态数组NSMutableArray,然后将将数组赋予一 个UIView的对象的animationImages进行逐帧动画,那么这将会很有可能造成内存泄露。并且释放图像所占据的内存也不会那么简单。但是利 用imageNamed加载图像也有自己的优势。对于同一个图像系统只会把它Cache到内存一次,这对于图像的重复利用是非常有优势的。例如:你需要在 一个TableView里重复加载同样一个图标,那么用imageNamed加载图像,系统会把那个图标Cache到内存,在Table里每次利用那个图 像的时候,只会把图片指针指向同一块内存。这种情况使用imageNamed加载图像就会变得非常有效。

    2)利用NSData方式加载时,图像会被系统以数据方式加载到程序。当你不需要重用该图像,或者你需要将图像以数据方式存储到数据库,又或者你要通过网络下载一个很大的图像时,请尽量使用imageWithData的方式加载图像。

    无论用哪种方式加载图像,图像使用结束后,一定要记得显示释放内存。

参考文章:

http://www.cnblogs.com/pengyingh/articles/2355033.html



评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值