├── 屏幕快照 2018-11-29 下午9.05.12.png ├── README.md └── PicD ├── PicD.xcodeproj ├── xcuserdata │ ├── zssy.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── caoshixin.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ ├── zssy.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ └── caoshixin.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── project.pbxproj └── PicD ├── ViewController.h ├── AppDelegate.h ├── main.m ├── CSXImageCompressTool.h ├── Base.lproj ├── Main.storyboard └── LaunchScreen.storyboard ├── Info.plist ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── AppDelegate.m ├── ViewController.m └── CSXImageCompressTool.m /屏幕快照 2018-11-29 下午9.05.12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KirstenDunst/CSXImageCompress/HEAD/屏幕快照 2018-11-29 下午9.05.12.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSXImageCompress 2 | iOS图片压缩解决大图片压缩内存爆增,系统压缩不能满足限定的大小 3 | ![使用介绍](https://github.com/KirstenDunst/CSXImageCompress/blob/master/屏幕快照%202018-11-29%20下午9.05.12.png) 4 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/xcuserdata/zssy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/xcuserdata/caoshixin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/project.xcworkspace/xcuserdata/zssy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KirstenDunst/CSXImageCompress/HEAD/PicD/PicD.xcodeproj/project.xcworkspace/xcuserdata/zssy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/project.xcworkspace/xcuserdata/caoshixin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KirstenDunst/CSXImageCompress/HEAD/PicD/PicD.xcodeproj/project.xcworkspace/xcuserdata/caoshixin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PicD/PicD/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PicD 4 | // 5 | // Created by CSX on 2018/1/19. 6 | // Copyright © 2018年 宗盛商业. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PicD/PicD/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PicD 4 | // 5 | // Created by CSX on 2018/1/19. 6 | // Copyright © 2018年 宗盛商业. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /PicD/PicD/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PicD 4 | // 5 | // Created by CSX on 2018/1/19. 6 | // Copyright © 2018年 宗盛商业. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/xcuserdata/zssy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PicD.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/xcuserdata/caoshixin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PicD.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | PicD.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /PicD/PicD/CSXImageCompressTool.h: -------------------------------------------------------------------------------- 1 | /* __.--'\ \.__./ /'--.__ 2 | _.-' '.__.' '.__.' '-._ 3 | .' 曹世鑫 '. 4 | / \ 5 | | CSDN:https://me.csdn.net/BUG_delete | 6 | | GitHub:https://github.com/KirstenDunst | 7 | \ .---. .---. / 8 | '._ .' '.''. .''.' '. _.' 9 | '-./ \ / \.-' 10 | ''*/ 11 | // 12 | // CSXImageCompressTool.h 13 | // PicD 14 | // 15 | // Created by 曹世鑫 on 2019/5/22. 16 | // Copyright © 2019 宗盛商业. All rights reserved. 17 | // 18 | 19 | #import 20 | #import 21 | 22 | typedef void(^ImageBlock)(NSData *imageData); 23 | 24 | NS_ASSUME_NONNULL_BEGIN 25 | 26 | @interface CSXImageCompressTool : NSObject 27 | 28 | 29 | /** 30 | 内存处理,循环压缩处理,图片处理过程中内存不会爆增 31 | 32 | @param image 原始图片 33 | @param fImageKBytes 限制最终的文件大小 34 | @param block 处理之后的数据返回,data类型 35 | */ 36 | + (void)compressedImageFiles:(UIImage *)image imageKB:(CGFloat)fImageKBytes imageBlock:(void(^)(NSData *imageData))block; 37 | 38 | 39 | 40 | /** 41 | 图片压缩(针对内存爆表出现的压缩失真分层问题的使用工具) 42 | 43 | @param orignalImage 原始图片 44 | @param fImageKBytes 最终限制 45 | @param block 处理之后的数据返回,data类型 46 | */ 47 | + (void)resetSizeOfImage:(UIImage *)orignalImage imageKB:(CGFloat)fImageKBytes imageBlock:(ImageBlock)block; 48 | 49 | 50 | 51 | @end 52 | 53 | NS_ASSUME_NONNULL_END 54 | -------------------------------------------------------------------------------- /PicD/PicD/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /PicD/PicD/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | NSPhotoLibraryUsageDescription 45 | 使用相册 46 | 47 | 48 | -------------------------------------------------------------------------------- /PicD/PicD/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PicD/PicD/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /PicD/PicD/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PicD 4 | // 5 | // Created by CSX on 2018/1/19. 6 | // Copyright © 2018年 宗盛商业. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /PicD/PicD/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PicD 4 | // 5 | // Created by CSX on 2018/1/19. 6 | // Copyright © 2018年 宗盛商业. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "CSXImageCompressTool.h" 11 | 12 | @interface ViewController () 13 | { 14 | UIImageView * imageView; 15 | } 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | self.view.backgroundColor = [UIColor cyanColor]; 23 | // Do any additional setup after loading the view, typically from a nib. 24 | imageView = [[UIImageView alloc]init]; 25 | imageView.backgroundColor = [UIColor redColor]; 26 | imageView.frame = CGRectMake(100, 200, 200, 200); 27 | [self.view addSubview:imageView]; 28 | UIButton *myCreateButton = [UIButton buttonWithType:UIButtonTypeCustom]; 29 | myCreateButton.frame = CGRectMake(100, 100, 100, 100); 30 | [myCreateButton setBackgroundColor:[UIColor grayColor]]; 31 | [myCreateButton setTitle:@"Choose" forState:UIControlStateNormal]; 32 | [myCreateButton addTarget:self action:@selector(buttonChoose:) forControlEvents:UIControlEventTouchUpInside]; 33 | [self.view addSubview:myCreateButton]; 34 | 35 | 36 | } 37 | 38 | - (void)buttonChoose:(UIButton *)sender{ 39 | NSFileManager *fileManager = [NSFileManager defaultManager]; 40 | 41 | NSArray * paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 42 | NSString *documentsDirectory = [paths objectAtIndex:0];//去处需要的路径 43 | /// NSDocumentDirectory, NSUserDomainMask, YES) 44 | NSString *strPath = [documentsDirectory stringByAppendingPathComponent:@"text"]; 45 | NSLog(@">>>>>>>>>>>>>>>>>%@",strPath); 46 | // NSString *strPath = [[NSBundle mainBundle]pathForResource:@"123" ofType:@"png"]; 47 | NSDirectoryEnumerator * myDirectoryEnumerator; 48 | 49 | myDirectoryEnumerator= [fileManager enumeratorAtPath:strPath]; 50 | 51 | 52 | while (strPath = [myDirectoryEnumerator nextObject]) { 53 | 54 | for (NSString * namePath in strPath.pathComponents) { 55 | if ([namePath isEqualToString:@".DS_Store"]) { 56 | continue; 57 | } 58 | NSLog(@"-----AAA-----%@", namePath ); 59 | static UIImage *image; 60 | image = [[UIImage alloc]initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",[documentsDirectory stringByAppendingPathComponent:@"text"],namePath]]; 61 | // [CSXImageCompressTool resetSizeOfImage:image imageKB:500 imageBlock:^(NSData *imageData) { 62 | [CSXImageCompressTool compressedImageFiles:image imageKB:500 imageBlock:^(NSData *imageData) { 63 | NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"new/%@", namePath]];// 保存文件的名称 64 | 65 | BOOL result = [imageData writeToFile: filePath atomically:YES]; // 保存成功会返回YES 66 | 67 | NSLog(@"文件%@保存成功?%d",namePath,result); 68 | }]; 69 | } 70 | } 71 | } 72 | 73 | - (void)didReceiveMemoryWarning { 74 | [super didReceiveMemoryWarning]; 75 | // Dispose of any resources that can be recreated. 76 | } 77 | 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /PicD/PicD/CSXImageCompressTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSXImageCompressTool.m 3 | // PicD 4 | // 5 | // Created by 曹世鑫 on 2019/5/22. 6 | // Copyright © 2019 宗盛商业. All rights reserved. 7 | // 8 | 9 | #import "CSXImageCompressTool.h" 10 | 11 | @implementation CSXImageCompressTool 12 | 13 | 14 | + (void)compressedImageFiles:(UIImage *)image imageKB:(CGFloat)fImageKBytes imageBlock:(void(^)(NSData *imageData))block { 15 | //二分法压缩图片 16 | CGFloat compression = 1; 17 | NSData *imageData = UIImageJPEGRepresentation(image, compression); 18 | NSUInteger fImageBytes = fImageKBytes * 1000;//需要压缩的字节Byte,iOS系统内部的进制1000 19 | if (imageData.length <= fImageBytes){ 20 | block(imageData); 21 | return; 22 | } 23 | CGFloat max = 1; 24 | CGFloat min = 0; 25 | //指数二分处理,s首先计算最小值 26 | compression = pow(2, -6); 27 | imageData = UIImageJPEGRepresentation(image, compression); 28 | if (imageData.length < fImageBytes) { 29 | //二分最大10次,区间范围精度最大可达0.00097657;最大6次,精度可达0.015625 30 | for (int i = 0; i < 6; ++i) { 31 | compression = (max + min) / 2; 32 | imageData = UIImageJPEGRepresentation(image, compression); 33 | //容错区间范围0.9~1.0 34 | if (imageData.length < fImageBytes * 0.9) { 35 | min = compression; 36 | } else if (imageData.length > fImageBytes) { 37 | max = compression; 38 | } else { 39 | break; 40 | } 41 | } 42 | 43 | block(imageData); 44 | return; 45 | } 46 | 47 | // 对于图片太大上面的压缩比即使很小压缩出来的图片也是很大,不满足使用。 48 | //然后再一步绘制压缩处理 49 | UIImage *resultImage = [UIImage imageWithData:imageData]; 50 | while (imageData.length > fImageBytes) { 51 | @autoreleasepool { 52 | CGFloat ratio = (CGFloat)fImageBytes / imageData.length; 53 | //使用NSUInteger不然由于精度问题,某些图片会有白边 54 | NSLog(@">>>>>>>>>>>>>>>>>%f>>>>>>>>>>>>%f>>>>>>>>>>>%f",resultImage.size.width,sqrtf(ratio),resultImage.size.height); 55 | CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)), 56 | (NSUInteger)(resultImage.size.height * sqrtf(ratio))); 57 | resultImage = [self createImageForData:imageData maxPixelSize:MAX(size.width, size.height)]; 58 | imageData = UIImageJPEGRepresentation(resultImage, compression); 59 | } 60 | } 61 | 62 | // 整理后的图片尽量不要用UIImageJPEGRepresentation方法转换,后面参数1.0并不表示的是原质量转换。 63 | block(imageData); 64 | } 65 | 66 | + (void)resetSizeOfImage:(UIImage *)orignalImage imageKB:(CGFloat)fImageKBytes imageBlock:(ImageBlock)block { 67 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 68 | //二分法压缩图片 69 | CGFloat compression = 1; 70 | __block NSData *imageData = UIImageJPEGRepresentation(orignalImage, compression); 71 | NSUInteger fImageBytes = fImageKBytes*1000; 72 | if (imageData.length <= fImageBytes){ 73 | block(imageData); 74 | return; 75 | } 76 | //这里二分之前重绘一下,就能解决掉内存的不足导致的问题。 77 | UIImage *newImage = [self createImageForData:imageData maxPixelSize:MAX((NSUInteger)orignalImage.size.width, (NSUInteger)orignalImage.size.height)]; 78 | [self halfFuntionImage:newImage maxSizeByte:fImageBytes back:^(NSData *halfImageData, CGFloat compress) { 79 | //再一步绘制压缩处理 80 | UIImage *resultImage = [UIImage imageWithData:halfImageData]; 81 | imageData = halfImageData; 82 | while (imageData.length > fImageBytes) { 83 | CGFloat ratio = (CGFloat)fImageBytes / imageData.length; 84 | //使用NSUInteger不然由于精度问题,某些图片会有白边 85 | CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)), 86 | (NSUInteger)(resultImage.size.height * sqrtf(ratio))); 87 | resultImage = [self createImageForData:imageData maxPixelSize:MAX(size.width, size.height)]; 88 | imageData = UIImageJPEGRepresentation(resultImage, compress); 89 | } 90 | // 整理后的图片尽量不要用UIImageJPEGRepresentation方法转换,后面参数1.0并不表示的是原质量转换。 91 | block(imageData); 92 | }]; 93 | }); 94 | } 95 | 96 | 97 | #pragma mark --------------二分法 98 | + (void)halfFuntionImage:(UIImage *)image maxSizeByte:(NSInteger)maxSizeByte back:(void(^)(NSData *halfImageData, CGFloat compress))block { 99 | //二分法压缩图片 100 | CGFloat compression = 1; 101 | NSData *imageData = UIImageJPEGRepresentation(image, compression); 102 | CGFloat max = 1; 103 | CGFloat min = 0; 104 | //指数二分处理,s首先计算最小值 105 | compression = pow(2, -6); 106 | imageData = UIImageJPEGRepresentation(image, compression); 107 | if (imageData.length < maxSizeByte) { 108 | //二分最大10次,区间范围精度最大可达0.00097657;最大6次,精度可达0.015625 109 | for (int i = 0; i < 6; i++) { 110 | compression = (max + min) / 2; 111 | imageData = UIImageJPEGRepresentation(image, compression); 112 | //容错区间范围0.9~1.0 113 | if (imageData.length < maxSizeByte * 0.9) { 114 | min = compression; 115 | } else if (imageData.length > maxSizeByte) { 116 | max = compression; 117 | } else { 118 | break; 119 | } 120 | } 121 | } 122 | if (block) { 123 | block(imageData, compression); 124 | } 125 | } 126 | 127 | + (UIImage *)createImageForData:(NSData *)data maxPixelSize:(NSUInteger)size { 128 | CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 129 | CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, NULL); 130 | CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef) @{ 131 | (NSString *)kCGImageSourceCreateThumbnailFromImageAlways : @YES, 132 | (NSString *)kCGImageSourceThumbnailMaxPixelSize : @(size), 133 | (NSString *)kCGImageSourceCreateThumbnailWithTransform : @YES, 134 | }); 135 | CFRelease(source); 136 | CFRelease(provider); 137 | if (!imageRef) { 138 | return nil; 139 | } 140 | UIImage *toReturn = [UIImage imageWithCGImage:imageRef]; 141 | CFRelease(imageRef); 142 | return toReturn; 143 | } 144 | 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /PicD/PicD.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1FBAA31D20118EAD001C0CAA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBAA31C20118EAD001C0CAA /* AppDelegate.m */; }; 11 | 1FBAA32020118EAD001C0CAA /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBAA31F20118EAD001C0CAA /* ViewController.m */; }; 12 | 1FBAA32320118EAD001C0CAA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1FBAA32120118EAD001C0CAA /* Main.storyboard */; }; 13 | 1FBAA32520118EAD001C0CAA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1FBAA32420118EAD001C0CAA /* Assets.xcassets */; }; 14 | 1FBAA32820118EAD001C0CAA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1FBAA32620118EAD001C0CAA /* LaunchScreen.storyboard */; }; 15 | 1FBAA32B20118EAD001C0CAA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBAA32A20118EAD001C0CAA /* main.m */; }; 16 | DBF0EAD62295493E00A588CB /* CSXImageCompressTool.m in Sources */ = {isa = PBXBuildFile; fileRef = DBF0EAD52295493E00A588CB /* CSXImageCompressTool.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 1FBAA31820118EAD001C0CAA /* PicD.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PicD.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 1FBAA31B20118EAD001C0CAA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 22 | 1FBAA31C20118EAD001C0CAA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 23 | 1FBAA31E20118EAD001C0CAA /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 24 | 1FBAA31F20118EAD001C0CAA /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 25 | 1FBAA32220118EAD001C0CAA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 1FBAA32420118EAD001C0CAA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | 1FBAA32720118EAD001C0CAA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 28 | 1FBAA32920118EAD001C0CAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | 1FBAA32A20118EAD001C0CAA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | DBF0EAD42295493E00A588CB /* CSXImageCompressTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSXImageCompressTool.h; sourceTree = ""; }; 31 | DBF0EAD52295493E00A588CB /* CSXImageCompressTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSXImageCompressTool.m; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | 1FBAA31520118EAD001C0CAA /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | 1FBAA30F20118EAC001C0CAA = { 46 | isa = PBXGroup; 47 | children = ( 48 | 1FBAA31A20118EAD001C0CAA /* PicD */, 49 | 1FBAA31920118EAD001C0CAA /* Products */, 50 | ); 51 | sourceTree = ""; 52 | }; 53 | 1FBAA31920118EAD001C0CAA /* Products */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 1FBAA31820118EAD001C0CAA /* PicD.app */, 57 | ); 58 | name = Products; 59 | sourceTree = ""; 60 | }; 61 | 1FBAA31A20118EAD001C0CAA /* PicD */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | 1FBAA31B20118EAD001C0CAA /* AppDelegate.h */, 65 | 1FBAA31C20118EAD001C0CAA /* AppDelegate.m */, 66 | 1FBAA31E20118EAD001C0CAA /* ViewController.h */, 67 | 1FBAA31F20118EAD001C0CAA /* ViewController.m */, 68 | DBF0EAD42295493E00A588CB /* CSXImageCompressTool.h */, 69 | DBF0EAD52295493E00A588CB /* CSXImageCompressTool.m */, 70 | 1FBAA32120118EAD001C0CAA /* Main.storyboard */, 71 | 1FBAA32420118EAD001C0CAA /* Assets.xcassets */, 72 | 1FBAA32620118EAD001C0CAA /* LaunchScreen.storyboard */, 73 | 1FBAA32920118EAD001C0CAA /* Info.plist */, 74 | 1FBAA32A20118EAD001C0CAA /* main.m */, 75 | ); 76 | path = PicD; 77 | sourceTree = ""; 78 | }; 79 | /* End PBXGroup section */ 80 | 81 | /* Begin PBXNativeTarget section */ 82 | 1FBAA31720118EAD001C0CAA /* PicD */ = { 83 | isa = PBXNativeTarget; 84 | buildConfigurationList = 1FBAA32E20118EAD001C0CAA /* Build configuration list for PBXNativeTarget "PicD" */; 85 | buildPhases = ( 86 | 1FBAA31420118EAD001C0CAA /* Sources */, 87 | 1FBAA31520118EAD001C0CAA /* Frameworks */, 88 | 1FBAA31620118EAD001C0CAA /* Resources */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = PicD; 95 | productName = PicD; 96 | productReference = 1FBAA31820118EAD001C0CAA /* PicD.app */; 97 | productType = "com.apple.product-type.application"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | 1FBAA31020118EAD001C0CAA /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | LastUpgradeCheck = 0920; 106 | ORGANIZATIONNAME = "宗盛商业"; 107 | TargetAttributes = { 108 | 1FBAA31720118EAD001C0CAA = { 109 | CreatedOnToolsVersion = 9.2; 110 | ProvisioningStyle = Automatic; 111 | }; 112 | }; 113 | }; 114 | buildConfigurationList = 1FBAA31320118EAD001C0CAA /* Build configuration list for PBXProject "PicD" */; 115 | compatibilityVersion = "Xcode 8.0"; 116 | developmentRegion = en; 117 | hasScannedForEncodings = 0; 118 | knownRegions = ( 119 | en, 120 | Base, 121 | ); 122 | mainGroup = 1FBAA30F20118EAC001C0CAA; 123 | productRefGroup = 1FBAA31920118EAD001C0CAA /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | 1FBAA31720118EAD001C0CAA /* PicD */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXResourcesBuildPhase section */ 133 | 1FBAA31620118EAD001C0CAA /* Resources */ = { 134 | isa = PBXResourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 1FBAA32820118EAD001C0CAA /* LaunchScreen.storyboard in Resources */, 138 | 1FBAA32520118EAD001C0CAA /* Assets.xcassets in Resources */, 139 | 1FBAA32320118EAD001C0CAA /* Main.storyboard in Resources */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXResourcesBuildPhase section */ 144 | 145 | /* Begin PBXSourcesBuildPhase section */ 146 | 1FBAA31420118EAD001C0CAA /* Sources */ = { 147 | isa = PBXSourcesBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | DBF0EAD62295493E00A588CB /* CSXImageCompressTool.m in Sources */, 151 | 1FBAA32020118EAD001C0CAA /* ViewController.m in Sources */, 152 | 1FBAA32B20118EAD001C0CAA /* main.m in Sources */, 153 | 1FBAA31D20118EAD001C0CAA /* AppDelegate.m in Sources */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXSourcesBuildPhase section */ 158 | 159 | /* Begin PBXVariantGroup section */ 160 | 1FBAA32120118EAD001C0CAA /* Main.storyboard */ = { 161 | isa = PBXVariantGroup; 162 | children = ( 163 | 1FBAA32220118EAD001C0CAA /* Base */, 164 | ); 165 | name = Main.storyboard; 166 | sourceTree = ""; 167 | }; 168 | 1FBAA32620118EAD001C0CAA /* LaunchScreen.storyboard */ = { 169 | isa = PBXVariantGroup; 170 | children = ( 171 | 1FBAA32720118EAD001C0CAA /* Base */, 172 | ); 173 | name = LaunchScreen.storyboard; 174 | sourceTree = ""; 175 | }; 176 | /* End PBXVariantGroup section */ 177 | 178 | /* Begin XCBuildConfiguration section */ 179 | 1FBAA32C20118EAD001C0CAA /* Debug */ = { 180 | isa = XCBuildConfiguration; 181 | buildSettings = { 182 | ALWAYS_SEARCH_USER_PATHS = NO; 183 | CLANG_ANALYZER_NONNULL = YES; 184 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 185 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 186 | CLANG_CXX_LIBRARY = "libc++"; 187 | CLANG_ENABLE_MODULES = YES; 188 | CLANG_ENABLE_OBJC_ARC = YES; 189 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 190 | CLANG_WARN_BOOL_CONVERSION = YES; 191 | CLANG_WARN_COMMA = YES; 192 | CLANG_WARN_CONSTANT_CONVERSION = YES; 193 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 194 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 195 | CLANG_WARN_EMPTY_BODY = YES; 196 | CLANG_WARN_ENUM_CONVERSION = YES; 197 | CLANG_WARN_INFINITE_RECURSION = YES; 198 | CLANG_WARN_INT_CONVERSION = YES; 199 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 200 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 201 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 202 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 203 | CLANG_WARN_STRICT_PROTOTYPES = YES; 204 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 205 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 206 | CLANG_WARN_UNREACHABLE_CODE = YES; 207 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 208 | CODE_SIGN_IDENTITY = "iPhone Developer"; 209 | COPY_PHASE_STRIP = NO; 210 | DEBUG_INFORMATION_FORMAT = dwarf; 211 | ENABLE_STRICT_OBJC_MSGSEND = YES; 212 | ENABLE_TESTABILITY = YES; 213 | GCC_C_LANGUAGE_STANDARD = gnu11; 214 | GCC_DYNAMIC_NO_PIC = NO; 215 | GCC_NO_COMMON_BLOCKS = YES; 216 | GCC_OPTIMIZATION_LEVEL = 0; 217 | GCC_PREPROCESSOR_DEFINITIONS = ( 218 | "DEBUG=1", 219 | "$(inherited)", 220 | ); 221 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 222 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 223 | GCC_WARN_UNDECLARED_SELECTOR = YES; 224 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 225 | GCC_WARN_UNUSED_FUNCTION = YES; 226 | GCC_WARN_UNUSED_VARIABLE = YES; 227 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 228 | MTL_ENABLE_DEBUG_INFO = YES; 229 | ONLY_ACTIVE_ARCH = YES; 230 | SDKROOT = iphoneos; 231 | }; 232 | name = Debug; 233 | }; 234 | 1FBAA32D20118EAD001C0CAA /* Release */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 240 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 241 | CLANG_CXX_LIBRARY = "libc++"; 242 | CLANG_ENABLE_MODULES = YES; 243 | CLANG_ENABLE_OBJC_ARC = YES; 244 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 245 | CLANG_WARN_BOOL_CONVERSION = YES; 246 | CLANG_WARN_COMMA = YES; 247 | CLANG_WARN_CONSTANT_CONVERSION = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 250 | CLANG_WARN_EMPTY_BODY = YES; 251 | CLANG_WARN_ENUM_CONVERSION = YES; 252 | CLANG_WARN_INFINITE_RECURSION = YES; 253 | CLANG_WARN_INT_CONVERSION = YES; 254 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 261 | CLANG_WARN_UNREACHABLE_CODE = YES; 262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 263 | CODE_SIGN_IDENTITY = "iPhone Developer"; 264 | COPY_PHASE_STRIP = NO; 265 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 266 | ENABLE_NS_ASSERTIONS = NO; 267 | ENABLE_STRICT_OBJC_MSGSEND = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu11; 269 | GCC_NO_COMMON_BLOCKS = YES; 270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 272 | GCC_WARN_UNDECLARED_SELECTOR = YES; 273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 274 | GCC_WARN_UNUSED_FUNCTION = YES; 275 | GCC_WARN_UNUSED_VARIABLE = YES; 276 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 277 | MTL_ENABLE_DEBUG_INFO = NO; 278 | SDKROOT = iphoneos; 279 | VALIDATE_PRODUCT = YES; 280 | }; 281 | name = Release; 282 | }; 283 | 1FBAA32F20118EAD001C0CAA /* Debug */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 287 | CODE_SIGN_STYLE = Automatic; 288 | DEVELOPMENT_TEAM = J34X25TCYP; 289 | INFOPLIST_FILE = PicD/Info.plist; 290 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 291 | PRODUCT_BUNDLE_IDENTIFIER = com.zssy.AM.text; 292 | PRODUCT_NAME = "$(TARGET_NAME)"; 293 | TARGETED_DEVICE_FAMILY = "1,2"; 294 | }; 295 | name = Debug; 296 | }; 297 | 1FBAA33020118EAD001C0CAA /* Release */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 301 | CODE_SIGN_STYLE = Automatic; 302 | DEVELOPMENT_TEAM = J34X25TCYP; 303 | INFOPLIST_FILE = PicD/Info.plist; 304 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 305 | PRODUCT_BUNDLE_IDENTIFIER = com.zssy.AM.text; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | TARGETED_DEVICE_FAMILY = "1,2"; 308 | }; 309 | name = Release; 310 | }; 311 | /* End XCBuildConfiguration section */ 312 | 313 | /* Begin XCConfigurationList section */ 314 | 1FBAA31320118EAD001C0CAA /* Build configuration list for PBXProject "PicD" */ = { 315 | isa = XCConfigurationList; 316 | buildConfigurations = ( 317 | 1FBAA32C20118EAD001C0CAA /* Debug */, 318 | 1FBAA32D20118EAD001C0CAA /* Release */, 319 | ); 320 | defaultConfigurationIsVisible = 0; 321 | defaultConfigurationName = Release; 322 | }; 323 | 1FBAA32E20118EAD001C0CAA /* Build configuration list for PBXNativeTarget "PicD" */ = { 324 | isa = XCConfigurationList; 325 | buildConfigurations = ( 326 | 1FBAA32F20118EAD001C0CAA /* Debug */, 327 | 1FBAA33020118EAD001C0CAA /* Release */, 328 | ); 329 | defaultConfigurationIsVisible = 0; 330 | defaultConfigurationName = Release; 331 | }; 332 | /* End XCConfigurationList section */ 333 | }; 334 | rootObject = 1FBAA31020118EAD001C0CAA /* Project object */; 335 | } 336 | --------------------------------------------------------------------------------