├── Pod └── Classes │ ├── .gitkeep │ └── WXImageCompress.swift ├── configure ├── .travis.yml ├── WXImageCompress.podspec ├── LICENSE ├── README.md └── .gitignore /Pod/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | $current_dir = File.dirname(File.expand_path(__FILE__)) 4 | Dir[File.join($current_dir, "setup/*.rb")].each do |file| 5 | require_relative(file) 6 | end 7 | 8 | pod_name = ARGV.shift 9 | Pod::TemplateConfigurator.new(pod_name).run 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode10.2 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -workspace Example/${POD_NAME}.xcworkspace -scheme ${POD_NAME}-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /WXImageCompress.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'WXImageCompress' 3 | s.version = '0.1.3' 4 | s.swift_version = '5.1' 5 | s.summary = 'Image size quality compression, very close to WeChat picture compression strategy' 6 | s.homepage = 'https://github.com/hucool/WXImageCompress' 7 | s.license = { :type => 'MIT', :file => 'LICENSE' } 8 | s.author = { 'tiger' => 'tiger@socool@gmail.com' } 9 | s.source = { :git => 'https://github.com/hucool/WXImageCompress.git', :tag => s.version.to_s } 10 | s.ios.deployment_target = '8.0' 11 | s.source_files = 'Pod/Classes/**/*' 12 | s.frameworks = 'UIKit', 'Foundation' 13 | end 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 YangHu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Requirements 2 | * iOS 8.0+ | macOS 10.10+ | tvOS 9.0+ | watchOS 2.0+ 3 | * Xcode 8 4 | 5 | ## Integration 6 | CocoaPods (iOS 8+, OS X 10.9+) 7 | ```ruby 8 | pod 'WXImageCompress', '~> 0.1.1' 9 | ``` 10 | 11 | 12 | ## Usage 13 | ```swift 14 | import WXImageCompress 15 | ``` 16 | ```swift 17 | let image = UIImage(named: "imageName")! 18 | ``` 19 | ```swift 20 | let thumbImage = image.wxCompress() 21 | ``` 22 | 23 | 24 | ## Effect comparison 25 | | original | wechat | this | 26 | | -------- | ----- | ---- | 27 | | 1500 * 4000, 2.5MB | 800 * 2134, 325KB | 800 * 2134, 306KB | 28 | | 960 * 600, 210KB | 960 * 600, 147KB | 960 * 600, 147KB | 29 | | 800 * 1280, 595KB | 800 * 1280, 140KB | 800 * 1280, 142KB | 30 | | 1080 * 1920, 1.8MB | 720 * 1280, 139KB | 720 * 1280, 140KB | 31 | | 640 * 1136, 505KB | 640 * 1136, 68KB | 640 * 1136 69KB | 32 | | 4000 * 3000, 497KB | 1280 * 960, 140KB | 1280 * 960, 139KB | 33 | | 2560 * 1600, 232KB | 1280 * 800 112KB | 1280 * 800, 112KB | 34 | | 800 * 2138, 307KB | 800 * 2134, 649KB | 800 * 2138, 599KB | 35 | | 3351 * 1430, 386KB | 1874 * 800, 296KB | 1875 * 800, 286KB | 36 | | 3000 * 1300, 458KB | 1846 * 800 322KB | 1847 * 800, 307KB | 37 | | 8323 * 5793, 19.67MB | 1280 * 890, 428KB | 1280 * 891, 465KB | 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /Pod/Classes/WXImageCompress.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Luban.swift 3 | // XMImagePicker 4 | // 5 | // Created by tiger on 2017/2/16. 6 | // Copyright © 2017年 xinma. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Foundation 11 | 12 | public enum WechatCompressType { 13 | case session 14 | case timeline 15 | } 16 | 17 | public extension UIImage { 18 | 19 | /** 20 | wechat image compress 21 | 22 | - parameter type: session image boundary is 800, timeline is 1280 23 | 24 | - returns: thumb image 25 | */ 26 | func wxCompress(type: WechatCompressType = .timeline) -> UIImage { 27 | let size = self.wxImageSize(type: type) 28 | let reImage = resizedImage(size: size) 29 | let data = reImage.jpegData(compressionQuality: 0.5)! 30 | return UIImage.init(data: data)! 31 | } 32 | 33 | /** 34 | get wechat compress image size 35 | 36 | - parameter type: session / timeline 37 | 38 | - returns: size 39 | */ 40 | private func wxImageSize(type: WechatCompressType) -> CGSize { 41 | var width = self.size.width 42 | var height = self.size.height 43 | 44 | var boundary: CGFloat = 1280 45 | 46 | // width, height <= 1280, Size remains the same 47 | guard width > boundary || height > boundary else { 48 | return CGSize(width: width, height: height) 49 | } 50 | 51 | // aspect ratio 52 | let s = max(width, height) / min(width, height) 53 | if s <= 2 { 54 | // Set the larger value to the boundary, the smaller the value of the compression 55 | let x = max(width, height) / boundary 56 | if width > height { 57 | width = boundary 58 | height = height / x 59 | } else { 60 | height = boundary 61 | width = width / x 62 | } 63 | } else { 64 | // width, height > 1280 65 | if min(width, height) >= boundary { 66 | boundary = type == .session ? 800 : 1280 67 | // Set the smaller value to the boundary, and the larger value is compressed 68 | let x = min(width, height) / boundary 69 | if width < height { 70 | width = boundary 71 | height = height / x 72 | } else { 73 | height = boundary 74 | width = width / x 75 | } 76 | } 77 | } 78 | return CGSize(width: width, height: height) 79 | } 80 | 81 | /** 82 | Zoom the picture to the specified size 83 | 84 | - parameter newSize: image size 85 | 86 | - returns: new image 87 | */ 88 | private func resizedImage(size: CGSize) -> UIImage { 89 | let newRect = CGRect(x: 0, y: 0, width: size.width, height: size.height) 90 | var newImage: UIImage! 91 | UIGraphicsBeginImageContext(newRect.size) 92 | newImage = UIImage(cgImage: self.cgImage!, scale: 1, orientation: self.imageOrientation) 93 | newImage.draw(in: newRect) 94 | newImage = UIGraphicsGetImageFromCurrentImageContext() 95 | UIGraphicsEndImageContext() 96 | return newImage 97 | } 98 | 99 | } 100 | --------------------------------------------------------------------------------