开发笔记(图片相册相机)

目录

1.获取图片的自身大小
2.iOS系统8.x上面icon图片花屏问题处理
3.图片URL中含有中文无法显示
4.iPhone上读取图片数据的简单方法
5.跳转相册的时候想修改相册上方导航栏的文字、颜色等
6.图片压缩并转base64功能
7.图片压缩方法(知本家)
8.图片选择器:PictureSelector
9.iOS中图片拉伸的几种方式
10.相机 - 相册访问
11.相机和相册介绍
12.Xcode里面xx.xcassets图标1x、2x、3x什么时候调用

1.获取图片的自身大小

2.iOS系统8.x上面icon图片花屏问题处理

这种情况下,把图片资源直接放在bundle下,不要放在image assets下。
https://www.jianshu.com/p/ca0bbb403143

3.图片URL中含有中文无法显示

在开发的过程中经常会遇到记载图片的问题,一般由后台给我们提供图片的链接地址,我们使用第三方库进行记载,而在个别图片是带有汉字的,导致图片记载失败导致一些问题。针对这个问题是由于,我们在使用带有汉字的url请求时,汉字部分转码会出现错误。解决办法是将url进行UTF-8编码转换之后再请求,这样就能顺利加载出图片了。图片接口如:http: //7xq0ch.com1.z0.glb.clouddn.com//company/1521171384722/灰car5?e=1523763412&token=TwDqISTq2s5np1-

4.iPhone上读取图片数据的简单方法

iPhone上读取图片数据的简单方法有两种:UIImageJPEGRepresentation和UIImagePNGRepresentation

1.JPEG需要两个参数:图片的引用和压缩系数,PNG只需要图片引用作为参数(这里JPEG表示UIImageJPEGRepresentation;PNG表示UIImagePNGRepresentation)
2.PNG比JPEG返回的图片数据量大很多,耗时长,有时候会卡顿
3.JPEG可以通过更改压缩系数缩小图片数据量(如果对照片的清晰度没有非常高的要求);而且从视角角度看,其图片的质量并没有明显的降低

  • 总结:在读取图片数据内容时,建议优先使用UIImageJPEGRepresentation,并可根据自己的实际使用场景设置压缩系数,进一步降低图片数据量大小

相关链接:https://blog.csdn.net/he317165264/article/details/50401959

UIImage *getImage = [UIImage imageWithContentsOfFile:file];
NSData *data;
if (UIImagePNGRepresentation(getImage) == nil){
   data = UIImageJPEGRepresentation(getImage, 1);
} else {
   data = UIImagePNGRepresentation(getImage);
}
  • 例子:李库管微信发送账单的时候,使用UIImageJPEGRepresentation导致用[WXApi sendReq:req]方法时,iPhoneX无法授权微信(手机上已经安装了微信,但识别是没有安装);解决方法是改成使用UIImagePNGRepresentation方法,所以在这个微信调起的地方还是用PNG的图片设置方法比较好
UIImagePNGRepresentation

5.跳转相册的时候想修改相册上方导航栏的文字、颜色等

导航栏相关的文字、颜色等修改

6.图片压缩并转base64功能

问题场景:填写认证信息的时候需要从手机选择照片上传到服务器,像素较高,上传时间会很长,用户体验较差,所以通过压缩上传提高速度。

相关链接:
图片压缩:https://www.jianshu.com/p/0b1d10cf8f61
图片压缩第三方库:ZipArchive(https://github.com/ZipArchive/ZipArchive
图片转base64:
https://www.jianshu.com/p/77d1370c0bab
https://www.jianshu.com/p/91979b5def90

1.解决方法1:常规压缩

// 图片压缩方法
- (NSData *)zipNSDataWithImage:(UIImage *)sourceImage{ //进行图像尺寸的压缩
    
    CGSize imageSize = sourceImage.size;//取出要压缩的image尺寸
    CGFloat width = imageSize.width; //图片宽度
    CGFloat height = imageSize.height; //图片高度 //1.宽高大于1280(宽高比不按照2来算,按照1来算)
    
    if (width>1280 || height>1280) {
        
        if (width>height) {
            
            CGFloat scale = height/width;
            width = 1280;
            height = width*scale;
        } else {
            
            CGFloat scale = width/height;
            height = 1280;
            width = height*scale;
        } //2.宽大于1280高小于1280
    } else if (width>1280 || height<1280) {
        
        CGFloat scale = height/width;
        width = 1280;
        height = width*scale; //3.宽小于1280高大于1280
        
    } else if (width<1280 || height>1280) {
        
        CGFloat scale = width/height;
        height = 1280;
        width = height*scale; //4.宽高都小于1280
    } 
    
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    [sourceImage drawInRect:CGRectMake(0,0,width,height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext(); //进行图像的画面质量压缩
    NSData *data = UIImageJPEGRepresentation(newImage, 1.0);
    
    if (data.length>100*1024) {
        
        if (data.length>1024*1024) {//1M以及以上
            
            data = UIImageJPEGRepresentation(newImage, 0.7);
        } else if (data.length>512*1024) {//0.5M-1M
            
            data = UIImageJPEGRepresentation(newImage, 0.8);
        } else if (data.length>200*1024) { //0.25M-0.5M
            
            data = UIImageJPEGRepresentation(newImage, 0.9);
        }
    }
    return data;
}
要用的地方回调

2.解决方法2:第三方库ZipArchive压缩

大致代码

7.图片压缩方法(知本家)

  • 封装的方法
/// 图片压缩
/// @param originalImage 原图片
/// @param imgWidth 裁剪的宽 默认屏幕宽
/// @param imgHeight 裁剪的高 默认屏幕高
/// @param qualityNum 图片质量设置 默认 1
+ (UIImage *)compressImage:(UIImage *)originalImage andImageWidth:(CGFloat)imgWidth AndImageHeight:(CGFloat)imgHeight andImageQuality:(CGFloat)qualityNum {
    
    CGFloat scaleWidth;
    CGFloat scaleHeight;
    CGFloat widthInPoint;
    CGSize newSize;
    NSData *imageData = UIImageJPEGRepresentation(originalImage, 1.0);
    
    if (imageData.length>2*1024*1024) {
        
          if (imgWidth==0) {
              scaleWidth = [UIScreen mainScreen].bounds.size.width * 2;
              widthInPoint = scaleWidth / [[UIScreen mainScreen] scale];
          } else {
              scaleWidth = imgWidth * 2;
              widthInPoint = scaleWidth / [[UIScreen mainScreen] scale];
          }
          
          if (imgHeight==0) {
              scaleHeight = widthInPoint * originalImage.size.height / originalImage.size.width;
          } else {
              scaleHeight = imgHeight * 2;
              scaleHeight = scaleHeight / [[UIScreen mainScreen] scale];
          }
        
          newSize = CGSizeMake(widthInPoint,scaleHeight);
          UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:newSize];
          UIImage * tempImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
              [originalImage drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
          }];
          tempImage = [UIImage imageWithData:UIImageJPEGRepresentation(tempImage, qualityNum)];
          return tempImage;
    } else {
        return originalImage;
    }
}
  • 举例实际应用
//点击相机方法
- (void)takingPictures {
    [self.imagePicker photographWithController:self selectedAssets:@[] finishPickering:^(NSArray<UIImage *> * _Nonnull photos, NSArray * _Nonnull assets) {
        
        UIImage *image = [UIImage imageWithData:UIImageJPEGRepresentation([photos[0] fixOrientation], 0.5)];
        NSData *fileData = UIImageJPEGRepresentation(image, 1.0);
        
        if (fileData.length >  20 * 1024 * 1024) {
            [MBProgressHUD showError:kLocLanguage(@"txt_JHAddInfoViewController_waringGigMessage") toView:kWindow];
        } else {
            image = [UIImage compressImage:image andImageWidth:0 AndImageHeight:0 andImageQuality:0.5];
            NSVillagePictureFileList *model = [NSVillagePictureFileList new];
            model.chooseImage = image;
            [self.dataArr addObj:model];
            [self.collectionView reloadData];
            [self setAddBtnFram];
        }
    }];
}

8.图片选择器:PictureSelector

https://www.jianshu.com/p/cf091f9becfd?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

9.iOS中图片拉伸的几种方式

1.UIImageView整体拉伸

UIImageView-contentMode:

typedef NS_ENUM(NSInteger, UIViewContentMode) {    
UIViewContentModeScaleToFill,         // 默认 拉伸(会变形)    
UIViewContentModeScaleAspectFit,      // 等比例拉伸    
UIViewContentModeScaleAspectFill,     // 等比例填充    
UIViewContentModeRedraw,              // redraw on bounds change (这个不清楚)     
UIViewContentModeCenter,              // 下面的就是不拉伸按位置显示了    
UIViewContentModeTop,    
UIViewContentModeBottom,    
UIViewContentModeLeft,    
UIViewContentModeRight,    
UIViewContentModeTopLeft,    
UIViewContentModeTopRight,    
UIViewContentModeBottomLeft,    
UIViewContentModeBottomRight,
};

2.UIImage局部拉伸

// 按4边间距显示不拉伸的区域
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(5_0); 
// 按2点拉伸
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode;
// 拉伸模式
typedef NS_ENUM(NSInteger, UIImageResizingMode) {    
UIImageResizingModeTile,//进行区域复制模式拉伸    
UIImageResizingModeStretch,//进行渐变复制模式拉伸
};

3.UIImage修改大小

//内缩放,一条变等于最长边,另外一条小于等于最长边
- (UIImage *)scaleToSize:(CGSize)newSize {    
CGFloat width = self.size.width;    
CGFloat height= self.size.height;    
CGFloat newSizeWidth = newSize.width;    
CGFloat newSizeHeight= newSize.height;    
if (width <= newSizeWidth &&height <= newSizeHeight) 
{        
return self;    
}        
if (width == 0 || height == 0 || newSizeHeight == 0 || newSizeWidth == 0) 
{        
return nil;    
}    
CGSize size;    
if (width / height > newSizeWidth / newSizeHeight) 
{        
size = CGSizeMake(newSizeWidth, newSizeWidth * height / width);    
} 
else 
{        
size = CGSizeMake(newSizeHeight * width / height, newSizeHeight);    
}    
return [self drawImageWithSize:size];
}

- (UIImage *)drawImageWithSize: (CGSize)size {    
CGSize drawSize = CGSizeMake(floor(size.width), floor(size.height));    
UIGraphicsBeginImageContext(drawSize);        
[self drawInRect:CGRectMake(0, 0, drawSize.width, drawSize.height)];   
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
UIGraphicsEndImageContext();    
return newImage;
}

4.images.xcassets

在Xcode中选中图片,然后点击右下角的Show Slicing
slicing 面板和一个按钮"Start Slicing
点击按钮之后,会显示下面的三个选项,左边的按钮用于horizontal edge insets,右边的按钮用于vertical edge insets,中间的则是两个都有。在我们的例子中要保留圆角,所以我们按中间的按钮,告诉系统我们想要按钮的中间在水平和垂直方向拉伸。在按下按钮之后,就能看到一些可以拖动的细条,这可以设置从哪里开始拉伸图片
系统会保留深紫色的区域,浅紫色的区域会被拉伸
更厉害的是,Xcode自动找到了圆角,所以我们不需要设置从哪里开始拉伸图片。最后别忘了在Attribtues pane中设置图片是可拉伸的

如果我是你的话,我就会尝试并习惯这个功能。有了这个无价之宝,你就不用再在resizableImageWithCapInsets方法中填写那些神奇的数字了,也能帮助你分离view逻辑和app逻辑。转载自原文

10.相机 - 相册访问

1.问题描述

1.访问相机和相册的时候,如果用户拒绝访问,则进入显示系统的页面,想改里面的导航拦右边的取消按钮的颜色
2.初次下载app时相机和相册的访问权限的设置操作(注意分为:根据状态来判断 || 根据允许和不允许的操作回调来判断)

2.解决问题

  • 改变颜色
[[UINavigationBar appearance] setBarTintColor: [UToColor whiteColor]];
[[UINavigationBar appearance] setTintColor:[UToColor blackColor]];
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UToColor blackColor],NSFontAttributeName:[UToFont defaultAdaptationFontWithSize:16.0]}];
  • 权限设置问题
    1.根据按钮的回调方法来判断:(即用户还没有点击过允许和不允许,现在进行点击来获取相应展示)
// 相机
[_selectHeadImgView camerBtnClick:^(UIButton *sender){// 相机
        
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            
          [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {//相机权限
                
             if (granted) {
                    
                    UIImagePickerController *imagePickerVC = [[UIImagePickerController alloc] init];
                    imagePickerVC.sourceType = UIImagePickerControllerSourceTypeCamera;
                    imagePickerVC.modalPresentationStyle = UIModalPresentationCurrentContext;
                    [[UINavigationBar appearance] setBarTintColor: [UToColor whiteColor]];
                    [[UINavigationBar appearance] setTintColor:[UToColor blackColor]];
                    [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UToColor blackColor],NSFontAttributeName:[UToFont defaultAdaptationFontWithSize:16.0]}];
                    imagePickerVC.allowsEditing = YES;
                    imagePickerVC.delegate = self;
                    
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        
                        [self presentViewController:imagePickerVC animated:YES completion:NULL];
                    });
                } else {
                    
                    UToAlert *aler =[UToAlert AlertTitle:@"无法使用相机" content:@"请在iPhone的“设置-隐私-相机”中允许访问相机。" cancelButton:@"" okButton:@"确定" complete:nil];
                    [aler showAlertWithController:self];
                }
            }];
        }
    }];
 
// 相册
    [_selectHeadImgView photoBtnClick:^(UIButton *sender){// 照片
        
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
            
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                
                if (status == PHAuthorizationStatusAuthorized) {
                    
                } else {
                    
                }
                UIImagePickerController * imagePickerVC = [[UIImagePickerController alloc]init];
                imagePickerVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                [[UINavigationBar appearance] setBarTintColor: [UToColor whiteColor]];
                [[UINavigationBar appearance] setTintColor:[UToColor blackColor]];
                [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UToColor blackColor],NSFontAttributeName:[UToFont defaultAdaptationFontWithSize:16.0]}];
                imagePickerVC.allowsEditing = YES;
                imagePickerVC.modalPresentationStyle = UIModalPresentationCurrentContext;
                imagePickerVC.delegate = self;
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [self presentViewController:imagePickerVC animated:YES completion:NULL];
                });
            }];
        }
    }];

2.根据状态来判断:(即用户已经做过允许与不允许的操作之后,再根据这个用户的反馈状态来判断展示)

11.相机和相册介绍

控制器了解篇章中的 UIImagePickController部分:http://www.jianshu.com/p/6ce0a8cdc02a

开启相机或相册的代码如下所示:

// 创建一个图像选择视图控制器
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
// 检查相机是否可用
if ([UIImagePickerController 
        isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    // 相机可用就使用相机
    ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else {
    // 相机不可用就使用相册
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
// 允许编辑照片
ipc.allowsEditing = YES;
// 绑定委托
ipc.delegate = self;
[self presentViewController:ipc animated:YES completion:nil];

UIImagePickerControllerDelegate的两个回调方法:

// 选中照片执行的回调方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    // info参数是一个字典,可以取出原始照片或编辑后的照片
}
// 取消选择照片的回调方法
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

}

说明:在开启相机时可以通过设置UIImagePickerController对象的mediaTypes属性来支持摄像操作,摄像完成后需要调用UISaveVideoAtPathToSavedPhotosAlbum函数将保存在临时文件夹下的视频文件保存到相册中,当然在此之前最好用UIVideoAtPathIsCompatibleWithSavedPhotosAlbum函数判断能否保存,在此之后可以通过NSFileManager对象的removeItemAtPath:error:方法将临时文件删除

Demo代码如下:

注意在plist文件中添加相应属性(否则会奔溃):NSMicrophoneUsageDescription、NSCameraUsageDescription、NSPhotoLibraryUsageDescription

效果:

补充拓展

12.Xcode里面xx.xcassets图标1x、2x、3x什么时候调用

Xcode里面xx.xcassets(xx是文件名称,一般自带叫Assets,可以进行更改)文件中的图标1x、2x、3x是系统自动调用,一般小手机调用1x和2x,大手机调用3x,比如:iPhone4以下机型图标会调用1x、6调用2x、6p和x系列调用3x。

补充:

1.通常尽量将图片资源放入 Images.xcassets 中,包括 pod 库的图片。 Images.xcassets 中的图片加载后会有缓存,提升加载速度,并且在最终打包时会自动进行压缩(Compress PNG Files),再根据最终运行设备进行 1x、2x、3x 分发。

2.对于内部 Pod 库中的资源文件,我们可以在 Pod 库里面的 Resources 目录下新建 Asset Catalog 文件,命名为 Images.xcassets,移入所有图片文件,接着手动修改该 SDK 的 podspec 文件指定使用该 Images.xcassets。

RTImageAssets - Xcode 插件:https://github.com/rickytan/RTImageAssets
RTImageAssets 是 Xcode 插件,用来生成 @3x 的图片资源对应的 @2x 和 @1x 版本,只要拖拽高清图到 @3x 的位置上,然后按 Ctrl+Shift+A 即可自动生成两张低清的补全空位,还可以从 @2x 的图生成 @3x 版本,如果你对图片质量要求不高的话。

.xcassets文件夹中图标1x、2x、3x
1x、2x、3x说明
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容