好習慣之先放demo,
https://github.com/ssj1314/SSJImage-Scan
好用的話大家可以給點個star。哈哈哈
首先撮弧,我們必須明確圖片的壓縮其實是兩個概念:
1.“壓” 是指文件體積變小贿衍,但是像素數(shù)不變贸辈,長寬尺寸不變奢啥,那么質(zhì)量可能下降桩盲。
2.“縮” 是指文件的尺寸變小赌结,也就是像素數(shù)減少,而長寬尺寸變小伤靠,文件體積同樣會減小宴合。
對這個不明白的可以先看看標哥的文章。 PS:標哥博客關閉了....
http://www.reibang.com/p/f014d0dfeac3
感謝開源精神!!!這是 參考文獻 可以去這里看看
https://cnbin.github.io/blog/2016/03/23/iostu-pian-ya-suo-chu-li/ 和 http://www.reibang.com/p/9b47fc25f526#
寫了個小demo 這是簡單的功能界面
1. 先介紹一下怎么用 -------開始
1.點擊選擇圖片進入相冊,選擇圖片蚤霞。(iOS10以后記得添加key昧绣,不然會掛的)
2.點擊壓縮圖片拖刃,圖片壓縮。有沒有效果呢均函?廢話
壓縮前2M ----- 壓縮后1M
3.可以保存到相冊。
什么時候用到壓縮圖片呢?
1.向服務器上傳圖片翻擒,如果太大,速度會很慢巩趁。
2.等等等等议慰,其他情況。炉菲。拍霜。
回到上文的圖片的 "壓" 和 "縮" 以下參考簡書文章 --- iOS 圖片壓縮邏輯
http://www.reibang.com/p/7533ed993130
圖片壓縮的邏輯: 首先進行圖片的尺寸壓縮 再進行圖片的質(zhì)量壓縮
一 : 圖片尺寸壓縮 主要分為以下幾種情況 一般參照像素為 1280
a. 圖片寬高均≤1280px 時,圖片尺寸保持不變;
b. 寬或高均>1280px 時 ——圖片寬高比≤2吠裆,則將圖片寬或者高取大的等比壓縮至 1280px; ——但是圖片寬高比>2 時试疙,則寬或者高取小的等比壓縮至 1280px;
c. 寬高一個>1280px祝旷,另一個<1280px怀跛,-- 圖片寬高比>2 時忠蝗,則寬高尺寸不變;-- 但是圖片寬高比≤2 時, 則將圖片寬或者高取大的等比壓縮至 1280px.
二 : 圖片質(zhì)量壓縮
一般圖片質(zhì)量都壓縮在 90% 就可以了
測試結果:有時候原圖片太大阁最,有時壓縮需要重復幾次, 一般壓縮出來的 data 再 150 - 300kb 之間 這個結果相對于大多數(shù)的 APP 已經(jīng)夠了配阵。
代碼和圖
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface SSJKitImageManager : NSObject
// 我們項目中的圖片壓縮參照為1280px
#define KitTargetPx 1280
/**
* 圖片壓縮的邏輯類
*/
/**
* 圖片壓縮的單例實現(xiàn)方法
*
* @return 返回一個圖片壓縮的類
*/
+ (instancetype)shareManager;
/**
* 將圖片壓縮的data返回
*
* @param sourceImage 傳進來要壓縮的照片
* @param targetPx 壓縮圖片時參照的像素px
*
* @return 返回圖片壓縮后的data
*/
- (NSData *)imageCompressForSize:(UIImage *)sourceImage targetPx:(NSInteger)targetPx;
@end
.m文件
#import "SSJKitImageManager.h"
@implementation SSJKitImageManager
#pragma mark -- 返回圖片壓縮類的單例
+ (instancetype)shareManager
{
static SSJKitImageManager *manager = nil;
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
manager = [[SSJKitImageManager alloc] init];
});
return manager;
}
/**
圖片壓縮的邏輯:
一:圖片尺寸壓縮 主要分為以下幾種情況 一般參照像素為1280
a.圖片寬高均≤1280px時,圖片尺寸保持不變;
b.寬或高均>1280px時 ——圖片寬高比≤2,則將圖片寬或者高取大的等比壓縮至1280px; ——但是圖片寬高比>2時拂铡,則寬或者高取小的等比壓縮至1280px;
c.寬高一個>1280px感帅,另一個<1280px,--圖片寬高比>2時实苞,則寬高尺寸不變;--但是圖片寬高比≤2時,則將圖片寬或者高取大的等比壓縮至1280px.
二:圖片質(zhì)量壓縮
一般圖片質(zhì)量都壓縮在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中創(chuàng)建一個改變大小后的圖片
newImage =UIGraphicsGetImageFromCurrentImageContext();
// 使當前的context出堆棧
UIGraphicsEndImageContext();
}
// 防止出錯 可以刪掉的
if (newImage == nil) {
newImage = sourceImage;
}
// 如果圖片大小大于200kb 在進行質(zhì)量上壓縮
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;
}
壓縮圖片按鈕執(zhí)行方法
圖有時候會掛還是上代碼吧-----
#//壓縮圖片
- (void)ssjKitImage{
NSData * imageData = UIImageJPEGRepresentation(self.SelImage.image,1);
NSUInteger length = [imageData length]/1000;
NSLog(@"self.SelImage.imageOriginal = %ld", length);
SSJKitImageManager * SSJKit = [SSJKitImageManager shareManager];
//壓縮圖片調(diào)用
NSData * imageDatas = [SSJKit imageCompressForSize:self.SelImage.image targetPx:1000];
// NSData * imageDatas = UIImageJPEGRepresentation(self.SelImage.image,1);
NSUInteger lengths = [imageDatas length]/1000;
NSLog(@"self.SelImage.imageKit = %ld", lengths);
}
#// 打開相冊
- (IBAction)SelectImage:(UIButton *)sender {
//調(diào)用系統(tǒng)相冊的類
UIImagePickerController * pickController = [[UIImagePickerController alloc] init];
//設置是否選取的照片可編輯
pickController.allowsEditing = YES;
//設置相冊的呈現(xiàn)樣式
pickController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;//圖片分組列表樣式
//照片的選取樣式還有以下兩種
//UIImagePickerControllerSourceTypePhotoLibrary,直接全部呈現(xiàn)系統(tǒng)相冊
//UIImagePickerControllerSourceTypeCamera//調(diào)取攝像頭
//選擇完成圖片或者點擊取消按鈕都是通過代理來操作我們所需要的邏輯過程
pickController.delegate = self;
//使用模態(tài)呈現(xiàn)相冊
self.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
[self.navigationController presentViewController:pickController animated:YES completion:^{
}];
// if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
// NSLog(@"相機類型可用YES");
//
// }else{
// NSLog(@"相機類型不可用NO");
// }
}
#//保存壓縮過的圖片 這是最簡單的保存 勿噴0.0
- (IBAction)SaveImage:(UIButton *)sender {
UIImageWriteToSavedPhotosAlbum(self.SelImage.image, self, nil, nil);
}