美文网首页
开发笔记(图片相册相机)

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

作者: Kevin_wzx | 来源:发表于2023-03-14 18:00 被阅读0次

    目录

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

    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

    效果:

    补充拓展

    相关文章

      网友评论

          本文标题:开发笔记(图片相册相机)

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