iOS 图片压缩逻辑

作者: 清晨十分的阳光 | 来源:发表于2016-10-09 18:38 被阅读625次

由于目前项目需要, 于是就参考了网上晒出来的微信等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;
    }
    // b.宽或高均>1280px时
    else if (width > targetPx && height > targetPx) {
        drawImge = YES;
        CGFloat factor = width / height;
        if (factor <= 2) {
        // b.1图片宽高比≤2,则将图片宽或者高取大的等比压缩至1280px
            if (width > height) {
                scaleFactor  = targetPx / width;
            } else {
                scaleFactor = targetPx / height;
            }
        } else {
        // b.2图片宽高比>2时,则宽或者高取小的等比压缩至1280px
            if (width > height) {
                scaleFactor  = targetPx / height;
            } else {
                scaleFactor = targetPx / width;
            }
        }
    }
   // c.宽高一个>1280px,另一个<1280px 宽大于1280
   else if (width > targetPx &&  height < targetPx ) {
        if (width / height > 2) {
            newImage = sourceImage;
        } else {
             drawImge = YES;
            scaleFactor = targetPx / width;
        }
    }
   // c.宽高一个>1280px,另一个<1280px 高大于1280
   else if (width < targetPx &&  height > targetPx) {
        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

相关文章

  • iOS 图片压缩逻辑

    由于目前项目需要, 于是就参考了网上晒出来的微信等APP的压缩逻辑,封装了一个图片压缩的逻辑类,拿出来给大家分享一...

  • iOS 图片压缩方法

    iOS 图片压缩方法 更多图片处理方法见图片组件 BBWebImage iOS 图片压缩方法 两种图片压缩方法 两...

  • iOS 图片压缩、滤镜、剪切、渲染等解析

    iOS 图片压缩、滤镜、剪切、渲染等解析 iOS 图片压缩、滤镜、剪切、渲染等解析

  • iOS 图片压缩限制大小最优解

    iOS 图片压缩限制大小最优解 图片的两种压缩方法 1.1 压缩图片质量 1.2 压缩图片尺寸 压缩图片使图片文件...

  • iOS-图片解压缩相关

    SDWebimage中对图片的解压缩 谈谈 iOS 中图片的解压缩 iOS 开发:绘制像素到屏幕 探讨iOS 中图...

  • 探讨iOS 中图片的解压缩到渲染过程

    探讨iOS 中图片的解压缩到渲染过程 探讨iOS 中图片的解压缩到渲染过程

  • APP启动页

    安卓图片资源目录 iOS图片资源目录 图片压缩网址

  • imageView的处理

    图片的处理参见谈谈 iOS 中图片的解压缩

  • vue 图片压缩

    vue 图片压缩 上传图片大于100* 1024 的用canvas 来压缩来解决 然后IOS拍照上传会有图片旋转的...

  • vue 图片压缩

    vue 图片压缩 上传图片大于100* 1024 的用canvas来压缩来解决 然后IOS拍照上传会有图片旋转的问...

网友评论

  • 9e72b5a52cd1:请问一下if(UIImageJPEGRepresentation(newImage, 1) == nil)这个最外层的分支是什么作用呢?谢谢!
  • 西西西瓜sama:为什么要用单例呢,只是图片压缩,没必要吧?
    西西西瓜sama:@清晨十分的阳光 哈哈 感谢 感谢
    清晨十分的阳光:@西西西瓜sama 看自己项目情况吧 我们项目中对图片处理比较多:joy::joy:
  • 可可_running:怎么能保证压缩过的图片就一定小于200kb呢
    karthus:@清晨十分的阳光 使用循环压缩效率非常低 一个4,5M的图片压缩到100K以下需要几秒的时间
    清晨十分的阳光:@可可_running 这个是不能保证的 我做的只不过是大于200kb就会质量压缩 我测试的时候选了一些大图长图 压缩出来的大小一般在150-300kb 如果你一定要压缩到200kb 把最后的质量压缩循环就好了 200的时候再结束循环 希望是你想要的答案 谢谢

本文标题:iOS 图片压缩逻辑

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