• iOS:图片相关(19-05-09更)


    1、图片显示相关

      1)、图片聊天背景拉伸不失真

      2)、捏合、双击、下拉缩放

      3)、Banner、相册

      4)、动画

    2、图片操作相关

      1)、获取、下载图片(分享、传图片用)

      2)、保存UIImage到本地

      3)、绘制、解压图片

        3-1)、用原尺寸绘制 

        3-2)、修改大小绘制,免得每次拿原始大图片缩放显示

      4)、压缩图片

    0、写在前面

      1)、图片,显示模式为缩放以充满全屏,需要注意,剪切超出View的部分,否则有时有问题。

    self.photoImgV.contentMode = UIViewContentModeScaleAspectFill;
    self.photoImgV.clipsToBounds = YES;
    

      2)、加载网络图片,更新 imageView 尺寸。因为涉及缩放,所以要按比例算高度。

    // 缩放,宽度为 SCREEN_WIDTH
    self.goodsDetailImgV.contentMode = UIViewContentModeScaleAspectFit;
    // 网图加载成功,按比例更新高度
    [self.goodsDetailImgV sd_setImageWithURL:[NSURL URLWithString:data[@"pic"]] placeholderImage:[UIImage imageNamed:@"default_image"] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        [self.goodsDetailImgV mas_updateConstraints:^(MASConstraintMaker *make) {
            make.height.mas_equalTo( (SCREEN_WIDTH/image.size.width) * image.size.height );
        }];
    }];
    

    1、图片显示相关

      1)、图片聊天背景拉伸不失真

        1-1)、方法1,比较老的

    UIImage *originalImage = [UIImage imageNamed:@"sub.png"];
    finalImage = [originalImage stretchableImageWithLeftCapWidth:originalImage.size.width/2 topCapHeight:0];
    

        1-2)、方法2,比较新的

    UIImage *originalImg = [UIImage imageNamed:@"sub"];
    
    CGFloat protectH = originalImg.size.height/2;
    CGFloat protectW = originalImg.size.width/2;
        
    UIEdgeInsets protectEdg = UIEdgeInsetsMake(protectH, protectW, protectH, protectW);
        
    UIImage *finalImg = [originalImg resizableImageWithCapInsets:protectEdg resizingMode:UIImageResizingModeStretch];
    

       后续补充:

        根据情况,设置 Insets ,不一定都要取中点。意义为,分别保护 {0, 0, 0, 0} 到 {top, left, bottom, right} 距离的图片。

      2)、捏合、双击、下拉缩放

        2-1)、捏合缩放

          1)、设置最大、最小缩放比例

    scrollview.maximumZoomScale = 2.0;
    scrollview.minimumZoomScale = 0.5;
    

          2)、设置代理

    scrollview.delegate = self;
    

          3)、添加上ImageView  

    imageView.tag = 101;
    [scrollview addSubview:imageView];
    

          4)、给代理要缩放的View(不一定要添加上才可以缩放,可以缩放不在本 scrollview 的View,效果就很奇葩了)

    - (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        UIImageView *imageView = [scrollView viewWithTag:101];
        return imageView;
    }
    

        2-2)、双击缩放  

          0)、需要注意的地方:

            0-1)、scrollView要设最大/小缩放比例!

            0-2)、因为图片层在最上面,且默认不可交互,所以,图片的View记得userInteractionEnabled = YES 。

            0-3)、ScrollView需要缩小尺寸,重设contentsize的时候,如删除某照片,要先清掉超出的的控件、数据。否则拉到底,弹性的时候,还能看到之前的。

          1)、scrollView才可以缩放,所以要把ImageView加在scrollView,给scrollView添加手势识别。

    UITapGestureRecognizer *imageTwoTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(twoTapAction:)];
    imageTwoTap.numberOfTapsRequired = 2;
    [scrollView addGestureRecognizer: imageTwoTap];
    

          2)、第一次点哪放大哪,第二次恢复原来大小

    #define SCALE_WIDTH  60    		//要放大的局部宽度大小
    #define SCALE_HEIGHT 60    		//要放大的局部高度大小
    
    -(void)twoTapAction:(UITapGestureRecognizer *)tap
    {
        UIScrollView *scrollView = (UIScrollView *)tap.view;
        if (scrollView.zoomScale != 1.0)
        {
            [scrollView setZoomScale:1.0 animated:YES];
        }
        else
        {
            CGPoint tapPoint = [tap locationInView:scrollView];
            [scrollView zoomToRect:CGRectMake(tapPoint.x-SCALE_WIDTH/2, tapPoint.y-SCALE_HEIGHT/2, SCALE_WIDTH, SCALE_HEIGHT) animated:YES];
        }
    }
    

           3)、需要给代理放大、缩小的ImageView

    - (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        if ([[scrollView viewWithTag:1000] isMemberOfClass:[UIImageView class]])
        {
            return [scrollView viewWithTag:1000];
        }
        return nil;
    }
    

         2-3)、下拉缩放

        //根据手势位置缩放、移动view,判断所在位置需要返回,待补充

      3)、Banner、相册

          1)、图片移动、

      4)、动画

        参照《iOS:动画》 -> "0、写在前面" -> "4)、UIImageView 有自带的动画属性、方法:"

    2、图片操作相关

      1)、获取、下载图片(分享、传图片用)

        1-1)、从 SDWebImage 缓存取

    SDWebImageManager *manager = [SDWebImageManager sharedManager];
    
    [manager diskImageExistsForURL:url completion:^(BOOL isInCache) {
        UIImage *img = nil;
        if (isInCache) {
            // 有,直接取
            img = [[manager imageCache] imageFromDiskCacheForKey:url.absoluteString];
        }else{
            // 无,下载
        }
    }];
    

        1-2)、下载

          1)、同步加载图片(仅做了解)

    NSData *imgData = [NSData dataWithContentsOfURL:url];
    UIImage *image = [[UIImage alloc] initWithData:imgData];
    

          2)、异步加载图片(仅做了解)

    - (void)loadImageFromWebWithURL:(NSURL*)url
    {
       dispatch_queue_t queue = dispatch_queue_create("test", NULL);
        dispatch_async(queue, ^{
            // 获取数据
            NSData *data = [NSData dataWithContentsOfURL:url];
            // 主线程
            dispatch_sync(dispatch_get_main_queue(), ^{
                UIImage *image = [UIImage imageWithData:data];
            });
        });
    }
    

          3)、SDWebImageDownloader 直接下载

    SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
    
    [downloader downloadImageWithURL:url
                             options:SDWebImageDownloaderHighPriority
                            progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
                                // 进度
                            } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
                                // 完成
                            }];
    

      2)、保存UIImage到本地

        2-1)、弄成data

    // UIImage 转换成 data、图片 保存
    UIImage *img = [UIImage imageNamed:@"test"];
        
    //png格式
    NSData *imageData = UIImagePNGRepresentation(img);
    
    //JEPG格式
    NSData *imageData = UIImageJPEGRepresentation(img,1.0);
    

        2-2)、写入

          1)、直接写入

    NSString *cashesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) firstObject];
    
    // png,data写入
    [imageData writeToFile:[cashesPath stringByAppendingPathComponent:@"image1.png"] atomically:YES];
    
    // jpg,data写入
    [imageData writeToFile:[cashesPath stringByAppendingPathComponent:@"image1.jpg"] atomically:YES];
    

          2)、用fileManage写入

    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    NSString *cashesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) firstObject];
    
    // 将图片保存为PNG格式
    [fileManager createFileAtPath:[cashesPath stringByAppendingString:@"/image2.png"] contents:imageData attributes:nil];
    
    // 将图片保存为JPEG格式
    [fileManager createFileAtPath:[cashesPath stringByAppendingString:@"/image2.jpg"] contents:imageData attributes:nil];
    

      补充:测试后,无论 data 还是 fileManage 写入,同格式大小一致。如 image1.png 和 image2.png 。image1.jpg 和image2.jpg。

      3)、绘制、解压图片

        3-1)、用原尺寸绘制

    UIGraphicsBeginImageContextWithOptions(image.size, YES, 0);
    [image drawAtPoint:CGPointZero];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

      补充:意义不大,文件太大。目的是为了及时解压、刷新UI、且不改变原图片?

        3-2)、修改大小绘制,免得每次拿原始大图片缩放显示

    UIGraphicsBeginImageContextWithOptions(size, YES, 0);
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

      补充:1、注意size的设置。

            1)、如果是按原图片的size比例,最大一边为1280,绘制没问题。

            2)、如果是按显示控件 UIImageView 等固定size绘制,可能会出现,图片变形以填充满size。

         2、UIGraphicsBeginImageContextWithOptions(size, YES, 0) 会比 UIGraphicsBeginImageContext(size) 效果好。

      4)、压缩图片

    // 最大边长
    #define kMaxLength                  1280.0
    // JPG格式压缩质量 0 - 1
    #define kJPGCompressionQuality      0.5
    
    #pragma mark - 根据宽高压缩图片
    - (UIImage*)imageWithImage:(UIImage*)originalImage scaleToSize:(CGSize)finalSize{
        UIGraphicsBeginImageContextWithOptions(finalSize, YES, 0);
        [originalImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)];
        UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return finalImage;
    }
    
    #pragma mark - 压缩一张图片 自定义最大宽高
    - (UIImage*)imageWithImage:(UIImage*)originalImage maxLength:(CGFloat)maxLength{
        CGFloat originalImageW = originalImage.size.width;
        CGFloat originalImageH = originalImage.size.height;
        //宽高比
    //    CGFloat aspectRatio = originalImageW / originalImageH;
        CGFloat finalImageW = originalImageW;
        CGFloat finalImageH = originalImageH;
    
        if(originalImageW > maxLength || originalImageH > maxLength){
            //超过设置的最大宽度 判断那个边最长
            if(originalImageW > originalImageH){
                //宽度大于高度
                finalImageW = maxLength;
                finalImageH = (maxLength * originalImageH)/originalImageW;
            }else{
                finalImageH = maxLength;
                finalImageW = (maxLength * originalImageW)/originalImageH;
            }
        }
        
        UIImage *finalImage = [self imageWithImage:originalImage scaleToSize:CGSizeMake(finalImageW, finalImageH)];
        NSData *finalImageData = nil;
        if (UIImagePNGRepresentation(finalImage) == nil) {
            finalImageData = UIImageJPEGRepresentation(finalImage, kJPGCompressionQuality);
        }else{
            finalImageData = UIImagePNGRepresentation(finalImage);
        }
        
        return [UIImage imageWithData:finalImageData];
    }
    
    #pragma mark - 压缩多张图片 自定义最大宽高
    - (NSArray<UIImage*>*)imageArrayWithImageArray:(NSArray<UIImage*>*)originalImageArray maxLength:(CGFloat)maxLength{
        NSMutableArray *finalImageArray = [NSMutableArray array];
        for (int i = 0; i<originalImageArray.count; i++) {
            UIImage *finalImage = [self imageWithImage:originalImageArray[i] maxLength:maxLength];
            [finalImageArray addObject:finalImage];
        }
        return finalImageArray;
    }
    
    #pragma mark - 压缩一张图片 最大宽或高1280
    - (UIImage*)imageWithImage:(UIImage*)image{
        return [self imageWithImage:image maxLength:kMaxLength];
    }
    
    #pragma mark - 压缩多张图片 最大宽或高1280
    - (NSArray<UIImage*>*)imageArrayWithImageArray:(NSArray<UIImage*>*)imageArr{
        return [self imageArrayWithImageArray:imageArr maxLength:kMaxLength];
    }
    

      补充:   

        1、在方法 - (UIImage*)imageWithImage:(UIImage*)originalImage maxLength:(CGFloat)maxLength

          不管尺寸是否低于设定的最大宽高,都会被绘制,可选择优化。

        2、修改自《iOS-微信分享多张图片(UIActivityViewController多图分享和多图分享失败)》  -- ZFJ_张福杰   CSDN

  • 相关阅读:
    无线网破解软件|一键式破解无线网|BT17软件包下载[笔记本+软件就行]
    Boost环境配置及遇到的问题解决方案
    HDU 4255 A Famous Grid
    uva 10306
    系统学习Linux的11点建议
    linux shell except tcl login ssh Automatic interaction
    常用网址记录
    am335x Qt SocketCAN Demo hacking
    a demo for how to use QThread
    OK335xS CAN device register and deiver match hacking
  • 原文地址:https://www.cnblogs.com/leonlincq/p/8330418.html
Copyright © 2020-2023  润新知