├── Default-568h@2x.png ├── MIT-LICENSE.txt ├── README.md ├── UzysImageCropper.png ├── UzysImageCropper.xcodeproj └── project.pbxproj └── UzysImageCropper ├── AppDelegate.h ├── AppDelegate.m ├── Library ├── ARCHelper.h ├── UIImage-Extension.h ├── UIImage-Extension.m ├── UzysImageCropper.h ├── UzysImageCropper.m ├── UzysImageCropperViewController.h └── UzysImageCropperViewController.m ├── Resource ├── nc_crop_reset_btn.png ├── nc_crop_reset_btn_h.png ├── nc_crop_rotate_btn.png └── nc_crop_rotate_btn_h.png ├── UzysImageCropper-Info.plist ├── UzysImageCropper-Prefix.pch ├── ViewController.h ├── ViewController.m ├── en.lproj ├── InfoPlist.strings └── ViewController.xib └── main.m /Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uzysjung/UzysImageCropper/b76c85ed9d7cff27230a080ac77fe81980d50dd3/Default-568h@2x.png -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2013 Uzys. 2 | http://uzys.net 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UzysImageCropper 2 | ================ 3 | 4 | An alternative to the UIImagePickerController editor with extended features. 5 | ![Screenshot](https://github.com/uzysjung/UzysImageCropper/raw/master/UzysImageCropper.png) 6 | 7 | **UzysImageCropper features:** 8 | 9 | * You can crop image to exact size which you assign 10 | * Support rotate, scale, move, restore action. 11 | * Support Both ARC and non-ARC Project 12 | 13 | ## Installation 14 | Copy over the files libary folder to your project folder 15 | 16 | ## Usage 17 | 18 | Import header. 19 | 20 | ``` objective-c 21 | #import "UzysImageCropperViewController.h" 22 | @interface ViewController : UIViewController 23 | @end 24 | ``` 25 | 26 | ### Initialize 27 | Simply define CropviewController View size and cropImage size. 28 | 29 | ``` objective-c 30 | _imgCropperViewController = [[UzysImageCropperViewController alloc] initWithImage:[UIImage imageNamed:@"Hyuna.jpg"] 31 | andframeSize:[UIScreen mainScreen].bounds.size 32 | andcropSize:CGSizeMake(1024, 580)]; 33 | _imgCropperViewController.delegate = self; 34 | _imgCropperViewController.modalPresentationStyle = UIModalPresentationFullScreen; 35 | ``` 36 | 37 | ###Delegate 38 | ``` objective-c 39 | - (void)imageCropper:(UzysImageCropperViewController *)cropper didFinishCroppingWithImage:(UIImage *)image { 40 | //Save Image here 41 | [self dismissModalViewControllerAnimated:YES]; 42 | } 43 | 44 | - (void)imageCropperDidCancel:(UzysImageCropperViewController *)cropper { 45 | [self dismissModalViewControllerAnimated:YES]; 46 | } 47 | ``` 48 | 49 | ## Contact 50 | 51 | [Uzys.net](http://uzys.net) 52 | 53 | ## License 54 | 55 | See [LICENSE](https://github.com/uzysjung/UzysImageCropper/blob/master/MIT-LICENSE.txt). 56 | -------------------------------------------------------------------------------- /UzysImageCropper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uzysjung/UzysImageCropper/b76c85ed9d7cff27230a080ac77fe81980d50dd3/UzysImageCropper.png -------------------------------------------------------------------------------- /UzysImageCropper.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9595D4741683FA5500928DC8 /* UIImage-Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 9595D46F1683FA5500928DC8 /* UIImage-Extension.m */; }; 11 | 9595D4751683FA5500928DC8 /* UzysImageCropper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9595D4711683FA5500928DC8 /* UzysImageCropper.m */; }; 12 | 9595D4761683FA5500928DC8 /* UzysImageCropperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9595D4731683FA5500928DC8 /* UzysImageCropperViewController.m */; }; 13 | 959ECF3316BF630700048E1D /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 959ECF3216BF630700048E1D /* Default-568h@2x.png */; }; 14 | C09FE23214FCB8BC0012A2BB /* nc_crop_reset_btn.png in Resources */ = {isa = PBXBuildFile; fileRef = C09FE22E14FCB8BC0012A2BB /* nc_crop_reset_btn.png */; }; 15 | C09FE23314FCB8BC0012A2BB /* nc_crop_reset_btn_h.png in Resources */ = {isa = PBXBuildFile; fileRef = C09FE22F14FCB8BC0012A2BB /* nc_crop_reset_btn_h.png */; }; 16 | C09FE23414FCB8BC0012A2BB /* nc_crop_rotate_btn.png in Resources */ = {isa = PBXBuildFile; fileRef = C09FE23014FCB8BC0012A2BB /* nc_crop_rotate_btn.png */; }; 17 | C09FE23514FCB8BC0012A2BB /* nc_crop_rotate_btn_h.png in Resources */ = {isa = PBXBuildFile; fileRef = C09FE23114FCB8BC0012A2BB /* nc_crop_rotate_btn_h.png */; }; 18 | C0FCD38F14973CF200BFCA38 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0FCD38E14973CF200BFCA38 /* UIKit.framework */; }; 19 | C0FCD39114973CF200BFCA38 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0FCD39014973CF200BFCA38 /* Foundation.framework */; }; 20 | C0FCD39314973CF200BFCA38 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0FCD39214973CF200BFCA38 /* CoreGraphics.framework */; }; 21 | C0FCD39914973CF200BFCA38 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C0FCD39714973CF200BFCA38 /* InfoPlist.strings */; }; 22 | C0FCD39B14973CF200BFCA38 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C0FCD39A14973CF200BFCA38 /* main.m */; }; 23 | C0FCD39F14973CF200BFCA38 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C0FCD39E14973CF200BFCA38 /* AppDelegate.m */; }; 24 | C0FCD3A214973CF200BFCA38 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C0FCD3A114973CF200BFCA38 /* ViewController.m */; }; 25 | C0FCD3A514973CF200BFCA38 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C0FCD3A314973CF200BFCA38 /* ViewController.xib */; }; 26 | C0FFFEA8149B21AE007B78DE /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0FFFEA7149B21AE007B78DE /* QuartzCore.framework */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 9595D46E1683FA5500928DC8 /* UIImage-Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage-Extension.h"; sourceTree = ""; }; 31 | 9595D46F1683FA5500928DC8 /* UIImage-Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage-Extension.m"; sourceTree = ""; }; 32 | 9595D4701683FA5500928DC8 /* UzysImageCropper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysImageCropper.h; sourceTree = ""; }; 33 | 9595D4711683FA5500928DC8 /* UzysImageCropper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysImageCropper.m; sourceTree = ""; }; 34 | 9595D4721683FA5500928DC8 /* UzysImageCropperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysImageCropperViewController.h; sourceTree = ""; }; 35 | 9595D4731683FA5500928DC8 /* UzysImageCropperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysImageCropperViewController.m; sourceTree = ""; }; 36 | 959ECF3216BF630700048E1D /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; 37 | 95AF06DE16BA555500A50CFC /* ARCHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARCHelper.h; sourceTree = ""; }; 38 | C09FE22E14FCB8BC0012A2BB /* nc_crop_reset_btn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = nc_crop_reset_btn.png; sourceTree = ""; }; 39 | C09FE22F14FCB8BC0012A2BB /* nc_crop_reset_btn_h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = nc_crop_reset_btn_h.png; sourceTree = ""; }; 40 | C09FE23014FCB8BC0012A2BB /* nc_crop_rotate_btn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = nc_crop_rotate_btn.png; sourceTree = ""; }; 41 | C09FE23114FCB8BC0012A2BB /* nc_crop_rotate_btn_h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = nc_crop_rotate_btn_h.png; sourceTree = ""; }; 42 | C0FCD38A14973CF200BFCA38 /* UzysImageCropper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UzysImageCropper.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | C0FCD38E14973CF200BFCA38 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 44 | C0FCD39014973CF200BFCA38 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 45 | C0FCD39214973CF200BFCA38 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 46 | C0FCD39614973CF200BFCA38 /* UzysImageCropper-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UzysImageCropper-Info.plist"; sourceTree = ""; }; 47 | C0FCD39814973CF200BFCA38 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 48 | C0FCD39A14973CF200BFCA38 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 49 | C0FCD39C14973CF200BFCA38 /* UzysImageCropper-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UzysImageCropper-Prefix.pch"; sourceTree = ""; }; 50 | C0FCD39D14973CF200BFCA38 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | C0FCD39E14973CF200BFCA38 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | C0FCD3A014973CF200BFCA38 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 53 | C0FCD3A114973CF200BFCA38 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 54 | C0FCD3A414973CF200BFCA38 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; 55 | C0FFFEA7149B21AE007B78DE /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | C0FCD38714973CF200BFCA38 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | C0FFFEA8149B21AE007B78DE /* QuartzCore.framework in Frameworks */, 64 | C0FCD38F14973CF200BFCA38 /* UIKit.framework in Frameworks */, 65 | C0FCD39114973CF200BFCA38 /* Foundation.framework in Frameworks */, 66 | C0FCD39314973CF200BFCA38 /* CoreGraphics.framework in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | 9595D46D1683FA5500928DC8 /* Library */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 95AF06DE16BA555500A50CFC /* ARCHelper.h */, 77 | 9595D46E1683FA5500928DC8 /* UIImage-Extension.h */, 78 | 9595D46F1683FA5500928DC8 /* UIImage-Extension.m */, 79 | 9595D4701683FA5500928DC8 /* UzysImageCropper.h */, 80 | 9595D4711683FA5500928DC8 /* UzysImageCropper.m */, 81 | 9595D4721683FA5500928DC8 /* UzysImageCropperViewController.h */, 82 | 9595D4731683FA5500928DC8 /* UzysImageCropperViewController.m */, 83 | ); 84 | path = Library; 85 | sourceTree = ""; 86 | }; 87 | C09FE22D14FCB8BC0012A2BB /* Resource */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | C09FE22E14FCB8BC0012A2BB /* nc_crop_reset_btn.png */, 91 | C09FE22F14FCB8BC0012A2BB /* nc_crop_reset_btn_h.png */, 92 | C09FE23014FCB8BC0012A2BB /* nc_crop_rotate_btn.png */, 93 | C09FE23114FCB8BC0012A2BB /* nc_crop_rotate_btn_h.png */, 94 | ); 95 | path = Resource; 96 | sourceTree = ""; 97 | }; 98 | C0FCD37F14973CF200BFCA38 = { 99 | isa = PBXGroup; 100 | children = ( 101 | C0FCD39414973CF200BFCA38 /* UzysImageCropper */, 102 | C0FCD38D14973CF200BFCA38 /* Frameworks */, 103 | C0FCD38B14973CF200BFCA38 /* Products */, 104 | ); 105 | sourceTree = ""; 106 | }; 107 | C0FCD38B14973CF200BFCA38 /* Products */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | C0FCD38A14973CF200BFCA38 /* UzysImageCropper.app */, 111 | ); 112 | name = Products; 113 | sourceTree = ""; 114 | }; 115 | C0FCD38D14973CF200BFCA38 /* Frameworks */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | C0FFFEA7149B21AE007B78DE /* QuartzCore.framework */, 119 | C0FCD38E14973CF200BFCA38 /* UIKit.framework */, 120 | C0FCD39014973CF200BFCA38 /* Foundation.framework */, 121 | C0FCD39214973CF200BFCA38 /* CoreGraphics.framework */, 122 | ); 123 | name = Frameworks; 124 | sourceTree = ""; 125 | }; 126 | C0FCD39414973CF200BFCA38 /* UzysImageCropper */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 959ECF3216BF630700048E1D /* Default-568h@2x.png */, 130 | 9595D46D1683FA5500928DC8 /* Library */, 131 | C0FCD39D14973CF200BFCA38 /* AppDelegate.h */, 132 | C0FCD39E14973CF200BFCA38 /* AppDelegate.m */, 133 | C0FCD3A014973CF200BFCA38 /* ViewController.h */, 134 | C0FCD3A114973CF200BFCA38 /* ViewController.m */, 135 | C0FCD3A314973CF200BFCA38 /* ViewController.xib */, 136 | C0FCD39514973CF200BFCA38 /* Supporting Files */, 137 | C09FE22D14FCB8BC0012A2BB /* Resource */, 138 | ); 139 | path = UzysImageCropper; 140 | sourceTree = ""; 141 | }; 142 | C0FCD39514973CF200BFCA38 /* Supporting Files */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | C0FCD39614973CF200BFCA38 /* UzysImageCropper-Info.plist */, 146 | C0FCD39714973CF200BFCA38 /* InfoPlist.strings */, 147 | C0FCD39A14973CF200BFCA38 /* main.m */, 148 | C0FCD39C14973CF200BFCA38 /* UzysImageCropper-Prefix.pch */, 149 | ); 150 | name = "Supporting Files"; 151 | sourceTree = ""; 152 | }; 153 | /* End PBXGroup section */ 154 | 155 | /* Begin PBXNativeTarget section */ 156 | C0FCD38914973CF200BFCA38 /* UzysImageCropper */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = C0FCD3A814973CF200BFCA38 /* Build configuration list for PBXNativeTarget "UzysImageCropper" */; 159 | buildPhases = ( 160 | C0FCD38614973CF200BFCA38 /* Sources */, 161 | C0FCD38714973CF200BFCA38 /* Frameworks */, 162 | C0FCD38814973CF200BFCA38 /* Resources */, 163 | ); 164 | buildRules = ( 165 | ); 166 | dependencies = ( 167 | ); 168 | name = UzysImageCropper; 169 | productName = UzysImageCropper; 170 | productReference = C0FCD38A14973CF200BFCA38 /* UzysImageCropper.app */; 171 | productType = "com.apple.product-type.application"; 172 | }; 173 | /* End PBXNativeTarget section */ 174 | 175 | /* Begin PBXProject section */ 176 | C0FCD38114973CF200BFCA38 /* Project object */ = { 177 | isa = PBXProject; 178 | attributes = { 179 | LastUpgradeCheck = 0460; 180 | ORGANIZATIONNAME = NCSoft; 181 | }; 182 | buildConfigurationList = C0FCD38414973CF200BFCA38 /* Build configuration list for PBXProject "UzysImageCropper" */; 183 | compatibilityVersion = "Xcode 3.2"; 184 | developmentRegion = English; 185 | hasScannedForEncodings = 0; 186 | knownRegions = ( 187 | en, 188 | ); 189 | mainGroup = C0FCD37F14973CF200BFCA38; 190 | productRefGroup = C0FCD38B14973CF200BFCA38 /* Products */; 191 | projectDirPath = ""; 192 | projectRoot = ""; 193 | targets = ( 194 | C0FCD38914973CF200BFCA38 /* UzysImageCropper */, 195 | ); 196 | }; 197 | /* End PBXProject section */ 198 | 199 | /* Begin PBXResourcesBuildPhase section */ 200 | C0FCD38814973CF200BFCA38 /* Resources */ = { 201 | isa = PBXResourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | C0FCD39914973CF200BFCA38 /* InfoPlist.strings in Resources */, 205 | C0FCD3A514973CF200BFCA38 /* ViewController.xib in Resources */, 206 | C09FE23214FCB8BC0012A2BB /* nc_crop_reset_btn.png in Resources */, 207 | C09FE23314FCB8BC0012A2BB /* nc_crop_reset_btn_h.png in Resources */, 208 | C09FE23414FCB8BC0012A2BB /* nc_crop_rotate_btn.png in Resources */, 209 | C09FE23514FCB8BC0012A2BB /* nc_crop_rotate_btn_h.png in Resources */, 210 | 959ECF3316BF630700048E1D /* Default-568h@2x.png in Resources */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXResourcesBuildPhase section */ 215 | 216 | /* Begin PBXSourcesBuildPhase section */ 217 | C0FCD38614973CF200BFCA38 /* Sources */ = { 218 | isa = PBXSourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | C0FCD39B14973CF200BFCA38 /* main.m in Sources */, 222 | C0FCD39F14973CF200BFCA38 /* AppDelegate.m in Sources */, 223 | C0FCD3A214973CF200BFCA38 /* ViewController.m in Sources */, 224 | 9595D4741683FA5500928DC8 /* UIImage-Extension.m in Sources */, 225 | 9595D4751683FA5500928DC8 /* UzysImageCropper.m in Sources */, 226 | 9595D4761683FA5500928DC8 /* UzysImageCropperViewController.m in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXSourcesBuildPhase section */ 231 | 232 | /* Begin PBXVariantGroup section */ 233 | C0FCD39714973CF200BFCA38 /* InfoPlist.strings */ = { 234 | isa = PBXVariantGroup; 235 | children = ( 236 | C0FCD39814973CF200BFCA38 /* en */, 237 | ); 238 | name = InfoPlist.strings; 239 | sourceTree = ""; 240 | }; 241 | C0FCD3A314973CF200BFCA38 /* ViewController.xib */ = { 242 | isa = PBXVariantGroup; 243 | children = ( 244 | C0FCD3A414973CF200BFCA38 /* en */, 245 | ); 246 | name = ViewController.xib; 247 | sourceTree = ""; 248 | }; 249 | /* End PBXVariantGroup section */ 250 | 251 | /* Begin XCBuildConfiguration section */ 252 | C0FCD3A614973CF200BFCA38 /* Debug */ = { 253 | isa = XCBuildConfiguration; 254 | buildSettings = { 255 | ALWAYS_SEARCH_USER_PATHS = NO; 256 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 257 | CLANG_ENABLE_OBJC_ARC = YES; 258 | CLANG_WARN_CONSTANT_CONVERSION = YES; 259 | CLANG_WARN_ENUM_CONVERSION = YES; 260 | CLANG_WARN_INT_CONVERSION = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | CODE_SIGN_IDENTITY = "iPhone Developer: Jaehoon Jung (TUH344CALK)"; 263 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 264 | COPY_PHASE_STRIP = NO; 265 | GCC_C_LANGUAGE_STANDARD = gnu99; 266 | GCC_DYNAMIC_NO_PIC = NO; 267 | GCC_OPTIMIZATION_LEVEL = 0; 268 | GCC_PREPROCESSOR_DEFINITIONS = ( 269 | "DEBUG=1", 270 | "$(inherited)", 271 | ); 272 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 273 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 274 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 275 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 276 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 277 | GCC_WARN_UNUSED_VARIABLE = YES; 278 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 279 | PROVISIONING_PROFILE = "7EC5F80F-ECD9-4580-AAF4-9061490479AB"; 280 | SDKROOT = iphoneos; 281 | }; 282 | name = Debug; 283 | }; 284 | C0FCD3A714973CF200BFCA38 /* Release */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ALWAYS_SEARCH_USER_PATHS = NO; 288 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 289 | CLANG_ENABLE_OBJC_ARC = YES; 290 | CLANG_WARN_CONSTANT_CONVERSION = YES; 291 | CLANG_WARN_ENUM_CONVERSION = YES; 292 | CLANG_WARN_INT_CONVERSION = YES; 293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 294 | CODE_SIGN_IDENTITY = "iPhone Developer: Jaehoon Jung (TUH344CALK)"; 295 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 296 | COPY_PHASE_STRIP = YES; 297 | GCC_C_LANGUAGE_STANDARD = gnu99; 298 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 299 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 300 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 301 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 302 | GCC_WARN_UNUSED_VARIABLE = YES; 303 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 304 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 305 | PROVISIONING_PROFILE = "7EC5F80F-ECD9-4580-AAF4-9061490479AB"; 306 | SDKROOT = iphoneos; 307 | VALIDATE_PRODUCT = YES; 308 | }; 309 | name = Release; 310 | }; 311 | C0FCD3A914973CF200BFCA38 /* Debug */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | CLANG_ENABLE_OBJC_ARC = YES; 315 | CODE_SIGN_IDENTITY = "iPhone Developer: Jaehoon Jung (TUH344CALK)"; 316 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 317 | GCC_PREFIX_HEADER = "UzysImageCropper/UzysImageCropper-Prefix.pch"; 318 | INFOPLIST_FILE = "UzysImageCropper/UzysImageCropper-Info.plist"; 319 | PRODUCT_NAME = "$(TARGET_NAME)"; 320 | PROVISIONING_PROFILE = "7EC5F80F-ECD9-4580-AAF4-9061490479AB"; 321 | WRAPPER_EXTENSION = app; 322 | }; 323 | name = Debug; 324 | }; 325 | C0FCD3AA14973CF200BFCA38 /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CODE_SIGN_IDENTITY = "iPhone Developer: Jaehoon Jung (TUH344CALK)"; 330 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 331 | GCC_PREFIX_HEADER = "UzysImageCropper/UzysImageCropper-Prefix.pch"; 332 | INFOPLIST_FILE = "UzysImageCropper/UzysImageCropper-Info.plist"; 333 | PRODUCT_NAME = "$(TARGET_NAME)"; 334 | PROVISIONING_PROFILE = "7EC5F80F-ECD9-4580-AAF4-9061490479AB"; 335 | WRAPPER_EXTENSION = app; 336 | }; 337 | name = Release; 338 | }; 339 | /* End XCBuildConfiguration section */ 340 | 341 | /* Begin XCConfigurationList section */ 342 | C0FCD38414973CF200BFCA38 /* Build configuration list for PBXProject "UzysImageCropper" */ = { 343 | isa = XCConfigurationList; 344 | buildConfigurations = ( 345 | C0FCD3A614973CF200BFCA38 /* Debug */, 346 | C0FCD3A714973CF200BFCA38 /* Release */, 347 | ); 348 | defaultConfigurationIsVisible = 0; 349 | defaultConfigurationName = Release; 350 | }; 351 | C0FCD3A814973CF200BFCA38 /* Build configuration list for PBXNativeTarget "UzysImageCropper" */ = { 352 | isa = XCConfigurationList; 353 | buildConfigurations = ( 354 | C0FCD3A914973CF200BFCA38 /* Debug */, 355 | C0FCD3AA14973CF200BFCA38 /* Release */, 356 | ); 357 | defaultConfigurationIsVisible = 0; 358 | defaultConfigurationName = Release; 359 | }; 360 | /* End XCConfigurationList section */ 361 | }; 362 | rootObject = C0FCD38114973CF200BFCA38 /* Project object */; 363 | } 364 | -------------------------------------------------------------------------------- /UzysImageCropper/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import 9 | 10 | @class ViewController; 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @property (strong, nonatomic) ViewController *viewController; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /UzysImageCropper/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import "ViewController.h" 11 | 12 | @implementation AppDelegate 13 | 14 | @synthesize window = _window; 15 | @synthesize viewController = _viewController; 16 | 17 | - (void)dealloc 18 | { 19 | [_window release]; 20 | [_viewController release]; 21 | [super ah_dealloc]; 22 | } 23 | 24 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 25 | { 26 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 27 | // Override point for customization after application launch. 28 | self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; 29 | self.window.rootViewController = self.viewController; 30 | [self.window makeKeyAndVisible]; 31 | return YES; 32 | } 33 | 34 | - (void)applicationWillResignActive:(UIApplication *)application 35 | { 36 | /* 37 | 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. 38 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 39 | */ 40 | } 41 | 42 | - (void)applicationDidEnterBackground:(UIApplication *)application 43 | { 44 | /* 45 | 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. 46 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 47 | */ 48 | } 49 | 50 | - (void)applicationWillEnterForeground:(UIApplication *)application 51 | { 52 | /* 53 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 54 | */ 55 | } 56 | 57 | - (void)applicationDidBecomeActive:(UIApplication *)application 58 | { 59 | /* 60 | 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. 61 | */ 62 | } 63 | 64 | - (void)applicationWillTerminate:(UIApplication *)application 65 | { 66 | /* 67 | Called when the application is about to terminate. 68 | Save data if appropriate. 69 | See also applicationDidEnterBackground:. 70 | */ 71 | } 72 | @end 73 | -------------------------------------------------------------------------------- /UzysImageCropper/Library/ARCHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARC Helper 3 | // 4 | // Version 2.1 5 | // 6 | // Created by Nick Lockwood on 05/01/2012. 7 | // Copyright 2012 Charcoal Design 8 | // 9 | // Distributed under the permissive zlib license 10 | // Get the latest version from here: 11 | // 12 | // https://gist.github.com/1563325 13 | // 14 | 15 | #ifndef ah_retain 16 | #if __has_feature(objc_arc) 17 | #define ah_retain self 18 | #define ah_dealloc self 19 | #define release self 20 | #define autorelease self 21 | #else 22 | #define ah_retain retain 23 | #define ah_dealloc dealloc 24 | #define __bridge 25 | #endif 26 | #endif 27 | 28 | // Weak reference support 29 | 30 | #import 31 | #if (!__has_feature(objc_arc)) || \ 32 | (defined __IPHONE_OS_VERSION_MIN_REQUIRED && \ 33 | __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0) || \ 34 | (defined __MAC_OS_X_VERSION_MIN_REQUIRED && \ 35 | __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7) 36 | #undef weak 37 | #define weak unsafe_unretained 38 | #undef __weak 39 | #define __weak __unsafe_unretained 40 | #endif 41 | 42 | // Weak delegate support 43 | 44 | #ifndef ah_weak 45 | #import 46 | #if (__has_feature(objc_arc)) && \ 47 | ((defined __IPHONE_OS_VERSION_MIN_REQUIRED && \ 48 | __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_5_0) || \ 49 | (defined __MAC_OS_X_VERSION_MIN_REQUIRED && \ 50 | __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_7)) 51 | #define ah_weak weak 52 | #define __ah_weak __weak 53 | #else 54 | #define ah_weak unsafe_unretained 55 | #define __ah_weak __unsafe_unretained 56 | #endif 57 | #endif 58 | 59 | // ARC Helper ends -------------------------------------------------------------------------------- /UzysImageCropper/Library/UIImage-Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage-Extension.h 3 | // 4 | // Created by Hardy Macia on 7/1/09. 5 | // Copyright 2009 Catamount Software. All rights reserved. 6 | // 7 | #import 8 | #import "ARCHelper.h" 9 | 10 | @interface UIImage (CS_Extensions) 11 | - (UIImage *)imageRotatedByRadians:(CGFloat)radians; 12 | - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees; 13 | 14 | - (UIImage*)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale; 15 | - (UIImage*)resizedImageToSize:(CGSize)dstSize; 16 | - (UIImage *)cropImage:(CGRect) rect; 17 | - (UIImage *)fixOrientation; 18 | 19 | @end 20 | 21 | 22 | -------------------------------------------------------------------------------- /UzysImageCropper/Library/UIImage-Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage-Extensions.m 3 | // 4 | // Created by Hardy Macia on 7/1/09. 5 | // Copyright 2009 Catamount Software. All rights reserved. 6 | // 7 | 8 | #import "UIImage-Extension.h" 9 | CGFloat DegreesToRadians(CGFloat degrees); 10 | CGFloat RadiansToDegrees(CGFloat radians); 11 | 12 | @implementation UIImage (CS_Extensions) 13 | 14 | - (UIImage *)cropImage:(CGRect) rect{ 15 | CGAffineTransform rectTransform; 16 | switch (self.imageOrientation) 17 | { 18 | case UIImageOrientationLeft: 19 | rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(DegreesToRadians(90)), 0, -self.size.height); 20 | break; 21 | case UIImageOrientationRight: 22 | rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(DegreesToRadians(-90)), -self.size.width, 0); 23 | break; 24 | case UIImageOrientationDown: 25 | rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(DegreesToRadians(-180)), -self.size.width, -self.size.height); 26 | break; 27 | default: 28 | rectTransform = CGAffineTransformIdentity; 29 | }; 30 | rectTransform = CGAffineTransformScale(rectTransform, self.scale, self.scale); 31 | 32 | CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], CGRectApplyAffineTransform(rect, rectTransform)); 33 | UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; 34 | CGImageRelease(imageRef); 35 | return result; 36 | } 37 | 38 | -(UIImage*)resizedImageToSize:(CGSize)dstSize 39 | { 40 | CGImageRef imgRef = self.CGImage; 41 | // the below values are regardless of orientation : for UIImages from Camera, width>height (landscape) 42 | CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which is dependant on the imageOrientation)! 43 | 44 | CGFloat scaleRatio = dstSize.width / srcSize.width; 45 | UIImageOrientation orient = self.imageOrientation; 46 | CGAffineTransform transform = CGAffineTransformIdentity; 47 | switch(orient) { 48 | 49 | case UIImageOrientationUp: //EXIF = 1 50 | transform = CGAffineTransformIdentity; 51 | break; 52 | 53 | case UIImageOrientationUpMirrored: //EXIF = 2 54 | transform = CGAffineTransformMakeTranslation(srcSize.width, 0.0); 55 | transform = CGAffineTransformScale(transform, -1.0, 1.0); 56 | break; 57 | 58 | case UIImageOrientationDown: //EXIF = 3 59 | transform = CGAffineTransformMakeTranslation(srcSize.width, srcSize.height); 60 | transform = CGAffineTransformRotate(transform, M_PI); 61 | break; 62 | 63 | case UIImageOrientationDownMirrored: //EXIF = 4 64 | transform = CGAffineTransformMakeTranslation(0.0, srcSize.height); 65 | transform = CGAffineTransformScale(transform, 1.0, -1.0); 66 | break; 67 | 68 | case UIImageOrientationLeftMirrored: //EXIF = 5 69 | dstSize = CGSizeMake(dstSize.height, dstSize.width); 70 | transform = CGAffineTransformMakeTranslation(srcSize.height, srcSize.width); 71 | transform = CGAffineTransformScale(transform, -1.0, 1.0); 72 | transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2); 73 | break; 74 | 75 | case UIImageOrientationLeft: //EXIF = 6 76 | dstSize = CGSizeMake(dstSize.height, dstSize.width); 77 | transform = CGAffineTransformMakeTranslation(0.0, srcSize.width); 78 | transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2); 79 | break; 80 | 81 | case UIImageOrientationRightMirrored: //EXIF = 7 82 | dstSize = CGSizeMake(dstSize.height, dstSize.width); 83 | transform = CGAffineTransformMakeScale(-1.0, 1.0); 84 | transform = CGAffineTransformRotate(transform, M_PI_2); 85 | break; 86 | 87 | case UIImageOrientationRight: //EXIF = 8 88 | dstSize = CGSizeMake(dstSize.height, dstSize.width); 89 | transform = CGAffineTransformMakeTranslation(srcSize.height, 0.0); 90 | transform = CGAffineTransformRotate(transform, M_PI_2); 91 | break; 92 | 93 | default: 94 | [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; 95 | 96 | } 97 | 98 | ///////////////////////////////////////////////////////////////////////////// 99 | // The actual resize: draw the image on a new context, applying a transform matrix 100 | UIGraphicsBeginImageContextWithOptions(dstSize, NO, 0.0); 101 | 102 | CGContextRef context = UIGraphicsGetCurrentContext(); 103 | 104 | if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { 105 | CGContextScaleCTM(context, -scaleRatio, scaleRatio); 106 | CGContextTranslateCTM(context, -srcSize.height, 0); 107 | } else { 108 | CGContextScaleCTM(context, scaleRatio, -scaleRatio); 109 | CGContextTranslateCTM(context, 0, -srcSize.height); 110 | } 111 | 112 | CGContextConcatCTM(context, transform); 113 | 114 | // we use srcSize (and not dstSize) as the size to specify is in user space (and we use the CTM to apply a scaleRatio) 115 | CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, srcSize.width, srcSize.height), imgRef); 116 | UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext(); 117 | UIGraphicsEndImageContext(); 118 | 119 | return resizedImage; 120 | } 121 | 122 | 123 | 124 | ///////////////////////////////////////////////////////////////////////////// 125 | 126 | 127 | 128 | -(UIImage*)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale 129 | { 130 | // get the image size (independant of imageOrientation) 131 | CGImageRef imgRef = self.CGImage; 132 | CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which depends on the imageOrientation)! 133 | 134 | // adjust boundingSize to make it independant on imageOrientation too for farther computations 135 | UIImageOrientation orient = self.imageOrientation; 136 | switch (orient) { 137 | case UIImageOrientationLeft: 138 | case UIImageOrientationRight: 139 | case UIImageOrientationLeftMirrored: 140 | case UIImageOrientationRightMirrored: 141 | boundingSize = CGSizeMake(boundingSize.height, boundingSize.width); 142 | break; 143 | default: 144 | // NOP 145 | break; 146 | } 147 | 148 | // Compute the target CGRect in order to keep aspect-ratio 149 | CGSize dstSize; 150 | 151 | if ( !scale && (srcSize.width < boundingSize.width) && (srcSize.height < boundingSize.height) ) { 152 | //NSLog(@"Image is smaller, and we asked not to scale it in this case (scaleIfSmaller:NO)"); 153 | dstSize = srcSize; // no resize (we could directly return 'self' here, but we draw the image anyway to take image orientation into account) 154 | } else { 155 | CGFloat wRatio = boundingSize.width / srcSize.width; 156 | CGFloat hRatio = boundingSize.height / srcSize.height; 157 | 158 | if (wRatio < hRatio) { 159 | //NSLog(@"Width imposed, Height scaled ; ratio = %f",wRatio); 160 | dstSize = CGSizeMake(floorf(srcSize.width * hRatio), boundingSize.height); 161 | } else { 162 | //NSLog(@"Height imposed, Width scaled ; ratio = %f",hRatio); 163 | dstSize = CGSizeMake(boundingSize.width, floorf(srcSize.height * wRatio)); 164 | 165 | } 166 | } 167 | 168 | return [self resizedImageToSize:dstSize]; 169 | } 170 | 171 | 172 | - (UIImage *)imageRotatedByRadians:(CGFloat)radians 173 | { 174 | return [self imageRotatedByDegrees:RadiansToDegrees(radians)]; 175 | } 176 | 177 | - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees 178 | { 179 | 180 | 181 | // calculate the size of the rotated view's containing box for our drawing space 182 | UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)]; 183 | CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees)); 184 | rotatedViewBox.transform = t; 185 | CGSize rotatedSize = rotatedViewBox.frame.size; 186 | [rotatedViewBox release]; 187 | 188 | // Create the bitmap context 189 | UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, self.scale); 190 | CGContextRef bitmap = UIGraphicsGetCurrentContext(); 191 | 192 | // Move the origin to the middle of the image so we will rotate and scale around the center. 193 | CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); 194 | 195 | // // Rotate the image context 196 | CGContextRotateCTM(bitmap, DegreesToRadians(degrees)); 197 | 198 | // Now, draw the rotated/scaled image into the context 199 | CGContextScaleCTM(bitmap, 1.0, -1.0); 200 | CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]); 201 | 202 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 203 | UIGraphicsEndImageContext(); 204 | return newImage; 205 | 206 | } 207 | 208 | - (UIImage *)fixOrientation { 209 | 210 | // No-op if the orientation is already correct 211 | if (self.imageOrientation == UIImageOrientationUp) return self; 212 | 213 | // We need to calculate the proper transformation to make the image upright. 214 | // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 215 | CGAffineTransform transform = CGAffineTransformIdentity; 216 | 217 | switch (self.imageOrientation) { 218 | case UIImageOrientationDown: 219 | case UIImageOrientationDownMirrored: 220 | transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); 221 | transform = CGAffineTransformRotate(transform, M_PI); 222 | break; 223 | 224 | case UIImageOrientationLeft: 225 | case UIImageOrientationLeftMirrored: 226 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 227 | transform = CGAffineTransformRotate(transform, M_PI_2); 228 | break; 229 | 230 | case UIImageOrientationRight: 231 | case UIImageOrientationRightMirrored: 232 | transform = CGAffineTransformTranslate(transform, 0, self.size.height); 233 | transform = CGAffineTransformRotate(transform, -M_PI_2); 234 | break; 235 | case UIImageOrientationUp: 236 | case UIImageOrientationUpMirrored: 237 | break; 238 | } 239 | 240 | switch (self.imageOrientation) { 241 | case UIImageOrientationUpMirrored: 242 | case UIImageOrientationDownMirrored: 243 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 244 | transform = CGAffineTransformScale(transform, -1, 1); 245 | break; 246 | 247 | case UIImageOrientationLeftMirrored: 248 | case UIImageOrientationRightMirrored: 249 | transform = CGAffineTransformTranslate(transform, self.size.height, 0); 250 | transform = CGAffineTransformScale(transform, -1, 1); 251 | break; 252 | case UIImageOrientationUp: 253 | case UIImageOrientationDown: 254 | case UIImageOrientationLeft: 255 | case UIImageOrientationRight: 256 | break; 257 | } 258 | 259 | // Now we draw the underlying CGImage into a new context, applying the transform 260 | // calculated above. 261 | CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, 262 | CGImageGetBitsPerComponent(self.CGImage), 0, 263 | CGImageGetColorSpace(self.CGImage), 264 | CGImageGetBitmapInfo(self.CGImage)); 265 | CGContextConcatCTM(ctx, transform); 266 | switch (self.imageOrientation) { 267 | case UIImageOrientationLeft: 268 | case UIImageOrientationLeftMirrored: 269 | case UIImageOrientationRight: 270 | case UIImageOrientationRightMirrored: 271 | // Grr... 272 | CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); 273 | break; 274 | 275 | default: 276 | CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage); 277 | break; 278 | } 279 | 280 | // And now we just create a new UIImage from the drawing context 281 | CGImageRef cgimg = CGBitmapContextCreateImage(ctx); 282 | UIImage *img = [UIImage imageWithCGImage:cgimg]; 283 | CGContextRelease(ctx); 284 | CGImageRelease(cgimg); 285 | return img; 286 | } 287 | 288 | @end 289 | #pragma mark - C function 290 | CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; 291 | CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;}; 292 | -------------------------------------------------------------------------------- /UzysImageCropper/Library/UzysImageCropper.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysImageCropper.h 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import 9 | #import "ARCHelper.h" 10 | 11 | @interface UzysImageCropper : UIView 12 | { 13 | double _imageScale; //frame : image 14 | double _translateX; 15 | double _translateY; 16 | 17 | CGRect _imgViewframeInitValue; //imgView는 가운데 정렬 되므로 초기값 위치가 (0,0)이 아니므로 위치를 알아야함 18 | CGPoint _imgViewcenterInitValue; 19 | CGSize _realCropsize; 20 | UIView* _cropperView; 21 | } 22 | @property (nonatomic,strong) UIImage *inputImage; 23 | @property (nonatomic,strong) UIImageView *imgView; 24 | @property (nonatomic,assign) CGRect cropRect; 25 | 26 | - (id)initWithImage:(UIImage*)newImage andframeSize:(CGSize)frameSize andcropSize:(CGSize)cropSize; 27 | - (UIImage*) getCroppedImage; 28 | - (BOOL) saveCroppedImage:(NSString *)path; 29 | 30 | - (void) actionRotate; 31 | - (void) actionRestore; 32 | @end 33 | -------------------------------------------------------------------------------- /UzysImageCropper/Library/UzysImageCropper.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysImageCropper.m 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #define MAX_ZOOMSCALE 3 9 | 10 | //#define CROPPERVIEW_IMG 11 | 12 | #import "UzysImageCropper.h" 13 | #import "UIImage-Extension.h" 14 | #import 15 | #import 16 | @interface UzysImageCropper() 17 | - (void)setupGestureRecognizer; 18 | - (void)zoomAction:(UIGestureRecognizer *)sender; 19 | - (void)panAction:(UIPanGestureRecognizer *)gesture; 20 | - (void)RotationAction:(UIGestureRecognizer *)sender; 21 | - (void)DoubleTapAction:(UIGestureRecognizer *)sender; 22 | @end 23 | 24 | @implementation UzysImageCropper 25 | @synthesize imgView = _imgView,inputImage=_inputImage,cropRect=_cropRect; 26 | 27 | #pragma mark - initialize 28 | - (id)init 29 | { 30 | self = [super init]; 31 | if (self) 32 | { 33 | NSAssert(TRUE,@"Plz initialize using initWithImage:andframeSize:andcropSize: "); 34 | } 35 | 36 | return self; 37 | } 38 | - (id)initWithFrame:(CGRect)frame 39 | { 40 | self = [super initWithFrame:frame]; 41 | if (self) 42 | { 43 | // Initialization code 44 | NSAssert(TRUE,@"Plz initialize using initWithImage:andframeSize:andcropSize: "); 45 | } 46 | return self; 47 | } 48 | 49 | - (id)initWithImage:(UIImage*)newImage andframeSize:(CGSize)frameSize andcropSize:(CGSize)cropSize 50 | { 51 | self = [super init]; 52 | if(self) 53 | { 54 | //Variable for GestureRecognizer 55 | _translateX =0; 56 | _translateY =0; 57 | 58 | self.frame = CGRectMake(0, 0, frameSize.width, frameSize.height); 59 | self.inputImage = newImage; 60 | //Case 1 실제 이미지를 frame Width size에 맞춤 --> 이미지가 커지면 크롭영역도 320x480의 프레임 영역에서 작게 표시됨. 61 | //_imageScale = frameSize.width / inputImage.size.width; //scale criteria depend on width size 62 | 63 | //Case 2 crop Width를 310에 고정 --> 크롭영역은 일정. 64 | _imageScale = 310/cropSize.width ; 65 | 66 | CGRect imgViewBound = CGRectMake(0, 0, _inputImage.size.width*_imageScale, _inputImage.size.height*_imageScale); //이미지가 생성될 사이즈. 67 | _imgView = [[UIImageView alloc] initWithFrame:imgViewBound]; 68 | _imgView.center = self.center; 69 | _imgView.image = _inputImage; 70 | _imgView.backgroundColor = [UIColor whiteColor]; 71 | 72 | _imgViewframeInitValue = _imgView.frame; 73 | _imgViewcenterInitValue = _imgView.center; 74 | _realCropsize = cropSize; // _realCropsize = Cropping Size in RealImage 75 | 76 | //cropX,cropY = cropRect position to center in Frame. 77 | double cropX = (self.imgView.frame.size.width/2) - (_imageScale*cropSize.width/2); 78 | double cropY = (self.imgView.frame.size.height/2) - (_imageScale*cropSize.height/2); 79 | 80 | //cropX위치 + imgViewframe이 가운데 정렬되어있으므로 그위치 만큼 이동. 81 | _cropRect = CGRectMake(cropX+ _imgViewframeInitValue.origin.x, cropY+ _imgViewframeInitValue.origin.y, _imageScale*cropSize.width, _imageScale*cropSize.height); 82 | 83 | //_cropperView show the view will crop. 84 | _cropperView = [[UIView alloc] initWithFrame:_cropRect]; 85 | _cropperView.backgroundColor = [UIColor blueColor]; 86 | _cropperView.alpha = 0.5; 87 | 88 | UIImageView *cropimg = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cropperview.png"]] autorelease]; 89 | cropimg.center = _cropperView.center; 90 | cropimg.alpha = 0.7; 91 | 92 | #ifdef CROPPERVIEW_IMG 93 | _cropperView.hidden = YES; 94 | #else 95 | cropimg.hidden = YES; 96 | #endif 97 | 98 | [self addSubview:_imgView]; 99 | [self addSubview:cropimg]; 100 | [self addSubview:_cropperView]; 101 | [self setupGestureRecognizer]; 102 | 103 | self.clipsToBounds = YES; 104 | } 105 | return self; 106 | } 107 | 108 | 109 | #pragma mark - UIGestureAction 110 | - (void)zoomAction:(UIGestureRecognizer *)sender 111 | { 112 | CGFloat factor = [(UIPinchGestureRecognizer *)sender scale]; 113 | static CGFloat lastScale=1; 114 | 115 | if([sender state] == UIGestureRecognizerStateBegan) 116 | { 117 | // Reset the last scale, necessary if there are multiple objects with different scales 118 | lastScale =1; 119 | } 120 | if ([sender state] == UIGestureRecognizerStateChanged 121 | || [sender state] == UIGestureRecognizerStateEnded) 122 | { 123 | CGRect imgViewFrame = _imgView.frame; 124 | CGFloat minX,minY,maxX,maxY,imgViewMaxX,imgViewMaxY; 125 | minX= CGRectGetMinX(_cropRect); 126 | minY= CGRectGetMinY(_cropRect); 127 | maxX= CGRectGetMaxX(_cropRect); 128 | maxY= CGRectGetMaxY(_cropRect); 129 | 130 | CGFloat currentScale = [[self.imgView.layer valueForKeyPath:@"transform.scale.x"] floatValue]; 131 | // CGFloat currentScale = self.imgView.transform.a; 132 | const CGFloat kMaxScale = 2.0; 133 | CGFloat newScale = 1 - (lastScale - factor); // new scale is in the range (0-1) 134 | newScale = MIN(newScale, kMaxScale / currentScale); 135 | 136 | //변화된 후의 imgViewFrame 137 | imgViewFrame.size.width = imgViewFrame.size.width * newScale; 138 | imgViewFrame.size.height = imgViewFrame.size.height * newScale; 139 | imgViewFrame.origin.x = self.imgView.center.x - imgViewFrame.size.width/2; 140 | imgViewFrame.origin.y = self.imgView.center.y - imgViewFrame.size.height/2; 141 | 142 | imgViewMaxX= CGRectGetMaxX(imgViewFrame); 143 | imgViewMaxY= CGRectGetMaxY(imgViewFrame); 144 | 145 | //역변환 공식 146 | NSInteger collideState = 0; 147 | 148 | if(imgViewFrame.origin.x >= minX) //left 149 | { 150 | collideState = 1; 151 | } 152 | else if(imgViewFrame.origin.y >= minY) // up 153 | { 154 | collideState = 2; 155 | } 156 | else if(imgViewMaxX <= maxX) //right 157 | { 158 | collideState = 3; 159 | } 160 | else if(imgViewMaxY <= maxY) //down 161 | { 162 | collideState = 4; 163 | } 164 | 165 | // NSLog(@"scale :%f",newScale); 166 | if(collideState >0) // 걸렸을 때 167 | { 168 | 169 | if(lastScale - factor <= 0) //확대 모션 170 | { 171 | lastScale = factor; 172 | CGAffineTransform transformN = CGAffineTransformScale(self.imgView.transform, newScale, newScale); 173 | self.imgView.transform = transformN; 174 | } 175 | else 176 | { 177 | lastScale = factor; 178 | 179 | CGPoint newcenter = _imgView.center; 180 | 181 | if(collideState ==1 || collideState ==3) 182 | { 183 | newcenter.x = _cropperView.center.x; 184 | } 185 | else if(collideState ==2 || collideState ==4) 186 | { 187 | newcenter.y = _cropperView.center.y; 188 | } 189 | 190 | [UIView animateWithDuration:0.5f animations:^(void) { 191 | 192 | self.imgView.center = newcenter; 193 | [sender reset]; 194 | 195 | } ]; 196 | 197 | } 198 | 199 | } 200 | else //정상일 때 201 | { 202 | CGAffineTransform transformN = CGAffineTransformScale(self.imgView.transform, newScale, newScale); 203 | self.imgView.transform = transformN; 204 | lastScale = factor; 205 | } 206 | 207 | } 208 | 209 | } 210 | - (void)panAction:(UIPanGestureRecognizer *)gesture 211 | { 212 | 213 | static CGPoint prevLoc; 214 | CGPoint location = [gesture locationInView:self]; 215 | if(gesture.state == UIGestureRecognizerStateBegan) 216 | { 217 | prevLoc = location; //Starting position 218 | } 219 | 220 | if ((gesture.state == UIGestureRecognizerStateChanged) || (gesture.state == UIGestureRecognizerStateEnded)) 221 | { 222 | 223 | CGFloat minX,minY,maxX,maxY,imgViewMaxX,imgViewMaxY; 224 | 225 | //calculate offset 226 | _translateX = (location.x - prevLoc.x); 227 | _translateY = (location.y - prevLoc.y); 228 | 229 | // 회전이 있는 경우 기준 230 | CGPoint center = self.imgView.center; 231 | minX= CGRectGetMinX(_cropRect); 232 | minY= CGRectGetMinY(_cropRect); 233 | maxX= CGRectGetMaxX(_cropRect); 234 | maxY= CGRectGetMaxY(_cropRect); 235 | 236 | center.x =center.x +_translateX; 237 | center.y = center.y +_translateY; 238 | 239 | imgViewMaxX= center.x + _imgView.frame.size.width/2; 240 | imgViewMaxY= center.y+ _imgView.frame.size.height/2; 241 | 242 | if( (center.x - (_imgView.frame.size.width/2) ) >= minX) 243 | { 244 | center.x = minX + (_imgView.frame.size.width/2) ; 245 | } 246 | if( center.y - (_imgView.frame.size.height/2) >= minY) 247 | { 248 | center.y = minY + (_imgView.frame.size.height/2) ; 249 | } 250 | if(imgViewMaxX <= maxX) 251 | { 252 | center.x = maxX - (_imgView.frame.size.width/2); 253 | } 254 | if(imgViewMaxY <= maxY) 255 | { 256 | center.y = maxY - (_imgView.frame.size.height/2); 257 | } 258 | 259 | self.imgView.center = center; 260 | prevLoc = location; 261 | } 262 | } 263 | - (void)RotationAction:(UIGestureRecognizer *)sender 264 | { 265 | UIRotationGestureRecognizer *recognizer = (UIRotationGestureRecognizer *) sender; 266 | static CGFloat rot=0; 267 | //float RotationinDegrees = recognizer.rotation * (180/M_PI); 268 | if(sender.state == UIGestureRecognizerStateBegan) 269 | { 270 | rot = recognizer.rotation; 271 | } 272 | 273 | if(sender.state == UIGestureRecognizerStateBegan || sender.state == UIGestureRecognizerStateChanged) 274 | { 275 | self.imgView.transform = CGAffineTransformRotate(self.imgView.transform, recognizer.rotation - rot); 276 | // NSLog(@"imgViewFrame : %@",NSStringFromCGRect(self.imgView.frame)); 277 | rot =recognizer.rotation; 278 | 279 | } 280 | 281 | if (sender.state == UIGestureRecognizerStateEnded) { 282 | if(self.imgView.frame.size.width < _cropperView.frame.size.width || self.imgView.frame.size.height < _cropperView.frame.size.height) 283 | { 284 | double scale = MAX(_cropperView.frame.size.width/self.imgView.frame.size.width,_cropperView.frame.size.height/self.imgView.frame.size.height) + 0.01; 285 | 286 | self.imgView.transform = CGAffineTransformScale(self.imgView.transform,scale, scale); 287 | } 288 | } 289 | 290 | } 291 | - (void)DoubleTapAction:(UIGestureRecognizer *)sender 292 | { 293 | [UIView animateWithDuration:0.2f animations:^(void) { 294 | 295 | self.imgView.center = _cropperView.center; 296 | 297 | } ]; 298 | } 299 | 300 | 301 | - (void) setupGestureRecognizer 302 | { 303 | UIPinchGestureRecognizer *pinchGestureRecognizer = [[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(zoomAction:)] autorelease]; 304 | [pinchGestureRecognizer setDelegate:self]; 305 | 306 | UIPanGestureRecognizer *panGestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)] autorelease]; 307 | [panGestureRecognizer setMinimumNumberOfTouches:1]; 308 | [panGestureRecognizer setMaximumNumberOfTouches:1]; 309 | [panGestureRecognizer setDelegate:self]; 310 | 311 | UITapGestureRecognizer *doubleTapGestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(DoubleTapAction:)] autorelease]; 312 | [doubleTapGestureRecognizer setDelegate:self]; 313 | doubleTapGestureRecognizer.numberOfTapsRequired =2; 314 | 315 | UIRotationGestureRecognizer *rotationGestureRecognizer = [[[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(RotationAction:)] autorelease]; 316 | [rotationGestureRecognizer setDelegate:self]; 317 | 318 | [self addGestureRecognizer:pinchGestureRecognizer]; 319 | [self addGestureRecognizer:panGestureRecognizer]; 320 | [self addGestureRecognizer:doubleTapGestureRecognizer]; 321 | [self addGestureRecognizer:rotationGestureRecognizer]; 322 | 323 | } 324 | 325 | - (UIImage*) getCroppedImage 326 | { 327 | double zoomScale = [[self.imgView.layer valueForKeyPath:@"transform.scale.x"] floatValue]; 328 | double rotationZ = [[self.imgView.layer valueForKeyPath:@"transform.rotation.z"] floatValue]; 329 | 330 | CGPoint cropperViewOrigin = CGPointMake( (_cropperView.frame.origin.x - _imgView.frame.origin.x) *1/zoomScale , 331 | ( _cropperView.frame.origin.y - _imgView.frame.origin.y ) * 1/zoomScale 332 | ); 333 | CGSize cropperViewSize = CGSizeMake(_cropperView.frame.size.width * (1/zoomScale) ,_cropperView.frame.size.height * (1/zoomScale)); 334 | 335 | CGRect CropinView = CGRectMake(cropperViewOrigin.x, cropperViewOrigin.y, cropperViewSize.width , cropperViewSize.height); 336 | 337 | NSLog(@"CropinView : %@",NSStringFromCGRect(CropinView)); 338 | 339 | CGSize CropinViewSize = CGSizeMake((CropinView.size.width*(1/_imageScale)),(CropinView.size.height*(1/_imageScale))); 340 | 341 | 342 | if((NSInteger)CropinViewSize.width % 2 == 1) 343 | { 344 | CropinViewSize.width = ceil(CropinViewSize.width); 345 | } 346 | if((NSInteger)CropinViewSize.height % 2 == 1) 347 | { 348 | CropinViewSize.height = ceil(CropinViewSize.height); 349 | } 350 | 351 | CGRect CropRectinImage = CGRectMake((NSInteger)(CropinView.origin.x * (1/_imageScale)) ,(NSInteger)( CropinView.origin.y * (1/_imageScale)), (NSInteger)CropinViewSize.width,(NSInteger)CropinViewSize.height); 352 | 353 | UIImage *rotInputImage = [[_inputImage fixOrientation] imageRotatedByRadians:rotationZ]; 354 | UIImage *newImage = [rotInputImage cropImage:CropRectinImage]; 355 | 356 | if(newImage.size.width != _realCropsize.width) 357 | { 358 | newImage = [newImage resizedImageToFitInSize:_realCropsize scaleIfSmaller:YES]; 359 | } 360 | 361 | return newImage; 362 | } 363 | - (BOOL) saveCroppedImage:(NSString *) path 364 | { 365 | return [UIImagePNGRepresentation([self getCroppedImage]) writeToFile:path atomically:YES]; 366 | } 367 | - (void) actionRotate 368 | { 369 | [UIView animateWithDuration:0.15 animations:^{ 370 | 371 | self.imgView.transform = CGAffineTransformRotate(self.imgView.transform,M_PI/2); 372 | 373 | if(self.imgView.frame.size.width < _cropperView.frame.size.width || self.imgView.frame.size.height < _cropperView.frame.size.height) 374 | { 375 | double scale = MAX(_cropperView.frame.size.width/self.imgView.frame.size.width,_cropperView.frame.size.height/self.imgView.frame.size.height) + 0.01; 376 | 377 | self.imgView.transform = CGAffineTransformScale(self.imgView.transform,scale, scale); 378 | 379 | } 380 | }]; 381 | } 382 | 383 | - (void) actionRestore 384 | { 385 | [UIView animateWithDuration:0.2 animations:^{ 386 | self.imgView.transform = CGAffineTransformIdentity; 387 | self.imgView.center = _cropperView.center; 388 | }]; 389 | } 390 | 391 | - (void)dealloc { 392 | [_imgView release]; 393 | [_inputImage release]; 394 | [_cropperView release]; 395 | [super ah_dealloc]; 396 | } 397 | 398 | @end 399 | -------------------------------------------------------------------------------- /UzysImageCropper/Library/UzysImageCropperViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysImageCropperViewController.h 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import 9 | #import "UzysImageCropper.h" 10 | #import "ARCHelper.h" 11 | 12 | @protocol UzysImageCropperDelegate; 13 | @class UzysImageCropper; 14 | 15 | @interface UzysImageCropperViewController : UIViewController 16 | 17 | @property (nonatomic,strong) UzysImageCropper *cropperView; 18 | @property (nonatomic, assign) id delegate; 19 | - (id)initWithImage:(UIImage*)newImage andframeSize:(CGSize)frameSize andcropSize:(CGSize)cropSize; 20 | - (void)actionRotation:(id) senders; 21 | @end 22 | 23 | @protocol UzysImageCropperDelegate 24 | - (void)imageCropper:(UzysImageCropperViewController *)cropper didFinishCroppingWithImage:(UIImage *)image; 25 | - (void)imageCropperDidCancel:(UzysImageCropperViewController *)cropper; 26 | @end 27 | -------------------------------------------------------------------------------- /UzysImageCropper/Library/UzysImageCropperViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysImageCropperViewController.m 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import "UzysImageCropperViewController.h" 9 | #import "UIImage-Extension.h" 10 | 11 | @implementation UzysImageCropperViewController 12 | @synthesize cropperView,delegate; 13 | 14 | - (id)initWithImage:(UIImage*)newImage andframeSize:(CGSize)frameSize andcropSize:(CGSize)cropSize 15 | { 16 | self = [super init]; 17 | 18 | if (self) { 19 | 20 | if(newImage.size.width <= cropSize.width || newImage.size.height <= cropSize.height) 21 | { 22 | NSLog(@"Image Size is smaller than cropSize"); 23 | newImage = [newImage resizedImageToFitInSize:CGSizeMake(cropSize.width*1.3, cropSize.height*1.3) scaleIfSmaller:YES]; 24 | NSLog(@"newImage Size %@",NSStringFromCGSize(newImage.size)); 25 | } 26 | self.view.backgroundColor = [UIColor blackColor]; 27 | cropperView = [[UzysImageCropper alloc] 28 | initWithImage:newImage 29 | andframeSize:frameSize 30 | andcropSize:cropSize]; 31 | 32 | [self.view addSubview:cropperView]; 33 | UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)]; 34 | [navigationBar setBarStyle:UIBarStyleBlack]; 35 | [navigationBar setTranslucent:YES]; 36 | 37 | UINavigationItem *aNavigationItem = [[UINavigationItem alloc] initWithTitle:@"Image Crop"]; 38 | [aNavigationItem setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelCropping)] autorelease]]; 39 | [aNavigationItem setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(finishCropping)] autorelease]]; 40 | 41 | [navigationBar setItems:[NSArray arrayWithObject:aNavigationItem]]; 42 | 43 | [aNavigationItem release]; 44 | 45 | [[self view] addSubview:navigationBar]; 46 | 47 | [navigationBar release]; 48 | 49 | UIButton *btn_rotation = [UIButton buttonWithType:UIButtonTypeCustom]; 50 | [btn_rotation setFrame:CGRectMake(0 , cropperView.frame.size.height - 32 , 44, 32)]; 51 | [btn_rotation addTarget:self action:@selector(actionRotation:) forControlEvents:UIControlEventTouchUpInside]; 52 | [btn_rotation setImage:[UIImage imageNamed:@"nc_crop_rotate_btn.png"] forState:UIControlStateNormal]; 53 | [btn_rotation setImage:[UIImage imageNamed:@"nc_crop_rotate_btn_h.png"] forState:UIControlStateHighlighted]; 54 | btn_rotation.alpha = 0.7; 55 | [self.view addSubview:btn_rotation]; 56 | 57 | UIButton *btn_restore = [UIButton buttonWithType:UIButtonTypeCustom]; 58 | [btn_restore setFrame:CGRectMake(cropperView.frame.size.width -44 , cropperView.frame.size.height - 33 , 44, 33)]; 59 | [btn_restore addTarget:self action:@selector(actionRestore:) forControlEvents:UIControlEventTouchUpInside]; 60 | [btn_restore setImage:[UIImage imageNamed:@"nc_crop_reset_btn.png"] forState:UIControlStateNormal]; 61 | [btn_restore setImage:[UIImage imageNamed:@"nc_crop_reset_btn_h.png"] forState:UIControlStateHighlighted]; 62 | btn_restore.alpha = 0.7; 63 | [self.view addSubview:btn_restore]; 64 | } 65 | 66 | return self; 67 | 68 | } 69 | -(void) actionRestore:(id) senders 70 | { 71 | [cropperView actionRestore]; 72 | } 73 | -(void) actionRotation:(id) senders 74 | { 75 | [cropperView actionRotate]; 76 | } 77 | - (void)cancelCropping 78 | { 79 | [delegate imageCropperDidCancel:self]; 80 | } 81 | 82 | - (void)finishCropping 83 | { 84 | //NSLog(@"%@",@"ImageCropper finish cropping end"); 85 | UIImage *cropped =[cropperView getCroppedImage]; 86 | [delegate imageCropper:self didFinishCroppingWithImage:cropped]; 87 | } 88 | 89 | - (void)didReceiveMemoryWarning 90 | { 91 | // Releases the view if it doesn't have a superview. 92 | [super didReceiveMemoryWarning]; 93 | // Release any cached data, images, etc that aren't in use. 94 | } 95 | 96 | #pragma mark - View lifecycle 97 | // Implement loadView to create a view hierarchy programmatically, without using a nib. 98 | //- (void)loadView 99 | //{ 100 | // 101 | // 102 | //} 103 | 104 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 105 | - (void)viewDidLoad 106 | { 107 | [super viewDidLoad]; 108 | } 109 | 110 | - (void)viewDidUnload 111 | { 112 | [super viewDidUnload]; 113 | self.cropperView = nil; 114 | 115 | // Release any retained subviews of the main view. 116 | // e.g. self.myOutlet = nil; 117 | } 118 | 119 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 120 | { 121 | // Return YES for supported orientations 122 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 123 | } 124 | 125 | - (void)dealloc { 126 | [cropperView release]; 127 | [super ah_dealloc]; 128 | } 129 | @end 130 | -------------------------------------------------------------------------------- /UzysImageCropper/Resource/nc_crop_reset_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uzysjung/UzysImageCropper/b76c85ed9d7cff27230a080ac77fe81980d50dd3/UzysImageCropper/Resource/nc_crop_reset_btn.png -------------------------------------------------------------------------------- /UzysImageCropper/Resource/nc_crop_reset_btn_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uzysjung/UzysImageCropper/b76c85ed9d7cff27230a080ac77fe81980d50dd3/UzysImageCropper/Resource/nc_crop_reset_btn_h.png -------------------------------------------------------------------------------- /UzysImageCropper/Resource/nc_crop_rotate_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uzysjung/UzysImageCropper/b76c85ed9d7cff27230a080ac77fe81980d50dd3/UzysImageCropper/Resource/nc_crop_rotate_btn.png -------------------------------------------------------------------------------- /UzysImageCropper/Resource/nc_crop_rotate_btn_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uzysjung/UzysImageCropper/b76c85ed9d7cff27230a080ac77fe81980d50dd3/UzysImageCropper/Resource/nc_crop_rotate_btn_h.png -------------------------------------------------------------------------------- /UzysImageCropper/UzysImageCropper-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | com.uzys.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /UzysImageCropper/UzysImageCropper-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'UzysImageCropper' target in the 'UzysImageCropper' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /UzysImageCropper/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import 9 | #import "UzysImageCropperViewController.h" 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @property (nonatomic,retain) UIImageView *resultImgView; 14 | @property (nonatomic,retain) UzysImageCropperViewController *imgCropperViewController; 15 | @property (nonatomic,retain) UIImagePickerController *picker; 16 | @end 17 | -------------------------------------------------------------------------------- /UzysImageCropper/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 12. 13.. 6 | // 7 | 8 | #import "ViewController.h" 9 | #import 10 | @implementation ViewController 11 | 12 | - (void)didReceiveMemoryWarning 13 | { 14 | [super didReceiveMemoryWarning]; 15 | // Release any cached data, images, etc that aren't in use. 16 | } 17 | 18 | #pragma mark - View lifecycle 19 | - (void) cropButton 20 | { 21 | UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Image Picker" delegate:self cancelButtonTitle:nil destructiveButtonTitle:@"Close" otherButtonTitles:@"Camera",@"Library", nil]; 22 | 23 | [actionSheet showInView:self.view]; 24 | [actionSheet reloadInputViews]; 25 | 26 | } 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | // Do any additional setup after loading the view, typically from a nib. 31 | 32 | [self.view setFrame:[UIScreen mainScreen].applicationFrame]; 33 | self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 34 | 35 | UIButton *cropper = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 36 | [cropper setFrame:CGRectMake(110, self.view.frame.size.height - 40, 100, 30)]; 37 | [cropper setTitle:@"Crop" forState:UIControlStateNormal]; 38 | [cropper addTarget:self action:@selector(cropButton) forControlEvents:UIControlEventTouchUpInside]; 39 | [self.view addSubview:cropper]; 40 | } 41 | 42 | - (void)viewDidUnload 43 | { 44 | self.imgCropperViewController = nil; 45 | self.picker = nil; 46 | self.resultImgView = nil; 47 | [super viewDidUnload]; 48 | // Release any retained subviews of the main view. 49 | // e.g. self.myOutlet = nil; 50 | } 51 | 52 | - (void)dealloc 53 | { 54 | [_picker release]; 55 | [_resultImgView release]; 56 | [_imgCropperViewController release]; 57 | [super ah_dealloc]; 58 | } 59 | - (void)viewWillAppear:(BOOL)animated 60 | { 61 | [super viewWillAppear:animated]; 62 | [[UIApplication sharedApplication] setStatusBarHidden:NO]; 63 | } 64 | - (void)viewDidAppear:(BOOL)animated 65 | { 66 | [super viewDidAppear:animated]; 67 | } 68 | 69 | - (void)viewWillDisappear:(BOOL)animated 70 | { 71 | [super viewWillDisappear:animated]; 72 | } 73 | 74 | - (void)viewDidDisappear:(BOOL)animated 75 | { 76 | [super viewDidDisappear:animated]; 77 | } 78 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 79 | { 80 | // Return YES for supported orientations 81 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 82 | } 83 | 84 | #pragma mark - UzysImageCropperDelegate 85 | 86 | - (void)imageCropper:(UzysImageCropperViewController *)cropper didFinishCroppingWithImage:(UIImage *)image 87 | { 88 | if(self.resultImgView) 89 | [self.resultImgView removeFromSuperview]; 90 | 91 | self.resultImgView = [[[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 310, 310)] autorelease]; 92 | self.resultImgView.image = image; 93 | self.resultImgView.backgroundColor = [UIColor darkGrayColor]; 94 | self.resultImgView.contentMode = UIViewContentModeScaleAspectFit; 95 | [self.view addSubview:self.resultImgView]; 96 | 97 | NSLog(@"cropping Image Size : %@", NSStringFromCGSize(image.size)); 98 | [self dismissViewControllerAnimated:YES completion:nil]; 99 | } 100 | 101 | - (void)imageCropperDidCancel:(UzysImageCropperViewController *)cropper 102 | { 103 | [_picker dismissViewControllerAnimated:YES completion:nil]; 104 | } 105 | 106 | #pragma mark - UIImagePickerViewController 107 | 108 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 109 | 110 | UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 111 | NSLog(@"original Image Size : %@", NSStringFromCGSize(image.size)); 112 | _imgCropperViewController = [[UzysImageCropperViewController alloc] initWithImage:image andframeSize:picker.view.frame.size andcropSize:CGSizeMake(1024, 580)]; 113 | _imgCropperViewController.delegate = self; 114 | [picker presentViewController:_imgCropperViewController animated:YES completion:nil]; 115 | [_imgCropperViewController release]; 116 | } 117 | 118 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 119 | [self dismissViewControllerAnimated:YES completion:nil]; 120 | } 121 | 122 | #pragma mark - UIActionSheetDelegate 123 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 124 | { 125 | 126 | switch (buttonIndex) 127 | { 128 | case 1: 129 | { 130 | #if TARGET_IPHONE_SIMULATOR 131 | UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"demo" message:@"camera not available"delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil]; 132 | [alert show]; 133 | [alert release]; 134 | #elif TARGET_OS_IPHONE 135 | [[UIApplication sharedApplication] setStatusBarHidden:YES]; 136 | self.picker=[[[UIImagePickerController alloc]init] autorelease]; 137 | self.picker.sourceType = UIImagePickerControllerSourceTypeCamera; 138 | self.picker.delegate = self; 139 | [self presentViewController:self.picker animated:YES completion:nil]; 140 | #endif 141 | } 142 | break; 143 | case 2: 144 | { 145 | [[UIApplication sharedApplication] setStatusBarHidden:YES]; 146 | self.picker=[[[UIImagePickerController alloc]init] autorelease]; 147 | self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 148 | self.picker.delegate = self; 149 | [self presentViewController:self.picker animated:YES completion:nil]; 150 | } 151 | break; 152 | } 153 | 154 | } 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /UzysImageCropper/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /UzysImageCropper/en.lproj/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1536 5 | 12C60 6 | 2844 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1930 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 308 36 | {{0, 20}, {320, 548}} 37 | 38 | 39 | 40 | 3 41 | MC43NQA 42 | 43 | 2 44 | 45 | 46 | NO 47 | NO 48 | 49 | 50 | IBUISimulatedFreeformSizeMetricsSentinel 51 | Freeform 52 | 53 | IBCocoaTouchFramework 54 | 55 | 56 | 57 | 58 | 59 | 60 | view 61 | 62 | 63 | 64 | 7 65 | 66 | 67 | 68 | 69 | 70 | 0 71 | 72 | 73 | 74 | 75 | 76 | -1 77 | 78 | 79 | File's Owner 80 | 81 | 82 | -2 83 | 84 | 85 | 86 | 87 | 6 88 | 89 | 90 | 91 | 92 | 93 | 94 | ViewController 95 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 96 | UIResponder 97 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 98 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 99 | 100 | 101 | 102 | 103 | 104 | 7 105 | 106 | 107 | 108 | 109 | ViewController 110 | UIViewController 111 | 112 | IBProjectSource 113 | ./Classes/ViewController.h 114 | 115 | 116 | 117 | 118 | 0 119 | IBCocoaTouchFramework 120 | YES 121 | 3 122 | 1930 123 | 124 | 125 | -------------------------------------------------------------------------------- /UzysImageCropper/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // UzysImageCropper 4 | // 5 | // Created by Uzys on 11. 11. 22.. 6 | // 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 16 | } 17 | } 18 | --------------------------------------------------------------------------------