跳至主要內容

iOS - Image compression algorithm

Oragekk...大约 2 分钟iOSiOS工具集算法

由于最近公司在做图片相册选择上传的功能,对于图片的压缩算法这里我借鉴了 ochina 的 ios 端 App。其中有涉及到图片压缩的算法,这里贴出来留待后用;

GACompressionPicHandle.h

    	#import <Foundation/Foundation.h>
    	#import <UIKit/UIKit.h>
    	#import <CoreGraphics/CoreGraphics.h>

    	@class GACompressionPicHandle;
    	@protocol GACompressionPicHandleDelegate <NSObject>
    	- (void)CompressionPicHandle:(GACompressionPicHandle* )handle
      			CompressionFailureInfo:(NSString* )info;
      	@end

      	#define CompressionMax_W 1224
      	#define CompressionMax_Size 300 * 1024
      	/** OSChina 后台限制上传图片的大小*/
      	#define stand_size 1024 * 800
      	#define min_compressionRatio 0.3

      	@interface GACompressionPicHandle : NSObject

      	+ (instancetype)shareCompressionPicHandle;

    @property(nonatomic,weak)id<GACompressionPicHandleDelegate> delegate;

    	/** 分辨率越小反而越占用时间 建议分辨率高的图片使用*/
    - (NSData* )scaleToSize:(CGSize)size
                   image:(UIImage* )picture;

         /** 受到宽高比例问题 越接近正方形所用的时间越小 */
    - (NSData *)imageByScalingAndCroppingForSize:(	CGSize)targetSize image:(UIImage *)image;
    	@end

GACompressionPicHandle.m

#import "GACompressionPicHandle.h"

@implementation GACompressionPicHandle

static GACompressioinPicHandle*_shareCompressionPicHandle;

+ (instancetype)shareCompressionPicHandle{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _shareCompressionPicHandle = 					[[GACompressionPicHandle alloc]init];
    });
    return _shareCompressionPicHandle;
}


- (NSData* )scaleToSize:(CGSize)sizeimage:(UIImage* )picture {
    CGFloat width = CGImageGetWidth(picture.CGImage);
    CGFloat height = CGImageGetHeight(picture.CGImage);
    float verticalRadio = size.height * 1.0 / height;
    float horizontalRadio = size.width * 1.0 / width;
    float radio = 1;
    if(verticalRadio > 1 && horizontalRadio > 1) {
    radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio;
    }else{
    radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio;
    }
    width = width * radio;
    height = height * radio;

    int xPos = (size.width - width) / 2;
    int yPos = (size.height - height) / 2;

    UIGraphicsBeginImageContext(size);

    [picture drawInRect:CGRectMake(xPos, yPos, width, height)];

    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    NSData* scaledImageData = UIImageJPEGRepresentation(scaledImage, 1);

    CGFloat compressionRatio = 0.9f;
    NSData* tagerImageData = scaledImageData;
    NSLog(@"tagerImageData.length : %lu",(unsigned long)tagerImageData.length);
    while (tagerImageData.length > stand_size && compressionRatio > 0) {
        if (compressionRatio < min_compressionRatio) {
            if ([_delegate respondsToSelector:@selector(CompressionPicHandle:CompressionFailureInfo:)]) {
                [_delegate CompressionPicHandle:self CompressionFailureInfo:@"图片过大"];
            }
        }
        @autoreleasepool {
            NSData* newCompressionData = UIImageJPEGRepresentation(scaledImage, compressionRatio);
            tagerImageData = newCompressionData;
        }
        compressionRatio = compressionRatio - 0.12;
        NSLog(@"tagerImageData.length : %lu , compressionRatio : %lf",tagerImageData.length,compressionRatio);
    }
    NSLog(@"compressionRatio : %lf",compressionRatio);

    return tagerImageData;
}


- (NSData *)imageByScalingAndCroppingForSize:(CGSize)targetSize image:(UIImage *)image {
    UIImage *sourceImage = image;
    UIImage *newImage = nil;
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
    if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
    CGFloat widthFactor = targetWidth / width;
    CGFloat heightFactor = targetHeight / height;
    if (widthFactor > heightFactor){
    scaleFactor = widthFactor; // scale to fit height
    }else{
        scaleFactor = heightFactor; // scale to fit width
    }

    scaledWidth= width * scaleFactor;
    scaledHeight = height * scaleFactor;

    if (widthFactor > heightFactor) {
        thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
    } else if (widthFactor < heightFactor){
        thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    }
    }

    UIGraphicsBeginImageContext(targetSize); // this will crop
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width= scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    [sourceImage drawInRect:thumbnailRect];
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil)
    UIGraphicsEndImageContext();

    NSData* scaledImageData = UIImageJPEGRepresentation(newImage, 1);

    CGFloat compressionRatio = 0.9f;
    NSData* tagerImageData = scaledImageData;
    NSLog(@"tagerImageData.length : %lu",(unsigned long)tagerImageData.length);
    while (tagerImageData.length > stand_size && compressionRatio > 0) {
        if (compressionRatio < min_compressionRatio) {
            if ([_delegate respondsToSelector:@selector(CompressionPicHandle:CompressionFailureInfo:)]) {
                [_delegate CompressionPicHandle:self CompressionFailureInfo:@"图片过大"];
            }
        }
        @autoreleasepool {
            NSData* newCompressionData = UIImageJPEGRepresentation(newImage, compressionRatio);
            tagerImageData = newCompressionData;
        }
        compressionRatio = compressionRatio - 0.12;
        NSLog(@"tagerImageData.length : %lu , compressionRatio : %lf",tagerImageData.length,compressionRatio);
    }
    NSLog(@"compressionRatio : %lf",compressionRatio);

    return tagerImageData;

}
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3