百思不得姐之图片处理(保存与下载)

2023-05-16

一 功能图

这里写图片描述

二 讲解思路

1 回顾上一篇内容

2 创建加载图片类(同时创建xib)

3 点击图片查看大图

4 点击查看大图(查看长图)

5 model出展示图片的控制器

6 保存图片

7 封装根据网络状态展示不同的图片

三 回顾上一篇内容

1 上一篇内容讲到对整个cell的分析,通过创建一个类(XIB)来管理cell的顶部和尾部总共九个控件.然后创建三个不同的类(xib),各自负责自己的中间部分,然后根据服务器返回的帖子类型,拼接上对应的cell,展示在用户眼前.

四 处理图片

1 处理原因: 由于从服务器中返回的图片的类型有两种:小图和长图,相对于其他部分,图片的处理相对来说比较麻烦.所以这里我先将展示图片的功能处理下.

2 创建加载图片类

这里写图片描述

3 处理图片的xib

这里写图片描述

—-> 3.1 注意一 : 占位文字”百思不得姐”字样的放置位置,放在UIImageView的下面,有利于在图片还没有从服务器中加载的时候,能显示”百思不得姐”字样,给用户比较好的体验(由于美工没有提供占位视图,只提供了一段文字,注意设置文字的样式为:下图)

这里写图片描述

—-> 3.2 注意二 : 注意”点击查看大图”按钮中的图片和文字中间的距离.我们是通过让图片向左移动5厘米并且让文字想右移动5厘米来达到中间的间隙,并且能让图片和文字总体处于中间位置.(设置地方)
—> 图一 :

这里写图片描述

—> 图二 :

这里写图片描述

4 图片类中需要用到的属性(通过拖线的方式拿到xib中需要的属性)

/**
 *  背景图片
 */
@property (weak, nonatomic) IBOutlet UIImageView *pictureBackImageView;
/**
 *  点击查看大图
 */
@property (weak, nonatomic) IBOutlet UIButton *seeBigPictureImageView;
/**
 *  动图
 */
@property (weak, nonatomic) IBOutlet UIImageView *gifImageView;

5 定义模型属性(用于重写模型属性的set方法)

/**
 *  导入模型
 */
@property (nonatomic, strong) XFJItem *topicesPicture;

6 模型的set方法

—-> 6.1 开启上下文(如果图片为长图)
—-> 6.2 绘图(如果图片为长图)
—-> 6.3 关闭上下文 (如果图片为长图)

总体代码:

#pragma mark - 模型属性的set方法
- (void)setTopicesPicture:(XFJItem *)topicesPicture
{
    _topicesPicture = topicesPicture;

    [self.pictureBackImageView XFJ_originalImageURL:topicesPicture.image1 thumbnailImageURL:topicesPicture.image0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

        //判断如果图片下载失败就返回
        if (image == nil) return ;
        //如果不是长图就返回
        if (!topicesPicture.isBigPicture) return;

        //长图来到下面
        CGFloat pictureW = topicesPicture.middleFrame.size.width;
        CGFloat pictureH = topicesPicture.middleFrame.size.height;
        //开启上下文
        UIGraphicsBeginImageContext(CGSizeMake(pictureW, pictureH));
        /*
          上下文的宽度             上下文的高度
         ------------    =     ---------------
         服务器返回图片的宽度    服务器返回图片的高度
         */
        //绘图
        [image drawInRect:CGRectMake(0, 0, pictureW, pictureW * topicesPicture.height / topicesPicture.width)];

        //获得图片
        self.pictureBackImageView.image = UIGraphicsGetImageFromCurrentImageContext();

        //图形上下文
        UIGraphicsEndImageContext();

    }];

    //如果是短图就隐藏点击查看大图按钮
    self.seeBigPictureImageView.hidden = !topicesPicture.isBigPicture;

    //如果不是动图就隐藏动图图标
    self.gifImageView.hidden = !topicesPicture.is_gif;


}

五 处理点击图片和查看大图业务逻辑

1 点击查看大图(通过拖线的方式我们进行对按钮的监听)

- (IBAction)seeBigPictureClick
{
    [self seeBigPicture];
}

2 调用的方法

#pragma mark - 实现轻按事件
- (void)seeBigPicture
{
    //创建控制器
    XFJSeeBigPicture *seePicture = [[XFJSeeBigPicture alloc] init];
    //如果不写这一句的话,会出现NaN的情况
    seePicture.topicesItem = self.topicesPicture;
    //model出该控制器
    [self.window.rootViewController presentViewController:seePicture animated:YES completion:nil];
}

3 由于当用户不管点击图片还是点击查看大图都会使得图片上展示出来,所以,我们给图片添加一个点按手势,其中点按要实现的方法恰好是查看大图的方法.

#pragma mark - 加载xib的时候回来到这个方法
- (void)awakeFromNib
{
    //允许图片接收事件
    self.pictureBackImageView.userInteractionEnabled = YES;
    //创建请按手势
    UITapGestureRecognizer *gest = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(seeBigPicture)];
    //给图片添加手势
    [self.pictureBackImageView addGestureRecognizer:gest];
}

六 展示图片的控制器(处理)

1 通过点击图片或者查看图片的按钮,可以看得出控制器是直接model出来的.

2 通过整体的图片在该控制器中的展示,我们不难看出,当图片为长图的时候用户需要往上滑动才能查看下面的图片,所以在dodel出来的控制器中层次结构为: UIScrollView–>UIImageView–>返回和保存按钮.

3 展示的xib效果图

这里写图片描述

4 需要用到的属性

/**
 *  保存按钮
 */
@property (weak, nonatomic) IBOutlet UIButton *saveButton;

@property (nonatomic, weak) UIImageView *imageView;

5 通过直接拖线的方式,处理返回按钮(将model出来的控制器dissmiss)

- (IBAction)backClick
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

6 添加UIScrollView

#pragma mark - 添加scrollerView
- (void)setUpContentView
{
    //创建UIScrollView
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    //设置尺寸
    scrollView.frame = CGRectMake(0, 0, XFJ_screenW, XFJ_screenH);
    //添加手势
    [scrollView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backClick)]];
    //设置颜色
    scrollView.backgroundColor = [UIColor blackColor];
    //添加插入到view中
    [self.view insertSubview:scrollView atIndex:0];
    //调用方法
    [self setUpcontentImageView:scrollView];
}
—-> 6.1 注意 :创建的UIScrollView一定要选择插入到model出来的控制器中,否则会出错.不能直接添加.

7 添加UIScrollView上的UIImageView

—-> 7.1 计算图片的高度
—-> 7.2 给图片添加一个缩放功能

总体的代码:

#pragma mark - 在contentView中添加UIImageView
- (void)setUpcontentImageView:(UIScrollView *)scrollView
{
    UIImageView *imageView = [[UIImageView alloc] init];
    //添加图片
    [imageView sd_setImageWithURL:[NSURL URLWithString:self.topicesItem.image1] placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
       //如果下载的图片为空
        if (image == nil) return ;
        self.saveButton.enabled = YES;
    }];
    //设置尺寸
    imageView.XFJ_X = 0;
    imageView.XFJ_Width = scrollView.XFJ_Width;
    [scrollView addSubview:imageView];
    //赋值
    self.imageView = imageView;
    //图片的高度
    imageView.XFJ_Height = imageView.XFJ_Width * self.topicesItem.height / self.topicesItem.width;
    //判断
    if (imageView.XFJ_Height >= XFJ_screenH) {
        imageView.XFJ_Y = 0;
        scrollView.contentSize = CGSizeMake(0, imageView.XFJ_Height);
    }else{
        imageView.XFJ_centerY = scrollView.XFJ_Height * 0.5;
    }

    CGFloat maxScale = self.topicesItem.width / self.imageView.XFJ_Width;
    //判断
    if (maxScale >= 1.0) {
        scrollView.maximumZoomScale = maxScale;
        scrollView.delegate = self;
    }
}

8 代理方法处理缩放图片

#pragma mark - 代理方法
//return a view that will be scaled. if delegate returns nil, nothing happens
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}

9 保存图片

—-> 9.1 点击保存按钮,保存图片
- (IBAction)savePicture
{
    UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image: didFinishSavingWithError: contextInfo:), nil);
}
—-> 9.2 提示用户是否保存成功
#pragma mark - 是否保存成功
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        [SVProgressHUD showErrorWithStatus:@"保存失败"];
    }else{
        [SVProgressHUD showSuccessWithStatus:@"保存成功"];
    }
}
—-> 9.3 注意 :UIImageWriteToSavedPhotosAlbum对该方法,苹果官方文档中有说明,@selector中调用的方法,必须是(下面)方法,否则就会报错.
//  - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;

七 建立联系

1 怎么样将各部分负责的UIView插入到自定义的cell中呢?

—-> 解答:通过下面的判断(self.topicesPicture.topicesPicture = topices;)主要作用
//通过贴模型中定义的属性帖子的类型
    switch (self.topices.type) {
        case XFJTopicTypeWord://段子
            //将声音;图片;视频图片都隐藏
            self.topicesPicture.hidden = YES;
            self.topicesVideo.hidden = YES;
            self.topicesVoice.hidden = YES;
            break;
        case XFJTopicTypePicture://图片
            //图片出现;声音;视频隐藏
            self.topicesVideo.hidden = YES;
            self.topicesVoice.hidden = YES;
            self.topicesPicture.topicesPicture = topices;
            self.topicesPicture.hidden = NO;
            break;
        case XFJTopicTypeVideo://视频
            //视频出现;声音和图片隐藏
            self.topicesPicture.hidden = YES;
            self.topicesVoice.hidden = YES;
            self.topicesVideo.topicesVideo = topices;
            self.topicesVideo.hidden = NO;
            break;
        case XFJTopicTypeVoice://声音
            //声音出现;图片和视频隐藏
            self.topicesPicture.hidden =YES;
            self.topicesVoice.topicesVoice = topices;
            self.topicesVoice.hidden = NO;
            self.topicesVideo.hidden = YES;
            break;
        default:
            break;
    }

2 通过(self.topicesPicture.topicesPicture = topices;)需要加载对应的xib

#pragma mark - 图片xib懒加载
- (XFJTopicesPictureView *)topicesPicture
{
    if (_topicesPicture == nil) {
        //创建xib
        XFJTopicesPictureView *picture = [XFJTopicesPictureView XFJ_middleXib];
        //添加到tableView中的contentView中
        [self.contentView addSubview:picture];
        //赋值
        _topicesPicture = picture;
    }
    return _topicesPicture;
}

3 调用下面的方法来加载对应的xib(self:谁调用就代表加载谁的xib)

#pragma mark - 实现快速创建xib的方法
+ (instancetype)XFJ_middleXib
{
    return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil].firstObject;
}

八 根据用户网络状态来下载不同规格的图片大小(封装)

1 思路:见下面伪代码

/*
    if (缓存中有原图) {
        self.imageView.image = 原图;
    } else {
        if (Wifi环境) {
            下载显示原图
        } else if (手机自带网络) {
            if (用户设置3G\4G环境下仍然下载原图) {
                下载显示原图
            } else {
                下载显示小图
            }
        } else {
            if (缓存中有小图) {
                self.imageView.image = 小图;
            } else {
                self.imageView.image = 占位图片;
            }
        }
    }*/

2 封装

—-> 2.1 .h文件
/**
 *  设置下载的图片类型(原图或缩略图)
 *
 *  @param originalImageURL  原图的URL
 *  @param thumbnailImageURL 缩略图的URL
 *  @param placeholderImage  占位视图
 *  @param completedBlock    设置完图片回调
 */
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL placeholderImage:(UIImage *)placeholderImage completed:(SDWebImageCompletionBlock)completedBlock;
/**
 *  设置下载的图片类型(原图或缩略图)
 *
 *  @param originalImageURL  原图的URL
 *  @param thumbnailImageURL 缩略图的URL
 */
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL;
/**
 *  设置下载的图片类型(原图或缩略图)
 *
 *  @param originalImageURL  原图的URL
 *  @param thumbnailImageURL 缩略图的URL
 *  @param placeholderImage  占位视图
 */
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL placeholderImage:(UIImage *)placeholderImage;
/**
 *  设置下载的图片类型(原图或缩略图)
 *
 *  @param originalImageURL  原图的URL
 *  @param thumbnailImageURL 缩略图的URL
 *  @param completedBlock    设置完图片回调
 */
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL completed:(SDWebImageCompletionBlock)completedBlock;
—-> 2.2 .m文件(需要导入的框架AFN)
#pragma mark - 不需要传占位视图和完成需要做的事
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL
{
    [self XFJ_originalImageURL:originalImageURL thumbnailImageURL:thumbnailImageURL placeholderImage:nil completed:nil];
}

#pragma mark - 需要传入占位视图
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL placeholderImage:(UIImage *)placeholderImage
{
    [self XFJ_originalImageURL:originalImageURL thumbnailImageURL:thumbnailImageURL placeholderImage:placeholderImage completed:nil];
}
#pragma mark - 需要设置完图片回调
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL completed:(SDWebImageCompletionBlock)completedBlock
{
    [self XFJ_originalImageURL:originalImageURL thumbnailImageURL:thumbnailImageURL placeholderImage:nil completed:completedBlock];
}
#pragma mark - 需要设置占位视图和完成回调
- (void)XFJ_originalImageURL:(NSString *)originalImageURL thumbnailImageURL:(NSString *)thumbnailImageURL placeholderImage:(UIImage *)placeholderImage completed:(SDWebImageCompletionBlock)completedBlock
{
    //先去缓存池中或者沙盒中寻找原图
    UIImage *originalImageView = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:originalImageURL];
    //判断如果有原图的话
    if (originalImageView) {
        //设置图片(有原图)
        [self sd_setImageWithURL:[NSURL URLWithString:originalImageURL] placeholderImage:placeholderImage completed:completedBlock];
    }else{
        //        内存或者沙盒中没有原图-->下载
        AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
        //判断网络情况
        if (manager.isReachableViaWiFi) {//如果是wifi
            [self sd_setImageWithURL:[NSURL URLWithString:originalImageURL] placeholderImage:placeholderImage completed:completedBlock];
        }else if(manager.isReachableViaWWAN){//如果是3G或4G的话就看用户选择
            //从沙盒中读取用户对是否下载原图的配置
            BOOL alwaysDownloadOriginalImage = [[NSUserDefaults standardUserDefaults] boolForKey:@"alwaysDownloadOriginalImage"];
            //如果是下载原图就直接下载
            if (alwaysDownloadOriginalImage) {
                [self sd_setImageWithURL:[NSURL URLWithString:originalImageURL] placeholderImage:placeholderImage completed:completedBlock];
            }else{
                //否则就下载小图
                [self sd_setImageWithURL:[NSURL URLWithString:thumbnailImageURL] placeholderImage:placeholderImage completed:completedBlock];
            }

        }else{
            //没有网络,读取缓存\沙盒中小图
            UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:thumbnailImageURL];
            //如果有缓存\沙盒中有小图
            if (thumbnailImage) {
                [self sd_setImageWithURL:[NSURL URLWithString:thumbnailImageURL] placeholderImage:placeholderImage completed:completedBlock];
            }else{
                [self sd_setImageWithURL:nil placeholderImage:placeholderImage completed:completedBlock];
            }
        }
    }
}

九 总结

1 该部分着重的讲解了对图片处理和对用户网络状态显示多大规格的图片进行处理.代码内部的业务逻辑相对来说比较难(需要考虑到多方面的因素),但总的来说还是可以解决的,可能里面有一些还没有想到,后期想到会完善的.

2 后面我会继续完善百思不得姐,希望带给大家更多的不一样的想法,最后大家如果觉得我写的博客还满意的话,麻烦大家多多建议,多多关注我的官方博客,谢谢!!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

百思不得姐之图片处理(保存与下载) 的相关文章

  • python将文件夹中图像生成file list

    按行排列 xff0c 图像路径 span class token function import span os span class token function import span argparse span class token
  • Markdown插入图片 详细例子(本地图片,网络图片,base64) Windows

    网上一番搜索 xff0c 领略到基本所有回答 xff0c 都是一样的 xff0c 简简单单的介绍 而且 xff0c TMD xff0c 插入图片答案的本地路径 xff0c 都是回答的是Linux或Mac OS系统的路径 xff0c 诸如 x
  • Pixhawk学习笔记(2)——问题汇总

    1 遥控器校准时 xff0c 拨动摇杆 xff0c 上位机通道数据不变化 解决方法 xff1a PPM编码器上有一个跳线需短接 xff0c 短接后才可通过编码器对遥控器接收机供电 供电前PPM编码器模块上蓝灯快闪 xff0c 供电后变为慢闪
  • 在FPGA中使用Verilog实现I2C通信

    按照I2C标准的官方时序 可以看出时序看起来很简单 xff0c 不过它严格的按照时序要求来传送数据 xff0c 马虎不得的 xff0c 特别是起始和停止的条件 xff0c 起始必须要时钟线SCL为高电平时数据线SDA拉低 xff1b 而停止
  • Pixhawk学习笔记(5)——PX4FLOW光流传感器调试过程记录

    先使用qgc地面站查看光流图像及数据 xff0c 能看到不错的图像和波形 烧写官网固件后 xff0c 接入pixhawk飞控 xff0c 使用apm固件 xff0c 勾选启用光流 xff0c 超声波选用pix iic xff0c 在miss
  • 数据结构—布隆过滤器

    布隆过滤器可以快速地告诉你 xff1a 某个值一定不存在 xff0c 以及某个值可能存在 布隆过滤器是基于位图和哈希函数 xff08 如 xff0c MurmurHash xff09 来实现了 此处假设有两个哈希函数 hash 1 hash
  • PX4/Pixhawk---快速成为开发者(Windows)

    1 快速成为开发者入门教程 xff08 翻译 xff09 官方 1 1 编译环境 xff08 1 xff09 安装 MSysGIT 安装完成后 xff0c 配置GIT 安装注意 安装过程中除了下面一步外 xff0c 其他的步骤都采用默认安装
  • Cdence版图设计手册

    Cadence版图设计 工作站常用命令 一 在terminal窗口键入的基本命令 xff1a 1 ls xff1a 列出目录下所有文件 2 clear xff1a 清除terminal窗口里的内容 3 pwd xff1a 显示目前工作的目录
  • Pixhawk开发手册

    一 常见问题 xff1a 1 遥控器校准时 xff0c 拨动摇杆 xff0c 上位机通道数据不变化 解决方法 xff1a PPM编码器上有一个跳线需短接 xff0c 短接后才可通过编码器对遥控器接收机供电 供电前PPM编码器模块上蓝灯快闪
  • 浅谈四轴PID调试心得

    以下内容转自阿莫论坛 xff0c 写得很详细 xff0c 是调试大四轴的 小四轴调试也可参照着调 PID调试心得 本人不是自动化出身 xff0c 也没有受过专业训练 xff0c 都是自己摸索 xff0c 在这里浅述一下自己的PID参数整定心
  • rctimer二轴云台及云台控制板调试(Simple bgc 8位破解板)

    前段时间在鬼王家抢了rctimer的二轴云台和控制板 xff0c 感觉做工很精良 这几天有空了就调试下 整个过程比较容易 xff0c 首先要准备好usbisp烧写器 xff0c 和一根阶梯形的micro usb线 先刷bootloader
  • APM和PIX飞控日志分析入门贴

    我们在飞行中 xff0c 经常会碰到各种各样的问题 xff0c 经常有模友很纳闷 xff0c 为什么我的飞机会这样那样的问题 xff0c 为什么我的飞机会炸机 xff0c 各种问题得不到答案是一件非常不爽的问题 xff0c 在APM和PIX
  • 微电子及集成电路设计常用问题总结(考研面试向)

    mos管的沟道长度调制效应 xff1f 源极导致势垒下降 xff1f 衬底电流体效应 xff1f 衬底偏执效应 xff1f 速度饱和效应 xff1f 举例典型的trade off xff1f mos amp bjt的工作曲线 xff1f 加
  • YOLO详解

    转载自 xff1a https zhuanlan zhihu com p 25236464 从五个方面解读CVPR2016 目标检测论文YOLO Unified Real Time Object Detection 创新 核心思想 效果 改
  • 使用微信监管你的TF训练

    以TensorFlow的example中 xff0c 利用CNN处理MNIST的程序为例 xff0c 我们做了下面一点点小小的修改 1 xff0c 首先导入了itchat和threading两个包分别用于微信和县线程 xff08 因为要有一
  • 你应该知道的9篇深度学习论文(CNNs 理解)

    当时看到英文的博客 xff0c 本想翻译给感兴趣的同学们看看 xff0c 没想到已经有人翻译 xff0c 于是进行了转载 xff0c 留给自己和更多的人学习 xff0c 本文仅供参考 英文博客 xff1a https adeshpande3
  • JS笔记(==和===的介绍)

    61 61 和 61 61 61 介绍 61 61 关系运算符 等于 用于比较两个操作数是否相等的 相等为true xff0c 否则为false 61 不等于 61 61 61 xff1a 绝对等于 用于比较两个操作数是否相等的 相等为tr
  • 全国大学生电子设计竞赛B题感悟-优象光流篇

    今年是2019年电赛国赛年 xff0c 这本是是一个很好的机会冲击国家奖的 xff0c 但是由于个人视野太窄 xff0c 眼光不够长远而错失良机 今年测评结束的时候我就已经预感到了结果 xff0c 记得比赛前去提交作品的时候 xff0c 大
  • 滑模控制以及系统动力学与控制论(1)

    维基百科里是这样定义系统 System 的 System from Latin syst ma in turn from Greek syst ma is a set of entities real or abstract compris
  • 安装docker

    首先信任 Docker 的 GPG 公钥 sudo apt key adv keyserver hkp p80 pool sks keyservers net 80 recv keys 58118E89F3A912897C070ADBF76

随机推荐