iOS 图片压缩策略

前一段部门为了统一规范, 要一个通用的图片压缩的逻辑, 于是就参考了微信等APP的压缩逻辑,封装了一个图片压缩的逻辑类,拿出来给大家分享一下~

图片压缩的逻辑: 首先进行图片的尺寸压缩 再进行图片的质量压缩
一:图片尺寸压缩 主要分为以下几种情况 一般参照像素为1280
a.图片宽高均≤1280px时,图片尺寸保持不变;
b.宽或高均>1280px时 ——图片宽高比≤2,则将图片宽或者高取大的等比压缩至1280px; ——但是图片宽高比>2时,则宽或者高取小的等比压缩至1280px;
c.宽高一个>1280px,另一个<1280px,–图片宽高比>2时,则宽高尺寸不变;–但是图片宽高比≤2时,则将图片宽或者高取大的等比压缩至1280px.
二:图片质量压缩
一般图片质量都压缩在90%就可以了

测试结果: 一般压缩出来的data再150 - 300kb之间 这个结果相对于大多数的APP已经够了 下面是代码实现

#import <Foundation/Foundation.h>

// 我们项目中的图片压缩参照为1280px
#define KitTargetPx 1280

/**
 *  图片压缩的逻辑类
 */
@interface KitImageSeviceManager : NSObject

/**
 *  图片压缩的单例实现方法
 *
 *  @return 返回一个图片压缩的类
 */
+ (instancetype)shareManager;

/**
 *  将图片压缩的data返回
 *
 *  @param sourceImage 传进来要压缩的照片
 *  @param targetPx    压缩图片时参照的像素px
 *
 *  @return 返回图片压缩后的data
 */
- (NSData *)imageCompressForSize:(UIImage *)sourceImage 
                        targetPx:(NSInteger)targetPx;

@end
#import "KitImageSeviceManager.h"

@implementation KitImageSeviceManager


#pragma mark -- 返回图片压缩类的单例
+ (instancetype)shareManager {
    static KitImageSeviceManager *manager = nil;
    static dispatch_once_t oneToken;
    dispatch_once(&oneToken, ^{
        manager = [[KitImageSeviceManager alloc] init];
    });
    return manager;
}

/**
 图片压缩的逻辑:
   一:图片尺寸压缩 主要分为以下几种情况 一般参照像素为1280
     a.图片宽高均≤1280px时,图片尺寸保持不变;
     b.宽或高均>1280px时 ——图片宽高比≤2,则将图片宽或者高取大的等比压缩至1280px; ——但是图片宽高比>2时,则宽或者高取小的等比压缩至1280px;
     c.宽高一个>1280px,另一个<1280px,--图片宽高比>2时,则宽高尺寸不变;--但是图片宽高比≤2时,则将图片宽或者高取大的等比压缩至1280px.

   二:图片质量压缩
      一般图片质量都压缩在90%就可以了
 */

#pragma mark -- 图片压缩方法
- (NSData *)imageCompressForSize:(UIImage *)sourceImage targetPx:(NSInteger)targetPx {
    UIImage *newImage = nil;             // 尺寸压缩后的新图
    CGSize imageSize = sourceImage.size; // 源图片的size
    CGFloat width = imageSize.width;     // 源图片的宽
    CGFloat height = imageSize.height;   // 原图片的高
    BOOL drawImge = NO;     // 是否需要重绘图片 默认是NO
    CGFloat scaleFactor = 0.0;           // 压缩比例
    CGFloat scaledWidth = targetPx;      // 压缩时的宽度 默认是参照像素
    CGFloat scaledHeight = targetPx;     // 压缩是的高度 默认是参照像素

  // 先进行图片的尺寸的判断

  // a.图片宽高均≤参照像素时,图片尺寸保持不变
  if (width < targetPx && height < targetPx) {
       newImage = sourceImage;
  }  else if (width > targetPx && height > targetPx) {
  // b.宽或高均>1280px时
       drawImge = YES;
       CGFloat factor = width / height;
       if (factor <= 2) {
           // b.1图片宽高比≤2,则将图片宽或者高取大的等比压缩至1280px
           scaleFactor = width > height ? targetPx / width : targetPx / height;
        } else {
           // b.2图片宽高比>2时,则宽或者高取小的等比压缩至1280px
           scaleFactor = width > height ? targetPx / height : targetPx / width;
        }
  } else if (width > targetPx &&  height < targetPx ) {
  // c.宽高一个>1280px,另一个<1280px 宽大于1280
        if (width / height > 2) {
             newImage = sourceImage;
         } else {
             drawImge = YES;
             scaleFactor = targetPx / width;
         }
  } else if (width < targetPx &&  height > targetPx) {
  // c.宽高一个>1280px,另一个<1280px 高大于1280
         if (height / width > 2) {
              newImage = sourceImage;
          } else {
              drawImge = YES;
              scaleFactor = targetPx / height;
          }
  }

  // 如果图片需要重绘 就按照新的宽高压缩重绘图片
  if (drawImge == YES) {
      scaledWidth = width * scaleFactor;
      scaledHeight = height * scaleFactor;
      UIGraphicsBeginImageContext(CGSizeMake(scaledWidth, scaledHeight));
      // 绘制改变大小的图片
      [sourceImage drawInRect:CGRectMake(0, 0, scaledWidth,scaledHeight)];
      // 从当前context中创建一个改变大小后的图片
      newImage =UIGraphicsGetImageFromCurrentImageContext();
      // 使当前的context出堆栈
      UIGraphicsEndImageContext();
  }
  // 防止出错  可以删掉的
  if (newImage == nil) {
      newImage = sourceImage;
  }

  // 如果图片大小大于200kb 在进行质量上压缩
  NSData * scaledImageData = nil;
  if (UIImageJPEGRepresentation(newImage, 1) == nil) {
       scaledImageData = UIImagePNGRepresentation(newImage);
  }else{
       scaledImageData = UIImageJPEGRepresentation(newImage, 1);

       if (scaledImageData.length >= 1024 * 200) {
             scaledImageData =   UIImageJPEGRepresentation(newImage, 0.9);
       }
   } 

    return scaledImageData;
}


@end
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值