├── .github └── workflows │ └── main.yml ├── .gitignore ├── Example ├── Podfile ├── Podfile.lock ├── RSKImageCropperExample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── RSKImageCropperExample.xcscheme ├── RSKImageCropperExample.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── RSKImageCropperExample │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── photo.imageset │ │ │ ├── Contents.json │ │ │ └── photo.png │ │ └── photo_2.imageset │ │ │ ├── Contents.json │ │ │ └── photo_2.png │ ├── LaunchScreen.xib │ ├── RSKAppDelegate.h │ ├── RSKAppDelegate.m │ ├── RSKExampleViewController.h │ ├── RSKExampleViewController.m │ ├── RSKImageCropperExample-Info.plist │ ├── RSKImageCropperExample-Prefix.pch │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── RSKImageCropperExampleTests │ ├── RSKImageCropViewControllerTests.m │ ├── RSKImageCropperExample-Prefix.pch │ ├── RSKImageCropperExampleTests-Info.plist │ ├── RSKImageCropperPerformanceTests.m │ ├── RSKImageScrollViewTests.m │ ├── RSKTouchViewTests.m │ ├── ReferenceImages │ ├── RSKImageCropViewControllerSpec │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationDown@3x.png │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationDownMirrored@3x.png │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationLeft@3x.png │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationLeftMirrored@3x.png │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationRight@3x.png │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationRightMirrored@3x.png │ │ ├── crop_image_crop_image_with_any_image_orientation_UIImageOrientationUpMirrored@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_all_properties_are_default@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_content_offset_is_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_all_properties_are_default@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_content_offset_are_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_all_properties_are_default@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_content_offset_are_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png │ │ ├── crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png │ │ ├── crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCircle@3x.png │ │ ├── crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCustom@3x.png │ │ ├── crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeSquare@3x.png │ │ ├── crop_view_landscape_stroke_of_the_mask_looks_right_when_storked_outline_is_visible@3x.png │ │ ├── crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCircle@3x.png │ │ ├── crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCustom@3x.png │ │ ├── crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeSquare@3x.png │ │ ├── crop_view_portrait_stroke_of_the_mask_looks_right_when_stroked_outline_is_visible@3x.png │ │ └── zoomToRect_zooms_to_a_specific_area_of_the_image@3x.png │ └── RSKImageScrollViewSpec │ │ ├── visuals_looks_right_by_default@3x.png │ │ ├── visuals_looks_right_with_minimum_zoom_scale@3x.png │ │ └── visuals_looks_right_with_minimum_zoom_scale_and_when_aspectFill_is_YES@3x.png │ └── en.lproj │ └── InfoPlist.strings ├── Framework └── Info.plist ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Makefile ├── Package.swift ├── README.md ├── RSKImageCropper.podspec ├── RSKImageCropper.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── RSKImageCropper.xcscheme ├── RSKImageCropper.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── RSKImageCropper ├── CGGeometry+RSKImageCropper.h ├── CGGeometry+RSKImageCropper.m ├── RSKImageCropViewController+Protected.h ├── RSKImageCropViewController.h ├── RSKImageCropViewController.m ├── RSKImageCropper.h ├── RSKImageCropper.modulemap ├── RSKImageCropperStrings.bundle │ ├── ar.lproj │ │ └── RSKImageCropper.strings │ ├── bg.lproj │ │ └── RSKImageCropper.strings │ ├── bs.lproj │ │ └── RSKImageCropper.strings │ ├── ca.lproj │ │ └── RSKImageCropper.strings │ ├── cs.lproj │ │ └── RSKImageCropper.strings │ ├── da.lproj │ │ └── RSKImageCropper.strings │ ├── de.lproj │ │ └── RSKImageCropper.strings │ ├── el.lproj │ │ └── RSKImageCropper.strings │ ├── en.lproj │ │ └── RSKImageCropper.strings │ ├── es.lproj │ │ └── RSKImageCropper.strings │ ├── et.lproj │ │ └── RSKImageCropper.strings │ ├── fa.lproj │ │ └── RSKImageCropper.strings │ ├── fi.lproj │ │ └── RSKImageCropper.strings │ ├── fil.lproj │ │ └── RSKImageCropper.strings │ ├── fr.lproj │ │ └── RSKImageCropper.strings │ ├── he.lproj │ │ └── RSKImageCropper.strings │ ├── hi.lproj │ │ └── RSKImageCropper.strings │ ├── hr.lproj │ │ └── RSKImageCropper.strings │ ├── hu.lproj │ │ └── RSKImageCropper.strings │ ├── id.lproj │ │ └── RSKImageCropper.strings │ ├── it.lproj │ │ └── RSKImageCropper.strings │ ├── ja.lproj │ │ └── RSKImageCropper.strings │ ├── ko.lproj │ │ └── RSKImageCropper.strings │ ├── lt.lproj │ │ └── RSKImageCropper.strings │ ├── lv.lproj │ │ └── RSKImageCropper.strings │ ├── mk.lproj │ │ └── RSKImageCropper.strings │ ├── ms.lproj │ │ └── RSKImageCropper.strings │ ├── nb.lproj │ │ └── RSKImageCropper.strings │ ├── nl.lproj │ │ └── RSKImageCropper.strings │ ├── pl.lproj │ │ └── RSKImageCropper.strings │ ├── pt.lproj │ │ └── RSKImageCropper.strings │ ├── pt_BR.lproj │ │ └── RSKImageCropper.strings │ ├── pt_PT.lproj │ │ └── RSKImageCropper.strings │ ├── ro.lproj │ │ └── RSKImageCropper.strings │ ├── ru.lproj │ │ └── RSKImageCropper.strings │ ├── sk.lproj │ │ └── RSKImageCropper.strings │ ├── sl.lproj │ │ └── RSKImageCropper.strings │ ├── sr.lproj │ │ └── RSKImageCropper.strings │ ├── sv.lproj │ │ └── RSKImageCropper.strings │ ├── th.lproj │ │ └── RSKImageCropper.strings │ ├── tr.lproj │ │ └── RSKImageCropper.strings │ ├── uk.lproj │ │ └── RSKImageCropper.strings │ ├── vi.lproj │ │ └── RSKImageCropper.strings │ ├── zh-Hans.lproj │ │ └── RSKImageCropper.strings │ ├── zh-Hant.lproj │ │ └── RSKImageCropper.strings │ └── zh.lproj │ │ └── RSKImageCropper.strings ├── RSKImageScrollView.h ├── RSKImageScrollView.m ├── RSKImageScrollViewDelegate.h ├── RSKInternalUtility.h ├── RSKInternalUtility.m ├── RSKTouchView.h ├── RSKTouchView.m ├── UIImage+RSKImageCropper.h ├── UIImage+RSKImageCropper.m └── include │ └── RSKImageCropper │ ├── CGGeometry+RSKImageCropper.h │ ├── RSKImageCropViewController+Protected.h │ ├── RSKImageCropViewController.h │ ├── RSKImageScrollView.h │ ├── RSKImageScrollViewDelegate.h │ ├── RSKInternalUtility.h │ ├── RSKTouchView.h │ └── UIImage+RSKImageCropper.h └── Screenshot.png /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | branches: [master] 5 | workflow_dispatch: 6 | jobs: 7 | iOS: 8 | runs-on: macos-13 9 | env: 10 | DEVELOPER_DIR: '/Applications/Xcode_15.1.app/Contents/Developer' 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: ruby/setup-ruby@v1 14 | with: 15 | ruby-version: '3.2.2' 16 | bundler-cache: true 17 | - uses: actions/cache@v4 18 | with: 19 | path: Example/Pods 20 | key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} 21 | restore-keys: | 22 | ${{ runner.os }}-pods- 23 | - name: Delete Xcode.app 24 | run: sudo rm -rf /Applications/Xcode.app 25 | - name: Install Pods 26 | run: bundle exec pod install --repo-update --project-directory=Example 27 | - name: Test 28 | run: make test 29 | - name: Lint 30 | run: make lint 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | # 3 | .DS_Store 4 | 5 | 6 | # Build generated 7 | # 8 | build/ 9 | DerivedData 10 | 11 | 12 | # Various settings 13 | # 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata 23 | 24 | 25 | # Other 26 | # 27 | *.xccheckout 28 | *.moved-aside 29 | *.xcuserstate 30 | *.xcscmblueprint 31 | 32 | 33 | # Obj-C/Swift specific 34 | # 35 | *.hmap 36 | *.ipa 37 | *.gcno 38 | *.gcda 39 | 40 | 41 | # Binaries 42 | # 43 | *.zip 44 | 45 | 46 | # Carthage 47 | # 48 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 49 | # Carthage/Checkouts 50 | 51 | Carthage/Build 52 | 53 | 54 | # CocoaPods 55 | # 56 | # We recommend against adding the Pods directory to your .gitignore. However 57 | # you should judge for yourself, the pros and cons are mentioned at: 58 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 59 | # 60 | Pods/ 61 | 62 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://cdn.cocoapods.org/' 2 | 3 | platform :ios, '12.0' 4 | 5 | inhibit_all_warnings! 6 | 7 | target 'RSKImageCropperExampleTests' do 8 | pod 'Expecta+Snapshots', '3.1.1' 9 | pod 'Specta', '1.0.7' 10 | pod 'Expecta', '1.0.6' 11 | pod 'OCMock', '3.9.1' 12 | 13 | post_install do |installer| 14 | installer.pods_project.targets.each do |target| 15 | target.build_configurations.each do |config| 16 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Expecta (1.0.6) 3 | - "Expecta+Snapshots (3.1.1)": 4 | - Expecta (~> 1.0) 5 | - FBSnapshotTestCase/Core (~> 2.0) 6 | - Specta (~> 1.0) 7 | - FBSnapshotTestCase/Core (2.1.4) 8 | - OCMock (3.9.1) 9 | - Specta (1.0.7) 10 | 11 | DEPENDENCIES: 12 | - Expecta (= 1.0.6) 13 | - "Expecta+Snapshots (= 3.1.1)" 14 | - OCMock (= 3.9.1) 15 | - Specta (= 1.0.7) 16 | 17 | SPEC REPOS: 18 | trunk: 19 | - Expecta 20 | - "Expecta+Snapshots" 21 | - FBSnapshotTestCase 22 | - OCMock 23 | - Specta 24 | 25 | SPEC CHECKSUMS: 26 | Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 27 | "Expecta+Snapshots": dcff217eef506dabd6dfdc7864ea2da321fafbb8 28 | FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a 29 | OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 30 | Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 31 | 32 | PODFILE CHECKSUM: e2296c0f63c75329f0583a4252b3dfcb582ff009 33 | 34 | COCOAPODS: 1.16.2 35 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample.xcodeproj/xcshareddata/xcschemes/RSKImageCropperExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/Images.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 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/Images.xcassets/photo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "photo.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/Images.xcassets/photo.imageset/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExample/Images.xcassets/photo.imageset/photo.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/Images.xcassets/photo_2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "photo_2.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/Images.xcassets/photo_2.imageset/photo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExample/Images.xcassets/photo_2.imageset/photo_2.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/RSKAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKAppDelegate.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | @interface RSKAppDelegate : UIResponder 28 | 29 | @property (strong, nonatomic) UIWindow *window; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/RSKAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKAppDelegate.m 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "RSKAppDelegate.h" 26 | #import "RSKExampleViewController.h" 27 | 28 | @implementation RSKAppDelegate 29 | 30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 31 | { 32 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 33 | 34 | RSKExampleViewController *sampleVC = [[RSKExampleViewController alloc] init]; 35 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:sampleVC]; 36 | self.window.rootViewController = navController; 37 | 38 | self.window.backgroundColor = [UIColor whiteColor]; 39 | [self.window makeKeyAndVisible]; 40 | return YES; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/RSKExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKExampleViewController.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | @interface RSKExampleViewController : UIViewController 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/RSKExampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKExampleViewController.m 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "RSKExampleViewController.h" 26 | #import "RSKImageCropper.h" 27 | 28 | static const CGFloat kPhotoDiameter = 130.0f; 29 | static const CGFloat kPhotoFrameViewPadding = 2.0f; 30 | 31 | @interface RSKExampleViewController () 32 | 33 | @property (strong, nonatomic) UIView *photoFrameView; 34 | @property (strong, nonatomic) UIButton *addPhotoButton; 35 | @property (assign, nonatomic) BOOL didSetupConstraints; 36 | 37 | @end 38 | 39 | @implementation RSKExampleViewController 40 | 41 | #pragma mark - Lifecycle 42 | 43 | - (void)viewDidLoad 44 | { 45 | [super viewDidLoad]; 46 | 47 | if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { 48 | self.edgesForExtendedLayout = UIRectEdgeNone; 49 | } 50 | 51 | self.navigationItem.title = @"RSKImageCropper"; 52 | 53 | // --------------------------- 54 | // Add the frame of the photo. 55 | // --------------------------- 56 | 57 | self.photoFrameView = [[UIView alloc] init]; 58 | self.photoFrameView.backgroundColor = [UIColor colorWithRed:182/255.0f green:182/255.0f blue:187/255.0f alpha:1.0f]; 59 | self.photoFrameView.translatesAutoresizingMaskIntoConstraints = NO; 60 | self.photoFrameView.layer.masksToBounds = YES; 61 | self.photoFrameView.layer.cornerRadius = (kPhotoDiameter + kPhotoFrameViewPadding) / 2; 62 | [self.view addSubview:self.photoFrameView]; 63 | 64 | // --------------------------- 65 | // Add the button "add photo". 66 | // --------------------------- 67 | 68 | self.addPhotoButton = [[UIButton alloc] init]; 69 | self.addPhotoButton.backgroundColor = [UIColor whiteColor]; 70 | self.addPhotoButton.translatesAutoresizingMaskIntoConstraints = NO; 71 | self.addPhotoButton.layer.masksToBounds = YES; 72 | self.addPhotoButton.layer.cornerRadius = kPhotoDiameter / 2; 73 | self.addPhotoButton.imageView.contentMode = UIViewContentModeScaleAspectFit; 74 | self.addPhotoButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 75 | self.addPhotoButton.titleLabel.textAlignment = NSTextAlignmentCenter; 76 | [self.addPhotoButton setTitle:@"add\nphoto" forState:UIControlStateNormal]; 77 | [self.addPhotoButton setTitleColor:[UIColor colorWithRed:0/255.0f green:122/255.0f blue:255/255.0f alpha:1.0f] forState:UIControlStateNormal]; 78 | [self.addPhotoButton addTarget:self action:@selector(onAddPhotoButtonTouch:) forControlEvents:UIControlEventTouchUpInside]; 79 | [self.view addSubview:self.addPhotoButton]; 80 | 81 | // ---------------- 82 | // Add constraints. 83 | // ---------------- 84 | 85 | [self.view setNeedsUpdateConstraints]; 86 | } 87 | 88 | - (void)updateViewConstraints 89 | { 90 | [super updateViewConstraints]; 91 | 92 | if (self.didSetupConstraints) { 93 | return; 94 | } 95 | 96 | // --------------------------- 97 | // The frame of the photo. 98 | // --------------------------- 99 | 100 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.photoFrameView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual 101 | toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f 102 | constant:(kPhotoDiameter + kPhotoFrameViewPadding)]; 103 | [self.photoFrameView addConstraint:constraint]; 104 | 105 | constraint = [NSLayoutConstraint constraintWithItem:self.photoFrameView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual 106 | toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f 107 | constant:(kPhotoDiameter + kPhotoFrameViewPadding)]; 108 | [self.photoFrameView addConstraint:constraint]; 109 | 110 | constraint = [NSLayoutConstraint constraintWithItem:self.photoFrameView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual 111 | toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f 112 | constant:0.0f]; 113 | [self.view addConstraint:constraint]; 114 | 115 | constraint = [NSLayoutConstraint constraintWithItem:self.photoFrameView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual 116 | toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0f 117 | constant:0.0f]; 118 | [self.view addConstraint:constraint]; 119 | 120 | // --------------------------- 121 | // The button "add photo". 122 | // --------------------------- 123 | 124 | constraint = [NSLayoutConstraint constraintWithItem:self.addPhotoButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual 125 | toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f 126 | constant:kPhotoDiameter]; 127 | [self.addPhotoButton addConstraint:constraint]; 128 | 129 | constraint = [NSLayoutConstraint constraintWithItem:self.addPhotoButton attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual 130 | toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f 131 | constant:kPhotoDiameter]; 132 | [self.addPhotoButton addConstraint:constraint]; 133 | 134 | constraint = [NSLayoutConstraint constraintWithItem:self.addPhotoButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual 135 | toItem:self.photoFrameView attribute:NSLayoutAttributeCenterX multiplier:1.0f 136 | constant:0.0f]; 137 | [self.view addConstraint:constraint]; 138 | 139 | constraint = [NSLayoutConstraint constraintWithItem:self.addPhotoButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual 140 | toItem:self.photoFrameView attribute:NSLayoutAttributeCenterY multiplier:1.0f 141 | constant:0.0f]; 142 | [self.view addConstraint:constraint]; 143 | 144 | self.didSetupConstraints = YES; 145 | } 146 | 147 | #pragma mark - Action handling 148 | 149 | - (void)onAddPhotoButtonTouch:(UIButton *)sender 150 | { 151 | UIImage *photo = [UIImage imageNamed:@"photo"]; 152 | RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:photo cropMode:RSKImageCropModeCircle]; 153 | imageCropVC.delegate = self; 154 | [self.navigationController pushViewController:imageCropVC animated:YES]; 155 | } 156 | 157 | #pragma mark - RSKImageCropViewControllerDelegate 158 | 159 | - (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller 160 | { 161 | [self.navigationController popViewControllerAnimated:YES]; 162 | } 163 | 164 | - (void)imageCropViewController:(RSKImageCropViewController *)controller didCropImage:(UIImage *)croppedImage usingCropRect:(CGRect)cropRect rotationAngle:(CGFloat)rotationAngle 165 | { 166 | [self.addPhotoButton setImage:croppedImage forState:UIControlStateNormal]; 167 | [self.navigationController popViewControllerAnimated:YES]; 168 | } 169 | 170 | @end 171 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/RSKImageCropperExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/RSKImageCropperExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | #import "RSKAppDelegate.h" 28 | 29 | int main(int argc, char * argv[]) 30 | { 31 | @autoreleasepool { 32 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([RSKAppDelegate class])); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/RSKImageCropperExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifndef RSKImageCropperExample_Prefix_pch 8 | #define RSKImageCropperExample_Prefix_pch 9 | 10 | #ifdef __OBJC__ 11 | #import 12 | #import 13 | #define EXP_SHORTHAND 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/RSKImageCropperExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/RSKImageCropperPerformanceTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropperPerformanceTests.m 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | #import "RSKImageCropViewController.h" 27 | 28 | @interface RSKImageCropViewController (Testing) 29 | 30 | - (void)cropImage; 31 | - (void)setRotationAngle:(CGFloat)rotationAngle; 32 | 33 | @end 34 | 35 | @interface RSKImageCropperPerformanceTests : XCTestCase 36 | 37 | @property (strong, nonatomic) RSKImageCropViewController *imageCropViewController; 38 | 39 | @end 40 | 41 | @implementation RSKImageCropperPerformanceTests 42 | 43 | - (void)setUp 44 | { 45 | [super setUp]; 46 | 47 | self.imageCropViewController = [[RSKImageCropViewController alloc] initWithImage:[UIImage imageNamed:@"photo"]]; 48 | [self.imageCropViewController view]; 49 | [self.imageCropViewController.view setNeedsUpdateConstraints]; 50 | [self.imageCropViewController.view updateConstraintsIfNeeded]; 51 | [self.imageCropViewController.view setNeedsLayout]; 52 | [self.imageCropViewController.view layoutIfNeeded]; 53 | [self.imageCropViewController beginAppearanceTransition:YES animated:NO]; 54 | [self.imageCropViewController endAppearanceTransition]; 55 | } 56 | 57 | - (void)tearDown 58 | { 59 | self.imageCropViewController = nil; 60 | 61 | [super tearDown]; 62 | } 63 | 64 | - (void)testCropImagePerformanceWithDefaultSettings 65 | { 66 | [self measureBlock:^{ 67 | [self.imageCropViewController cropImage]; 68 | }]; 69 | } 70 | 71 | - (void)testCropImagePerformanceWithCustomRotationAngle 72 | { 73 | [self.imageCropViewController setRotationAngle:M_PI_4]; 74 | [self measureBlock:^{ 75 | [self.imageCropViewController cropImage]; 76 | }]; 77 | } 78 | 79 | - (void)testCropImagePerformanceWhenApplyMaskToCroppedImage 80 | { 81 | self.imageCropViewController.applyMaskToCroppedImage = YES; 82 | [self measureBlock:^{ 83 | [self.imageCropViewController cropImage]; 84 | }]; 85 | } 86 | 87 | - (void)testCropImagePerformanceWithCustomRotationAngleAndWhenApplyMaskToCroppedImage 88 | { 89 | [self.imageCropViewController setRotationAngle:M_PI_4]; 90 | self.imageCropViewController.applyMaskToCroppedImage = YES; 91 | [self measureBlock:^{ 92 | [self.imageCropViewController cropImage]; 93 | }]; 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/RSKImageScrollViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageScrollViewTests.m 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "RSKImageScrollView.h" 26 | 27 | SpecBegin(RSKImageScrollView) 28 | 29 | __block RSKImageScrollView *imageScrollView = nil; 30 | __block UIImage *image = nil; 31 | 32 | dispatch_block_t sharedIt = ^{ 33 | imageScrollView.image = image; 34 | 35 | [imageScrollView setNeedsLayout]; 36 | [imageScrollView layoutIfNeeded]; 37 | }; 38 | 39 | before(^{ 40 | imageScrollView = [[RSKImageScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)]; 41 | imageScrollView.clipsToBounds = NO; 42 | image = [UIImage imageNamed:@"photo"]; 43 | }); 44 | 45 | describe(@"visuals", ^{ 46 | it(@"looks right by default", ^{ 47 | sharedIt(); 48 | 49 | expect(imageScrollView).haveValidSnapshot(); 50 | }); 51 | 52 | it(@"looks right with minimum zoom scale", ^{ 53 | sharedIt(); 54 | imageScrollView.zoomScale = imageScrollView.minimumZoomScale; 55 | 56 | expect(imageScrollView).haveValidSnapshot(); 57 | }); 58 | 59 | it(@"looks right with minimum zoom scale and when `aspectFill` is `YES`", ^{ 60 | imageScrollView.aspectFill = YES; 61 | sharedIt(); 62 | imageScrollView.zoomScale = imageScrollView.minimumZoomScale; 63 | 64 | expect(imageScrollView).haveValidSnapshot(); 65 | }); 66 | }); 67 | 68 | after(^{ 69 | imageScrollView = nil; 70 | image = nil; 71 | }); 72 | 73 | SpecEnd 74 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/RSKTouchViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKTouchViewTests.m 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "RSKTouchView.h" 26 | 27 | SpecBegin(RSKTouchView) 28 | 29 | __block UIView *receiver = nil; 30 | __block RSKTouchView *touchView = nil; 31 | 32 | before(^{ 33 | receiver = [[UIView alloc] init]; 34 | 35 | touchView = [[RSKTouchView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; 36 | touchView.receiver = receiver; 37 | }); 38 | 39 | describe(@"hit test", ^{ 40 | it(@"returns the receiver if the view contains the specified point", ^{ 41 | CGPoint touchPoint = CGPointMake(50, 100); 42 | UIView *farthestDescendant = [touchView hitTest:touchPoint withEvent:nil]; 43 | 44 | expect(farthestDescendant).to.equal(receiver); 45 | }); 46 | 47 | it(@"returns `nil` if the view does not contain the specified point", ^{ 48 | CGPoint touchPoint = CGPointMake(50, 520); 49 | UIView *farthestDescendant = [touchView hitTest:touchPoint withEvent:nil]; 50 | 51 | expect(farthestDescendant).to.beNil(); 52 | }); 53 | }); 54 | 55 | after(^{ 56 | receiver = nil; 57 | touchView = nil; 58 | }); 59 | 60 | SpecEnd 61 | -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationDown@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationDown@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationDownMirrored@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationDownMirrored@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationLeft@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationLeft@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationLeftMirrored@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationLeftMirrored@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationRight@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationRight@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationRightMirrored@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationRightMirrored@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationUpMirrored@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_image_with_any_image_orientation_UIImageOrientationUpMirrored@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_all_properties_are_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_all_properties_are_default@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_content_offset_is_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_content_offset_is_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCircle_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_all_properties_are_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_all_properties_are_default@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_content_offset_are_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_content_offset_are_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeCustom_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_all_properties_are_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_all_properties_are_default@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_applyMaskToCroppedImage_is_YES@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_content_offset_are_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_content_offset_are_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_rotation_angle_and_content_offset_are_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_image_crop_mode_is_RSKImageCropModeSquare_correctly_crop_the_image_when_rotation_angle_is_not_equal_to_0@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCircle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCircle@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCustom@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCustom@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeSquare@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeSquare@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_stroke_of_the_mask_looks_right_when_storked_outline_is_visible@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_landscape_stroke_of_the_mask_looks_right_when_storked_outline_is_visible@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCircle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCircle@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCustom@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeCustom@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeSquare@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_crop_mode_looks_right_when_crop_mode_is_RSKImageCropModeSquare@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_stroke_of_the_mask_looks_right_when_stroked_outline_is_visible@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/crop_view_portrait_stroke_of_the_mask_looks_right_when_stroked_outline_is_visible@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/zoomToRect_zooms_to_a_specific_area_of_the_image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageCropViewControllerSpec/zoomToRect_zooms_to_a_specific_area_of_the_image@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageScrollViewSpec/visuals_looks_right_by_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageScrollViewSpec/visuals_looks_right_by_default@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageScrollViewSpec/visuals_looks_right_with_minimum_zoom_scale@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageScrollViewSpec/visuals_looks_right_with_minimum_zoom_scale@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageScrollViewSpec/visuals_looks_right_with_minimum_zoom_scale_and_when_aspectFill_is_YES@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Example/RSKImageCropperExampleTests/ReferenceImages/RSKImageScrollViewSpec/visuals_looks_right_with_minimum_zoom_scale_and_when_aspectFill_is_YES@3x.png -------------------------------------------------------------------------------- /Example/RSKImageCropperExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Framework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'cocoapods', '1.16.2' 4 | 5 | gem 'fui', '0.5.0' 6 | gem 'xcpretty', '0.4.0' 7 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | activesupport (7.2.2) 9 | base64 10 | benchmark (>= 0.3) 11 | bigdecimal 12 | concurrent-ruby (~> 1.0, >= 1.3.1) 13 | connection_pool (>= 2.2.5) 14 | drb 15 | i18n (>= 1.6, < 2) 16 | logger (>= 1.4.2) 17 | minitest (>= 5.1) 18 | securerandom (>= 0.3) 19 | tzinfo (~> 2.0, >= 2.0.5) 20 | addressable (2.8.7) 21 | public_suffix (>= 2.0.2, < 7.0) 22 | algoliasearch (1.27.5) 23 | httpclient (~> 2.8, >= 2.8.3) 24 | json (>= 1.5.1) 25 | atomos (0.1.3) 26 | base64 (0.2.0) 27 | benchmark (0.4.0) 28 | bigdecimal (3.1.8) 29 | claide (1.1.0) 30 | cocoapods (1.16.2) 31 | addressable (~> 2.8) 32 | claide (>= 1.0.2, < 2.0) 33 | cocoapods-core (= 1.16.2) 34 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 35 | cocoapods-downloader (>= 2.1, < 3.0) 36 | cocoapods-plugins (>= 1.0.0, < 2.0) 37 | cocoapods-search (>= 1.0.0, < 2.0) 38 | cocoapods-trunk (>= 1.6.0, < 2.0) 39 | cocoapods-try (>= 1.1.0, < 2.0) 40 | colored2 (~> 3.1) 41 | escape (~> 0.0.4) 42 | fourflusher (>= 2.3.0, < 3.0) 43 | gh_inspector (~> 1.0) 44 | molinillo (~> 0.8.0) 45 | nap (~> 1.0) 46 | ruby-macho (>= 2.3.0, < 3.0) 47 | xcodeproj (>= 1.27.0, < 2.0) 48 | cocoapods-core (1.16.2) 49 | activesupport (>= 5.0, < 8) 50 | addressable (~> 2.8) 51 | algoliasearch (~> 1.0) 52 | concurrent-ruby (~> 1.1) 53 | fuzzy_match (~> 2.0.4) 54 | nap (~> 1.0) 55 | netrc (~> 0.11) 56 | public_suffix (~> 4.0) 57 | typhoeus (~> 1.0) 58 | cocoapods-deintegrate (1.0.5) 59 | cocoapods-downloader (2.1) 60 | cocoapods-plugins (1.0.0) 61 | nap 62 | cocoapods-search (1.0.1) 63 | cocoapods-trunk (1.6.0) 64 | nap (>= 0.8, < 2.0) 65 | netrc (~> 0.11) 66 | cocoapods-try (1.2.0) 67 | colored2 (3.1.2) 68 | concurrent-ruby (1.3.4) 69 | connection_pool (2.4.1) 70 | drb (2.2.1) 71 | escape (0.0.4) 72 | ethon (0.16.0) 73 | ffi (>= 1.15.0) 74 | ffi (1.17.0) 75 | fourflusher (2.3.1) 76 | fui (0.5.0) 77 | gli 78 | fuzzy_match (2.0.4) 79 | gh_inspector (1.1.3) 80 | gli (2.21.1) 81 | httpclient (2.8.3) 82 | i18n (1.14.6) 83 | concurrent-ruby (~> 1.0) 84 | json (2.8.2) 85 | logger (1.6.1) 86 | minitest (5.25.2) 87 | molinillo (0.8.0) 88 | nanaimo (0.4.0) 89 | nap (1.1.0) 90 | netrc (0.11.0) 91 | nkf (0.2.0) 92 | public_suffix (4.0.7) 93 | rexml (3.3.9) 94 | rouge (3.28.0) 95 | ruby-macho (2.5.1) 96 | securerandom (0.3.2) 97 | typhoeus (1.4.1) 98 | ethon (>= 0.9.0) 99 | tzinfo (2.0.6) 100 | concurrent-ruby (~> 1.0) 101 | xcodeproj (1.27.0) 102 | CFPropertyList (>= 2.3.3, < 4.0) 103 | atomos (~> 0.1.3) 104 | claide (>= 1.0.2, < 2.0) 105 | colored2 (~> 3.1) 106 | nanaimo (~> 0.4.0) 107 | rexml (>= 3.3.6, < 4.0) 108 | xcpretty (0.4.0) 109 | rouge (~> 3.28.0) 110 | 111 | PLATFORMS 112 | ruby 113 | 114 | DEPENDENCIES 115 | cocoapods (= 1.16.2) 116 | fui (= 0.5.0) 117 | xcpretty (= 0.4.0) 118 | 119 | BUNDLED WITH 120 | 2.4.10 121 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-present Ruslan Skorb. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | WORKSPACE = Example/RSKImageCropperExample.xcworkspace 2 | SCHEME = RSKImageCropperExample 3 | CONFIGURATION = Release 4 | DEVICE_HOST = platform='iOS Simulator',OS='17.0.1',name='iPhone 15 Pro' 5 | 6 | .PHONY: all build ci clean test lint 7 | 8 | all: ci 9 | 10 | build: 11 | set -o pipefail && xcodebuild -workspace $(WORKSPACE) -scheme $(SCHEME) -configuration '$(CONFIGURATION)' -sdk iphonesimulator -destination $(DEVICE_HOST) build | bundle exec xcpretty -c 12 | 13 | clean: 14 | xcodebuild -workspace $(WORKSPACE) -scheme $(SCHEME) -configuration '$(CONFIGURATION)' clean 15 | 16 | test: 17 | set -o pipefail && xcodebuild -workspace $(WORKSPACE) -scheme $(SCHEME) -configuration Debug test -sdk iphonesimulator -destination $(DEVICE_HOST) | bundle exec xcpretty -c --test 18 | 19 | lint: 20 | bundle exec fui --path Example/RSKImageCropperExample find 21 | 22 | ci: CONFIGURATION = Debug 23 | ci: build 24 | 25 | bundler: 26 | gem install bundler 27 | bundle install 28 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "RSKImageCropper", 8 | platforms: [.iOS(.v12)], 9 | products: [ 10 | .library( 11 | name: "RSKImageCropper", 12 | targets: ["RSKImageCropper"]), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "RSKImageCropper", 17 | path: "RSKImageCropper", 18 | resources: [ 19 | .copy("RSKImageCropperStrings.bundle") 20 | ], 21 | publicHeadersPath: "include" 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## RSKImageCropper ![CI](https://github.com/ruslanskorb/RSKImageCropper/actions/workflows/main.yml/badge.svg) ![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat) ![CocoaPods](https://img.shields.io/cocoapods/v/RSKImageCropper.svg?style=flat) ![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat) 2 | 3 |

4 | Sample 5 |

6 | 7 | An image cropper for iOS like in the Contacts app with support for landscape orientation. 8 | 9 | ## Installation 10 | *RSKImageCropper requires iOS 12.0 or later.* 11 | 12 | ### Using [Swift Package Manager](https://swift.org/package-manager/) 13 | 14 | 1. To add the `RSKImageCropper` package to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the repository URL. 15 | 16 | https://github.com/ruslanskorb/RSKImageCropper.git 17 | 18 | ### Using [CocoaPods](http://cocoapods.org) 19 | 20 | 1. Add the pod `RSKImageCropper` to your [Podfile](http://guides.cocoapods.org/using/the-podfile.html). 21 | 22 | pod 'RSKImageCropper' 23 | 24 | 2. Run `pod install` from Terminal, then open your app's `.xcworkspace` file to launch Xcode. 25 | 3. Import the `RSKImageCropper.h` header. Typically, this should be written as `#import ` 26 | 27 | ### Using [Carthage](https://github.com/Carthage/Carthage) 28 | 29 | 1. Add the `ruslanskorb/RSKImageCropper` project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile). 30 | 31 | github "ruslanskorb/RSKImageCropper" 32 | 33 | 2. Run `carthage update`, then follow the [additional steps required](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add the iOS and/or Mac frameworks into your project. 34 | 3. Import the RSKImageCropper framework/module. 35 | * Using Modules: `@import RSKImageCropper` 36 | * Without Modules: `#import ` 37 | 38 | ## Basic Usage 39 | 40 | Import the class header. 41 | 42 | ``` objective-c 43 | #import 44 | ``` 45 | 46 | Just create a view controller for image cropping and set the delegate. 47 | 48 | ``` objective-c 49 | - (IBAction)onButtonTouch:(UIButton *)sender 50 | { 51 | UIImage *image = [UIImage imageNamed:@"image"]; 52 | RSKImageCropViewController *imageCropViewController = [[RSKImageCropViewController alloc] initWithImage:image]; 53 | imageCropViewController.delegate = self; 54 | [self.navigationController pushViewController:imageCropViewController animated:YES]; 55 | } 56 | ``` 57 | 58 | ## Delegate 59 | 60 | `RSKImageCropViewControllerDelegate` provides three delegate methods. To use them, implement the delegate in your view controller. 61 | 62 | ```objective-c 63 | @interface ViewController () 64 | ``` 65 | 66 | Then implement the delegate functions. 67 | 68 | ```objective-c 69 | // Crop image has been canceled. 70 | - (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller 71 | { 72 | [self.navigationController popViewControllerAnimated:YES]; 73 | } 74 | 75 | // The original image has been cropped. Additionally provides a rotation angle used to produce image. 76 | - (void)imageCropViewController:(RSKImageCropViewController *)controller 77 | didCropImage:(UIImage *)croppedImage 78 | usingCropRect:(CGRect)cropRect 79 | rotationAngle:(CGFloat)rotationAngle 80 | { 81 | self.imageView.image = croppedImage; 82 | [self.navigationController popViewControllerAnimated:YES]; 83 | } 84 | 85 | // The original image will be cropped. 86 | - (void)imageCropViewController:(RSKImageCropViewController *)controller 87 | willCropImage:(UIImage *)originalImage 88 | { 89 | // Use when `applyMaskToCroppedImage` set to YES. 90 | [SVProgressHUD show]; 91 | } 92 | ``` 93 | 94 | ## DataSource 95 | 96 | `RSKImageCropViewControllerDataSource` provides three data source methods. The method `imageCropViewControllerCustomMaskRect:` asks the data source for a custom rect for the mask. The method `imageCropViewControllerCustomMaskPath:` asks the data source for a custom path for the mask. The method `imageCropViewControllerCustomMovementRect:` asks the data source for a custom rect in which the image can be moved. To use them, implement the data source in your view controller. 97 | 98 | ```objective-c 99 | @interface ViewController () 100 | ``` 101 | 102 | Then implement the data source functions. 103 | 104 | ```objective-c 105 | // Returns a custom rect for the mask. 106 | - (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller 107 | { 108 | CGSize aspectRatio = CGSizeMake(16.0f, 9.0f); 109 | 110 | CGFloat viewWidth = CGRectGetWidth(controller.view.frame); 111 | CGFloat viewHeight = CGRectGetHeight(controller.view.frame); 112 | 113 | CGFloat maskWidth; 114 | if ([controller isPortraitInterfaceOrientation]) { 115 | maskWidth = viewWidth; 116 | } else { 117 | maskWidth = viewHeight; 118 | } 119 | 120 | CGFloat maskHeight; 121 | do { 122 | maskHeight = maskWidth * aspectRatio.height / aspectRatio.width; 123 | maskWidth -= 1.0f; 124 | } while (maskHeight != floor(maskHeight)); 125 | maskWidth += 1.0f; 126 | 127 | CGSize maskSize = CGSizeMake(maskWidth, maskHeight); 128 | 129 | CGRect maskRect = CGRectMake((viewWidth - maskSize.width) * 0.5f, 130 | (viewHeight - maskSize.height) * 0.5f, 131 | maskSize.width, 132 | maskSize.height); 133 | 134 | return maskRect; 135 | } 136 | 137 | // Returns a custom path for the mask. 138 | - (UIBezierPath *)imageCropViewControllerCustomMaskPath:(RSKImageCropViewController *)controller 139 | { 140 | CGRect rect = controller.maskRect; 141 | CGPoint point1 = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect)); 142 | CGPoint point2 = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect)); 143 | CGPoint point3 = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect)); 144 | CGPoint point4 = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect)); 145 | 146 | UIBezierPath *rectangle = [UIBezierPath bezierPath]; 147 | [rectangle moveToPoint:point1]; 148 | [rectangle addLineToPoint:point2]; 149 | [rectangle addLineToPoint:point3]; 150 | [rectangle addLineToPoint:point4]; 151 | [rectangle closePath]; 152 | 153 | return rectangle; 154 | } 155 | 156 | // Returns a custom rect in which the image can be moved. 157 | - (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller 158 | { 159 | if (controller.rotationAngle == 0) { 160 | return controller.maskRect; 161 | } else { 162 | CGRect maskRect = controller.maskRect; 163 | CGFloat rotationAngle = controller.rotationAngle; 164 | 165 | CGRect movementRect = CGRectZero; 166 | 167 | movementRect.size.width = CGRectGetWidth(maskRect) * fabs(cos(rotationAngle)) + CGRectGetHeight(maskRect) * fabs(sin(rotationAngle)); 168 | movementRect.size.height = CGRectGetHeight(maskRect) * fabs(cos(rotationAngle)) + CGRectGetWidth(maskRect) * fabs(sin(rotationAngle)); 169 | 170 | movementRect.origin.x = CGRectGetMinX(maskRect) + (CGRectGetWidth(maskRect) - CGRectGetWidth(movementRect)) * 0.5f; 171 | movementRect.origin.y = CGRectGetMinY(maskRect) + (CGRectGetHeight(maskRect) - CGRectGetHeight(movementRect)) * 0.5f; 172 | 173 | movementRect.origin.x = floor(CGRectGetMinX(movementRect)); 174 | movementRect.origin.y = floor(CGRectGetMinY(movementRect)); 175 | movementRect = CGRectIntegral(movementRect); 176 | 177 | return movementRect; 178 | } 179 | } 180 | ``` 181 | 182 | ## Coming Soon 183 | 184 | - If you would like to request a new feature, feel free to raise an issue. 185 | 186 | ## Demo 187 | 188 | Build and run the `RSKImageCropperExample` project in Xcode to see `RSKImageCropper` in action. 189 | Have fun. Fork and send pull requests. Figure out hooks for customization. 190 | 191 | ## Privacy 192 | 193 | `RSKImageCropper` doesn't require a privacy manifest. According to [information received from Apple](https://developer.apple.com/forums/thread/746481?answerId=782256022#782256022), we should avoid adding an empty privacy manifest to our frameworks. 194 | 195 | ## Contact 196 | 197 | Ruslan Skorb 198 | 199 | - http://github.com/ruslanskorb 200 | - http://twitter.com/ruslanskorb 201 | - ruslan.skorb@gmail.com 202 | 203 | ## License 204 | 205 | This project is available under the MIT license. See the LICENSE file for more info. Attribution by linking to the [project page](https://github.com/ruslanskorb/RSKImageCropper) is appreciated. 206 | -------------------------------------------------------------------------------- /RSKImageCropper.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'RSKImageCropper' 3 | s.version = '5.0.1' 4 | s.summary = 'An image cropper for iOS like in the Contacts app with support for landscape orientation.' 5 | s.homepage = 'https://github.com/ruslanskorb/RSKImageCropper' 6 | s.license = { :type => 'MIT', :file => 'LICENSE' } 7 | s.authors = { 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } 8 | s.source = { :git => 'https://github.com/ruslanskorb/RSKImageCropper.git', :tag => s.version.to_s } 9 | s.platform = :ios, '12.0' 10 | s.module_map = 'RSKImageCropper/RSKImageCropper.modulemap' 11 | s.source_files = 'RSKImageCropper/*.{h,m}' 12 | s.resources = 'RSKImageCropper/RSKImageCropperStrings.bundle' 13 | s.frameworks = 'QuartzCore', 'UIKit' 14 | s.requires_arc = true 15 | end 16 | -------------------------------------------------------------------------------- /RSKImageCropper.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RSKImageCropper.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RSKImageCropper.xcodeproj/xcshareddata/xcschemes/RSKImageCropper.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 77 | 83 | 84 | 85 | 86 | 92 | 93 | 99 | 100 | 101 | 102 | 104 | 105 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /RSKImageCropper.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RSKImageCropper.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RSKImageCropper/CGGeometry+RSKImageCropper.h: -------------------------------------------------------------------------------- 1 | // 2 | // CGGeometry+RSKImageCropper.h 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | #import 27 | 28 | // tgmath functions aren't used on iOS when modules are enabled. 29 | // Open Radar - http://www.openradar.me/16744288 30 | // Work around this by redeclaring things here. 31 | 32 | #ifdef __tg_promote1 33 | 34 | #undef cos 35 | #define cos(__x) __tg_cos(__tg_promote1((__x))(__x)) 36 | 37 | #undef sin 38 | #define sin(__x) __tg_sin(__tg_promote1((__x))(__x)) 39 | 40 | #undef sqrt 41 | #define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x)) 42 | 43 | #undef fabs 44 | #define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x)) 45 | 46 | #undef ceil 47 | #define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x)) 48 | 49 | #undef floor 50 | #define floor(__x) __tg_floor(__tg_promote1((__x))(__x)) 51 | 52 | #undef round 53 | #define round(__x) __tg_round(__tg_promote1((__x))(__x)) 54 | 55 | #endif /* __tg_promote1 */ 56 | 57 | #ifdef __tg_promote2 58 | 59 | #undef atan2 60 | #define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \ 61 | __tg_promote2((__x), (__y))(__y)) 62 | 63 | #undef pow 64 | #define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \ 65 | __tg_promote2((__x), (__y))(__y)) 66 | 67 | #endif /* __tg_promote2 */ 68 | 69 | #ifdef CGFLOAT_IS_DOUBLE 70 | #define RSK_EPSILON DBL_EPSILON 71 | #define RSK_MIN DBL_MIN 72 | #else 73 | #define RSK_EPSILON FLT_EPSILON 74 | #define RSK_MIN FLT_MIN 75 | #endif 76 | 77 | // Line segments. 78 | struct RSKLineSegment { 79 | CGPoint start; 80 | CGPoint end; 81 | }; 82 | typedef struct RSKLineSegment RSKLineSegment; 83 | 84 | // The "empty" point. This is the point returned when, for example, we 85 | // intersect two disjoint line segments. Note that the null point is not the 86 | // same as the zero point. 87 | CG_EXTERN const CGPoint RSKPointNull; 88 | 89 | // Returns the exact center point of the given rectangle. 90 | CGPoint RSKRectCenterPoint(CGRect rect); 91 | 92 | // Returns the `rect` with normalized values. 93 | CGRect RSKRectNormalize(CGRect rect); 94 | 95 | // Returns the `rect` scaled around the `point` by `sx` and `sy`. 96 | CGRect RSKRectScaleAroundPoint(CGRect rect, CGPoint point, CGFloat sx, CGFloat sy); 97 | 98 | // Returns true if `point' is the null point, false otherwise. 99 | bool RSKPointIsNull(CGPoint point); 100 | 101 | // Returns the `point` rotated around the `pivot` by `angle`. 102 | CGPoint RSKPointRotateAroundPoint(CGPoint point, CGPoint pivot, CGFloat angle); 103 | 104 | // Returns the distance between two points. 105 | CGFloat RSKPointDistance(CGPoint p1, CGPoint p2); 106 | 107 | // Make a line segment from two points `start` and `end`. 108 | RSKLineSegment RSKLineSegmentMake(CGPoint start, CGPoint end); 109 | 110 | // Returns the line segment rotated around the `pivot` by `angle`. 111 | RSKLineSegment RSKLineSegmentRotateAroundPoint(RSKLineSegment lineSegment, CGPoint pivot, CGFloat angle); 112 | 113 | // Returns the intersection of `ls1' and `ls2'. This may return a null point. 114 | CGPoint RSKLineSegmentIntersection(RSKLineSegment ls1, RSKLineSegment ls2); 115 | -------------------------------------------------------------------------------- /RSKImageCropper/CGGeometry+RSKImageCropper.m: -------------------------------------------------------------------------------- 1 | // 2 | // CGGeometry+RSKImageCropper.m 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "CGGeometry+RSKImageCropper.h" 26 | 27 | // K is a constant such that the accumulated error of our floating-point computations is definitely bounded by K units in the last place. 28 | #ifdef CGFLOAT_IS_DOUBLE 29 | static const CGFloat kK = 9; 30 | #else 31 | static const CGFloat kK = 0; 32 | #endif 33 | 34 | const CGPoint RSKPointNull = { INFINITY, INFINITY }; 35 | 36 | CGPoint RSKRectCenterPoint(CGRect rect) 37 | { 38 | return CGPointMake(CGRectGetMinX(rect) + CGRectGetWidth(rect) / 2, 39 | CGRectGetMinY(rect) + CGRectGetHeight(rect) / 2); 40 | } 41 | 42 | CGRect RSKRectNormalize(CGRect rect) 43 | { 44 | CGPoint origin = rect.origin; 45 | 46 | CGFloat x = origin.x; 47 | CGFloat y = origin.y; 48 | CGFloat ceilX = ceil(x); 49 | CGFloat ceilY = ceil(y); 50 | 51 | if (fabs(ceilX - x) < pow(10, kK) * RSK_EPSILON * fabs(ceilX + x) || fabs(ceilX - x) < RSK_MIN || 52 | fabs(ceilY - y) < pow(10, kK) * RSK_EPSILON * fabs(ceilY + y) || fabs(ceilY - y) < RSK_MIN) { 53 | 54 | origin.x = ceilX; 55 | origin.y = ceilY; 56 | } else { 57 | origin.x = floor(x); 58 | origin.y = floor(y); 59 | } 60 | 61 | CGSize size = rect.size; 62 | 63 | CGFloat width = size.width; 64 | CGFloat height = size.height; 65 | CGFloat ceilWidth = ceil(width); 66 | CGFloat ceilHeight = ceil(height); 67 | 68 | if (fabs(ceilWidth - width) < pow(10, kK) * RSK_EPSILON * fabs(ceilWidth + width) || fabs(ceilWidth - width) < RSK_MIN || 69 | fabs(ceilHeight - height) < pow(10, kK) * RSK_EPSILON * fabs(ceilHeight + height) || fabs(ceilHeight - height) < RSK_MIN) { 70 | 71 | size.width = ceilWidth; 72 | size.height = ceilHeight; 73 | } else { 74 | size.width = floor(width); 75 | size.height = floor(height); 76 | } 77 | 78 | return CGRectMake(origin.x, origin.y, size.width, size.height); 79 | } 80 | 81 | CGRect RSKRectScaleAroundPoint(CGRect rect, CGPoint point, CGFloat sx, CGFloat sy) 82 | { 83 | CGAffineTransform translationTransform, scaleTransform; 84 | translationTransform = CGAffineTransformMakeTranslation(-point.x, -point.y); 85 | rect = CGRectApplyAffineTransform(rect, translationTransform); 86 | scaleTransform = CGAffineTransformMakeScale(sx, sy); 87 | rect = CGRectApplyAffineTransform(rect, scaleTransform); 88 | translationTransform = CGAffineTransformMakeTranslation(point.x, point.y); 89 | rect = CGRectApplyAffineTransform(rect, translationTransform); 90 | return rect; 91 | } 92 | 93 | bool RSKPointIsNull(CGPoint point) 94 | { 95 | return CGPointEqualToPoint(point, RSKPointNull); 96 | } 97 | 98 | CGPoint RSKPointRotateAroundPoint(CGPoint point, CGPoint pivot, CGFloat angle) 99 | { 100 | CGAffineTransform translationTransform, rotationTransform; 101 | translationTransform = CGAffineTransformMakeTranslation(-pivot.x, -pivot.y); 102 | point = CGPointApplyAffineTransform(point, translationTransform); 103 | rotationTransform = CGAffineTransformMakeRotation(angle); 104 | point = CGPointApplyAffineTransform(point, rotationTransform); 105 | translationTransform = CGAffineTransformMakeTranslation(pivot.x, pivot.y); 106 | point = CGPointApplyAffineTransform(point, translationTransform); 107 | return point; 108 | } 109 | 110 | CGFloat RSKPointDistance(CGPoint p1, CGPoint p2) 111 | { 112 | CGFloat dx = p1.x - p2.x; 113 | CGFloat dy = p1.y - p2.y; 114 | return sqrt(pow(dx, 2) + pow(dy, 2)); 115 | } 116 | 117 | RSKLineSegment RSKLineSegmentMake(CGPoint start, CGPoint end) 118 | { 119 | return (RSKLineSegment){ start, end }; 120 | } 121 | 122 | RSKLineSegment RSKLineSegmentRotateAroundPoint(RSKLineSegment line, CGPoint pivot, CGFloat angle) 123 | { 124 | return RSKLineSegmentMake(RSKPointRotateAroundPoint(line.start, pivot, angle), 125 | RSKPointRotateAroundPoint(line.end, pivot, angle)); 126 | } 127 | 128 | /* 129 | Equations of line segments: 130 | 131 | pA = ls1.start + uA * (ls1.end - ls1.start) 132 | pB = ls2.start + uB * (ls2.end - ls2.start) 133 | 134 | In the case when `pA` is equal `pB` we have: 135 | 136 | x1 + uA * (x2 - x1) = x3 + uB * (x4 - x3) 137 | y1 + uA * (y2 - y1) = y3 + uB * (y4 - y3) 138 | 139 | uA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3) / (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) 140 | uB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3) / (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) 141 | 142 | numeratorA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3) 143 | denominatorA = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) 144 | 145 | numeratorA = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3) 146 | denominatorB = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) 147 | 148 | [1] Denominators are equal. 149 | [2] If numerators and denominator are zero, then the line segments are coincident. The point of intersection is the midpoint of the line segment. 150 | 151 | x = (x1 + x2) * 0.5 152 | y = (y1 + y2) * 0.5 153 | 154 | or 155 | 156 | x = (x3 + x4) * 0.5 157 | y = (y3 + y4) * 0.5 158 | 159 | [3] If denominator is zero, then the line segments are parallel. There is no point of intersection. 160 | [4] If `uA` and `uB` is included into the interval [0, 1], then the line segments intersects in the point (x, y). 161 | 162 | x = x1 + uA * (x2 - x1) 163 | y = y1 + uA * (y2 - y1) 164 | 165 | or 166 | 167 | x = x3 + uB * (x4 - x3) 168 | y = y3 + uB * (y4 - y3) 169 | */ 170 | CGPoint RSKLineSegmentIntersection(RSKLineSegment ls1, RSKLineSegment ls2) 171 | { 172 | CGFloat x1 = ls1.start.x; 173 | CGFloat y1 = ls1.start.y; 174 | CGFloat x2 = ls1.end.x; 175 | CGFloat y2 = ls1.end.y; 176 | CGFloat x3 = ls2.start.x; 177 | CGFloat y3 = ls2.start.y; 178 | CGFloat x4 = ls2.end.x; 179 | CGFloat y4 = ls2.end.y; 180 | 181 | CGFloat numeratorA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); 182 | CGFloat numeratorB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); 183 | CGFloat denominator = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); 184 | 185 | // Check the coincidence. 186 | if (fabs(numeratorA) < RSK_EPSILON && fabs(numeratorB) < RSK_EPSILON && fabs(denominator) < RSK_EPSILON) { 187 | return CGPointMake((x1 + x2) * 0.5, (y1 + y2) * 0.5); 188 | } 189 | 190 | // Check the parallelism. 191 | if (fabs(denominator) < RSK_EPSILON) { 192 | return RSKPointNull; 193 | } 194 | 195 | // Check the intersection. 196 | CGFloat uA = numeratorA / denominator; 197 | CGFloat uB = numeratorB / denominator; 198 | if (uA < 0 || uA > 1 || uB < 0 || uB > 1) { 199 | return RSKPointNull; 200 | } 201 | 202 | return CGPointMake(x1 + uA * (x2 - x1), y1 + uA * (y2 - y1)); 203 | } 204 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropViewController+Protected.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropViewController+Protected.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | #import 27 | #import 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | @interface RSKImageCropViewController (RSKImageCropViewControllerProtectedMethods) 32 | 33 | /** 34 | Asynchronously crops the original image in accordance with the current settings and tells the delegate that the original image will be / has been cropped. 35 | */ 36 | - (void)cropImage; 37 | 38 | /** 39 | Tells the delegate that the crop has been canceled. 40 | */ 41 | - (void)cancelCrop; 42 | 43 | /** 44 | Resets the rotation angle, the position and the zoom scale of the original image to the default values. 45 | 46 | @param animated Set this value to YES to animate the reset. 47 | */ 48 | - (void)reset:(BOOL)animated; 49 | 50 | /** 51 | Sets the current rotation angle of the image in radians. 52 | 53 | @param rotationAngle The rotation angle of the image in radians. 54 | */ 55 | - (void)setRotationAngle:(CGFloat)rotationAngle; 56 | 57 | /** 58 | Sets the current scale factor for the image. 59 | 60 | @param zoomScale The scale factor for the image. 61 | */ 62 | - (void)setZoomScale:(CGFloat)zoomScale; 63 | 64 | @end 65 | 66 | NS_ASSUME_NONNULL_END 67 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropViewController.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | NS_HEADER_AUDIT_BEGIN(nullability, sendability) 28 | 29 | @protocol RSKImageCropViewControllerDataSource; 30 | @protocol RSKImageCropViewControllerDelegate; 31 | 32 | /** 33 | Types of supported crop modes. 34 | */ 35 | typedef NS_ENUM(NSUInteger, RSKImageCropMode) { 36 | RSKImageCropModeCircle, 37 | RSKImageCropModeSquare, 38 | RSKImageCropModeCustom 39 | }; 40 | 41 | NS_SWIFT_UI_ACTOR 42 | @interface RSKImageCropViewController : UIViewController 43 | 44 | /** 45 | Designated initializer. Initializes and returns a newly allocated view controller object with the specified image. 46 | 47 | @param originalImage The image for cropping. 48 | */ 49 | - (instancetype)initWithImage:(UIImage *)originalImage; 50 | 51 | /** 52 | Initializes and returns a newly allocated view controller object with the specified image and the specified crop mode. 53 | 54 | @param originalImage The image for cropping. 55 | @param cropMode The mode for cropping. 56 | */ 57 | - (instancetype)initWithImage:(UIImage *)originalImage cropMode:(RSKImageCropMode)cropMode; 58 | 59 | /** 60 | Zooms to a specific area of the image so that it is visible. 61 | 62 | @param rect A rectangle defining an area of the image. The rectangle should be in the coordinate space of the image crop view controller's view. 63 | @param animated YES if the scrolling should be animated, NO if it should be immediate. 64 | */ 65 | - (void)zoomToRect:(CGRect)rect animated:(BOOL)animated; 66 | 67 | ///----------------------------- 68 | /// @name Accessing the Delegate 69 | ///----------------------------- 70 | 71 | /** 72 | The receiver's delegate. 73 | 74 | @discussion A `RSKImageCropViewControllerDelegate` delegate responds to messages sent by completing / canceling crop the image in the image crop view controller. 75 | */ 76 | @property (weak, nonatomic, nullable) id delegate; 77 | 78 | /** 79 | The receiver's data source. 80 | 81 | @discussion A `RSKImageCropViewControllerDataSource` data source provides a custom rect and a custom path for the mask and a custom movement rect for the image. 82 | */ 83 | @property (weak, nonatomic, nullable) id dataSource; 84 | 85 | ///-------------------------- 86 | /// @name Accessing the Image 87 | ///-------------------------- 88 | 89 | /** 90 | The image for cropping. 91 | */ 92 | @property (strong, nonatomic) UIImage *originalImage; 93 | 94 | /// ----------------------------------- 95 | /// @name Accessing the Mask Attributes 96 | /// ----------------------------------- 97 | 98 | /** 99 | The color of the layer with the mask. Default value is [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.7f]. 100 | */ 101 | @property (copy, nonatomic) UIColor *maskLayerColor; 102 | 103 | /** 104 | The line width used when stroking the path of the mask layer. Default value is 1.0. 105 | */ 106 | @property (assign, nonatomic) CGFloat maskLayerLineWidth; 107 | 108 | /** 109 | The color to fill the stroked outline of the path of the mask layer, or nil for no stroking. Default valus is nil. 110 | */ 111 | @property (copy, nonatomic, nullable) UIColor *maskLayerStrokeColor; 112 | 113 | /** 114 | The rect of the mask. 115 | 116 | @discussion Updating each time before the crop view lays out its subviews. 117 | */ 118 | @property (assign, readonly, nonatomic) CGRect maskRect; 119 | 120 | /** 121 | The path of the mask. 122 | 123 | @discussion Updating each time before the crop view lays out its subviews. 124 | */ 125 | @property (copy, readonly, nonatomic) UIBezierPath *maskPath; 126 | 127 | /// ----------------------------------- 128 | /// @name Accessing the Crop Attributes 129 | /// ----------------------------------- 130 | 131 | /** 132 | The mode for cropping. Default value is `RSKImageCropModeCircle`. 133 | */ 134 | @property (assign, nonatomic) RSKImageCropMode cropMode; 135 | 136 | /** 137 | The crop rectangle. 138 | 139 | @discussion The value is calculated at run time. 140 | */ 141 | @property (readonly, nonatomic) CGRect cropRect; 142 | 143 | /** 144 | A value that specifies the current rotation angle of the image in radians. 145 | 146 | @discussion The value is calculated at run time. 147 | */ 148 | @property (readonly, nonatomic) CGFloat rotationAngle; 149 | 150 | /** 151 | A floating-point value that specifies the current scale factor applied to the image. 152 | 153 | @discussion The value is calculated at run time. 154 | */ 155 | @property (readonly, nonatomic) CGFloat zoomScale; 156 | 157 | /** 158 | A Boolean value that determines whether the image will always fill the mask space. Default value is `NO`. 159 | */ 160 | @property (assign, nonatomic) BOOL avoidEmptySpaceAroundImage; 161 | 162 | /** 163 | A Boolean value that determines whether the image will always bounce horizontally. Default value is `NO`. 164 | */ 165 | @property (assign, nonatomic) BOOL alwaysBounceHorizontal; 166 | 167 | /** 168 | A Boolean value that determines whether the image will always bounce vertically. Default value is `NO`. 169 | */ 170 | @property (assign, nonatomic) BOOL alwaysBounceVertical; 171 | 172 | /** 173 | A Boolean value that determines whether the mask applies to the image after cropping. Default value is `NO`. 174 | */ 175 | @property (assign, nonatomic) BOOL applyMaskToCroppedImage; 176 | 177 | /** 178 | A Boolean value that controls whether the image bounces past the edge of the movement rect and back again. Default value is `YES`. 179 | */ 180 | @property (assign, nonatomic) BOOL bounces; 181 | 182 | /** 183 | A Boolean value that determines whether the image scaling is animated when the scaling exceeds the maximum or minimum limits. Default value is `YES`. 184 | */ 185 | @property (assign, nonatomic) BOOL bouncesZoom; 186 | 187 | /** 188 | A Boolean value that controls whether the rotaion gesture is enabled. Default value is `NO`. 189 | 190 | @discussion To support the rotation when `cropMode` is `RSKImageCropModeCustom` you must implement the data source method `imageCropViewControllerCustomMovementRect:`. 191 | */ 192 | @property (assign, getter=isRotationEnabled, nonatomic) BOOL rotationEnabled; 193 | 194 | /// ------------------------------- 195 | /// @name Accessing the UI Elements 196 | /// ------------------------------- 197 | 198 | /** 199 | The Title Label. 200 | */ 201 | @property (strong, nonatomic, readonly) UILabel *moveAndScaleLabel; 202 | 203 | /** 204 | The Cancel Button. 205 | */ 206 | @property (strong, nonatomic, readonly) UIButton *cancelButton; 207 | 208 | /** 209 | The Choose Button. 210 | */ 211 | @property (strong, nonatomic, readonly) UIButton *chooseButton; 212 | 213 | /// ------------------------------------------- 214 | /// @name Checking of the Interface Orientation 215 | /// ------------------------------------------- 216 | 217 | /** 218 | Returns a Boolean value indicating whether the user interface is currently presented in a portrait orientation. 219 | 220 | @return YES if the interface orientation is portrait, otherwise returns NO. 221 | */ 222 | - (BOOL)isPortraitInterfaceOrientation; 223 | 224 | /// ------------------------------------- 225 | /// @name Accessing the Layout Attributes 226 | /// ------------------------------------- 227 | 228 | /** 229 | The inset of the circle mask rect's area within the crop view's area in portrait orientation. Default value is `15.0f`. 230 | */ 231 | @property (assign, nonatomic) CGFloat portraitCircleMaskRectInnerEdgeInset; 232 | 233 | /** 234 | The inset of the square mask rect's area within the crop view's area in portrait orientation. Default value is `20.0f`. 235 | */ 236 | @property (assign, nonatomic) CGFloat portraitSquareMaskRectInnerEdgeInset; 237 | 238 | /** 239 | The vertical space between the top of the 'Move and Scale' label and the top of the crop view's safe area in portrait orientation. Default value is `44.0f`. 240 | */ 241 | @property (assign, nonatomic) CGFloat portraitMoveAndScaleLabelTopAndCropViewSafeAreaTopVerticalSpace; 242 | 243 | /** 244 | The vertical space between the bottom of the crop view's safe area and the bottom of the 'Cancel' button in portrait orientation. Default value is `21.0f`. 245 | */ 246 | @property (assign, nonatomic) CGFloat portraitCropViewSafeAreaBottomAndCancelButtonBottomVerticalSpace; 247 | 248 | /** 249 | The vertical space between the bottom of the crop view's safe area and the bottom of the 'Choose' button in portrait orientation. Default value is `21.0f`. 250 | */ 251 | @property (assign, nonatomic) CGFloat portraitCropViewSafeAreaBottomAndChooseButtonBottomVerticalSpace; 252 | 253 | /** 254 | The horizontal space between the leading of the 'Cancel' button and the leading of the crop view's safe area in portrait orientation. Default value is `13.0f`. 255 | */ 256 | @property (assign, nonatomic) CGFloat portraitCancelButtonLeadingAndCropViewSafeAreaLeadingHorizontalSpace; 257 | 258 | /** 259 | The horizontal space between the trailing of the crop view's safe area and the trailing of the 'Choose' button in portrait orientation. Default value is `13.0f`. 260 | */ 261 | @property (assign, nonatomic) CGFloat portraitCropViewSafeAreaTrailingAndChooseButtonTrailingHorizontalSpace; 262 | 263 | /** 264 | The inset of the circle mask rect's area within the crop view's area in landscape orientation. Default value is `45.0f`. 265 | */ 266 | @property (assign, nonatomic) CGFloat landscapeCircleMaskRectInnerEdgeInset; 267 | 268 | /** 269 | The inset of the square mask rect's area within the crop view's area in landscape orientation. Default value is `45.0f`. 270 | */ 271 | @property (assign, nonatomic) CGFloat landscapeSquareMaskRectInnerEdgeInset; 272 | 273 | /** 274 | The vertical space between the top of the 'Move and Scale' label and the top of the crop view's safe area in landscape orientation. Default value is `12.0f`. 275 | */ 276 | @property (assign, nonatomic) CGFloat landscapeMoveAndScaleLabelTopAndCropViewSafeAreaTopVerticalSpace; 277 | 278 | /** 279 | The vertical space between the bottom of the crop view's safe area and the bottom of the 'Cancel' button in landscape orientation. Default value is `12.0f`. 280 | */ 281 | @property (assign, nonatomic) CGFloat landscapeCropViewSafeAreaBottomAndCancelButtonBottomVerticalSpace; 282 | 283 | /** 284 | The vertical space between the bottom of the crop view's safe area and the bottom of the 'Choose' button in landscape orientation. Default value is `12.0f`. 285 | */ 286 | @property (assign, nonatomic) CGFloat landscapeCropViewSafeAreaBottomAndChooseButtonBottomVerticalSpace; 287 | 288 | /** 289 | The horizontal space between the leading of the 'Cancel' button and the leading of the crop view's safe area in landscape orientation. Default value is `13.0f`. 290 | */ 291 | @property (assign, nonatomic) CGFloat landscapeCancelButtonLeadingAndCropViewSafeAreaLeadingHorizontalSpace; 292 | 293 | /** 294 | The horizontal space between the trailing of the crop view's safe area and the trailing of the 'Choose' button in landscape orientation. Default value is `13.0f`. 295 | */ 296 | @property (assign, nonatomic) CGFloat landscapeCropViewSafeAreaTrailingAndChooseButtonTrailingHorizontalSpace; 297 | 298 | @end 299 | 300 | /** 301 | The `RSKImageCropViewControllerDataSource` protocol is adopted by an object that provides a custom rect and a custom path for the mask and a custom movement rect for the image. 302 | */ 303 | NS_SWIFT_UI_ACTOR 304 | @protocol RSKImageCropViewControllerDataSource 305 | 306 | /** 307 | Asks the data source a custom rect for the mask. 308 | 309 | @param controller The crop view controller object to whom a rect is provided. 310 | 311 | @return A custom rect for the mask. 312 | */ 313 | - (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller; 314 | 315 | /** 316 | Asks the data source a custom path for the mask. 317 | 318 | @param controller The crop view controller object to whom a path is provided. 319 | 320 | @return A custom path for the mask. 321 | */ 322 | - (UIBezierPath *)imageCropViewControllerCustomMaskPath:(RSKImageCropViewController *)controller; 323 | 324 | /** 325 | Asks the data source a custom rect in which the image can be moved. 326 | 327 | @param controller The crop view controller object to whom a rect is provided. 328 | 329 | @return A custom rect in which the image can be moved. 330 | */ 331 | - (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller; 332 | 333 | @end 334 | 335 | /** 336 | The `RSKImageCropViewControllerDelegate` protocol defines messages sent to a image crop view controller delegate when crop image was canceled or the original image was cropped. 337 | */ 338 | NS_SWIFT_UI_ACTOR 339 | @protocol RSKImageCropViewControllerDelegate 340 | 341 | /** 342 | Tells the delegate that crop image has been canceled. 343 | */ 344 | - (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller; 345 | 346 | /** 347 | Tells the delegate that the original image has been cropped. Additionally provides a crop rect and a rotation angle used to produce image. 348 | */ 349 | - (void)imageCropViewController:(RSKImageCropViewController *)controller didCropImage:(UIImage *)croppedImage usingCropRect:(CGRect)cropRect rotationAngle:(CGFloat)rotationAngle; 350 | 351 | @optional 352 | 353 | /** 354 | Tells the delegate that the image has been displayed. 355 | */ 356 | - (void)imageCropViewControllerDidDisplayImage:(RSKImageCropViewController *)controller; 357 | 358 | /** 359 | Tells the delegate that the original image will be cropped. 360 | */ 361 | - (void)imageCropViewController:(RSKImageCropViewController *)controller willCropImage:(UIImage *)originalImage; 362 | 363 | @end 364 | 365 | NS_HEADER_AUDIT_END(nullability, sendability) 366 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropper.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /** 26 | `RSKImageCropper` is an image cropper for iOS like in the Contacts app with support for landscape orientation. 27 | */ 28 | 29 | #import 30 | 31 | //! Project version number for RSKImageCropper. 32 | FOUNDATION_EXPORT double RSKImageCropperVersionNumber; 33 | 34 | //! Project version string for RSKImageCropper. 35 | FOUNDATION_EXPORT const unsigned char RSKImageCropperVersionString[]; 36 | 37 | #import 38 | #import 39 | #import 40 | #import 41 | #import 42 | #import 43 | #import 44 | #import 45 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropper.modulemap: -------------------------------------------------------------------------------- 1 | framework module RSKImageCropper { 2 | umbrella header "RSKImageCropper.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ar.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "نقل وتحجيم"; 27 | /* Cancel button */ 28 | "Cancel" = "إلغاء"; 29 | /* Choose button */ 30 | "Choose" = "تحديد"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/bg.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Преместване и мащабиране"; 27 | /* Cancel button */ 28 | "Cancel" = "Отмяна"; 29 | /* Choose button */ 30 | "Choose" = "Изберете"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/bs.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Pomjeri i skaliraj"; 27 | /* Cancel button */ 28 | "Cancel" = "Odustani"; 29 | /* Choose button */ 30 | "Choose" = "Odaberi"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ca.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Moure i escalar"; 27 | /* Cancel button */ 28 | "Cancel" = "Cancel·lar"; 29 | /* Choose button */ 30 | "Choose" = "Seleccionar"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/cs.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Vyberte výřez"; 27 | /* Cancel button */ 28 | "Cancel" = "Zrušit"; 29 | /* Choose button */ 30 | "Choose" = "Vybrat"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/da.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Flyt og skaler"; 27 | /* Cancel button */ 28 | "Cancel" = "Annuller"; 29 | /* Choose button */ 30 | "Choose" = "Vælg"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/de.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Bewegen und Skalieren"; 27 | /* Cancel button */ 28 | "Cancel" = "Abbrechen"; 29 | /* Choose button */ 30 | "Choose" = "Auswählen"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/el.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Aλλaγή θεσης και μεγεθoυς"; 27 | /* Cancel button */ 28 | "Cancel" = "Ακύρωση"; 29 | /* Choose button */ 30 | "Choose" = "Eπιλoγή"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/en.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Move and Scale"; 27 | /* Cancel button */ 28 | "Cancel" = "Cancel"; 29 | /* Choose button */ 30 | "Choose" = "Choose"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/es.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Mover y escalar"; 27 | /* Cancel button */ 28 | "Cancel" = "Cancelar"; 29 | /* Choose button */ 30 | "Choose" = "Usar"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/et.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Muuda suurust"; 27 | /* Cancel button */ 28 | "Cancel" = "Tühista"; 29 | /* Choose button */ 30 | "Choose" = "Vali"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/fa.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "جابجایی و بزرگ نمایی"; 27 | /* Cancel button */ 28 | "Cancel" = "لغو"; 29 | /* Choose button */ 30 | "Choose" = "انتخاب"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/fi.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Siirrä ja skaalaa"; 27 | /* Cancel button */ 28 | "Cancel" = "Kumoa"; 29 | /* Choose button */ 30 | "Choose" = "Valitse"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/fil.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Galawin at I-scale"; 27 | /* Cancel button */ 28 | "Cancel" = "Kanselahin"; 29 | /* Choose button */ 30 | "Choose" = "Pumili"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/fr.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Recadrer"; 27 | /* Cancel button */ 28 | "Cancel" = "Annuler"; 29 | /* Choose button */ 30 | "Choose" = "Choisir"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/he.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "הזז/י והתאם/י גודל"; 27 | /* Cancel button */ 28 | "Cancel" = "ביטול"; 29 | /* Choose button */ 30 | "Choose" = "בחר/י"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/hi.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "हिलाकर आकार बदलें"; 27 | /* Cancel button */ 28 | "Cancel" = "रद्द करें"; 29 | /* Choose button */ 30 | "Choose" = "चुनें"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/hr.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Pomaknite i podesite"; 27 | /* Cancel button */ 28 | "Cancel" = "Poništi"; 29 | /* Choose button */ 30 | "Choose" = "Odaberi"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/hu.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Mozgatás és méretezés"; 27 | /* Cancel button */ 28 | "Cancel" = "Mégsem"; 29 | /* Choose button */ 30 | "Choose" = "Kiválasztás"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/id.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Geser dan Ubah Skala"; 27 | /* Cancel button */ 28 | "Cancel" = "Batalkan"; 29 | /* Choose button */ 30 | "Choose" = "Pilih"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/it.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Sposta e ridimensiona"; 27 | /* Cancel button */ 28 | "Cancel" = "Annulla"; 29 | /* Choose button */ 30 | "Choose" = "Scegli"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ja.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "移動と拡大縮小"; 27 | /* Cancel button */ 28 | "Cancel" = "キャンセル"; 29 | /* Choose button */ 30 | "Choose" = "選択"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ko.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "이동 및 크기 조절"; 27 | /* Cancel button */ 28 | "Cancel" = "취소"; 29 | /* Choose button */ 30 | "Choose" = "선택"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/lt.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Judinti ir keisti mastelį"; 27 | /* Cancel button */ 28 | "Cancel" = "Atšaukti"; 29 | /* Choose button */ 30 | "Choose" = "Pasirinkti"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/lv.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Izgriez attēlu"; 27 | /* Cancel button */ 28 | "Cancel" = "Atcelt"; 29 | /* Choose button */ 30 | "Choose" = "Izvēlēties"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/mk.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Придвижи и одреди размер"; 27 | /* Cancel button */ 28 | "Cancel" = "Откажи"; 29 | /* Choose button */ 30 | "Choose" = "Избери"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ms.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Alih dan Skala"; 27 | /* Cancel button */ 28 | "Cancel" = "Batal"; 29 | /* Choose button */ 30 | "Choose" = "Pilih"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/nb.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Flytt og skaler"; 27 | /* Cancel button */ 28 | "Cancel" = "Avbryt"; 29 | /* Choose button */ 30 | "Choose" = "Velg"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/nl.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Verplaats en wijzig grootte"; 27 | /* Cancel button */ 28 | "Cancel" = "Annuleer"; 29 | /* Choose button */ 30 | "Choose" = "Kies"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/pl.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Wybierz kadr"; 27 | /* Cancel button */ 28 | "Cancel" = "Anuluj"; 29 | /* Choose button */ 30 | "Choose" = "Wybierz"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/pt.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Mover e dimensionar"; 27 | /* Cancel button */ 28 | "Cancel" = "Cancelar"; 29 | /* Choose button */ 30 | "Choose" = "Escolher"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/pt_BR.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Mover e Redimensionar"; 27 | /* Cancel button */ 28 | "Cancel" = "Cancelar"; 29 | /* Choose button */ 30 | "Choose" = "Escolher"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/pt_PT.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Mover e dimensionar"; 27 | /* Cancel button */ 28 | "Cancel" = "Cancelar"; 29 | /* Choose button */ 30 | "Choose" = "Escolher"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ro.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Mutaţi și redimensionaţi"; 27 | /* Cancel button */ 28 | "Cancel" = "Anulaţi"; 29 | /* Choose button */ 30 | "Choose" = "Selectaţi"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/ru.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Cдвиг и масштаб"; 27 | /* Cancel button */ 28 | "Cancel" = "Отменить"; 29 | /* Choose button */ 30 | "Choose" = "Выбрать"; 31 | 32 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/sk.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Premiestniť a zmeniť veľkosť"; 27 | /* Cancel button */ 28 | "Cancel" = "Zrušiť"; 29 | /* Choose button */ 30 | "Choose" = "Vybrať"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/sl.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Posunutie a veľkosť"; 27 | /* Cancel button */ 28 | "Cancel" = "Zrušiť"; 29 | /* Choose button */ 30 | "Choose" = "Vybrať"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/sr.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Pomeri i podesi"; 27 | /* Cancel button */ 28 | "Cancel" = "Odustani"; 29 | /* Choose button */ 30 | "Choose" = "Izaberi"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/sv.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Flytta och skalanpassa"; 27 | /* Cancel button */ 28 | "Cancel" = "Avbryt"; 29 | /* Choose button */ 30 | "Choose" = "Välj"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/th.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "เลื่อนและปรับขนาด"; 27 | /* Cancel button */ 28 | "Cancel" = "ยกเลิก"; 29 | /* Choose button */ 30 | "Choose" = "เลือก"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/tr.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Taşı ve Ölçekle"; 27 | /* Cancel button */ 28 | "Cancel" = "Vazgeç"; 29 | /* Choose button */ 30 | "Choose" = "Seç"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/uk.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Pyxaйтe i вiдмipяйтe"; 27 | /* Cancel button */ 28 | "Cancel" = "Скасувати"; 29 | /* Choose button */ 30 | "Choose" = "Вибрати"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/vi.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "Di chuyển và Chia tý lệ"; 27 | /* Cancel button */ 28 | "Cancel" = "Hủy"; 29 | /* Choose button */ 30 | "Choose" = "Chọn"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/zh-Hans.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "移动和缩放"; 27 | /* Cancel button */ 28 | "Cancel" = "取消"; 29 | /* Choose button */ 30 | "Choose" = "选取"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/zh-Hant.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "移動和縮放"; 27 | /* Cancel button */ 28 | "Cancel" = "取消"; 29 | /* Choose button */ 30 | "Choose" = "選擇"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageCropperStrings.bundle/zh.lproj/RSKImageCropper.strings: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageCropper.strings 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /* Move and Scale label */ 26 | "Move and Scale" = "移动和缩放"; 27 | /* Cancel button */ 28 | "Cancel" = "取消"; 29 | /* Choose button */ 30 | "Choose" = "选择"; 31 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageScrollView.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: RSKImageScrollView.h 3 | Abstract: Centers image within the scroll view and configures image sizing and display. 4 | Version: 1.5 modified by Ruslan Skorb on 11/26/24. 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2012 Apple Inc. All Rights Reserved. 45 | Copyright (C) 2014-present Ruslan Skorb. All Rights Reserved. 46 | 47 | */ 48 | 49 | #import 50 | 51 | NS_HEADER_AUDIT_BEGIN(nullability, sendability) 52 | 53 | @protocol RSKImageScrollViewDelegate; 54 | 55 | /** 56 | A view that allows the scrolling and zooming of its image. 57 | */ 58 | NS_SWIFT_UI_ACTOR 59 | @interface RSKImageScrollView : UIScrollView 60 | 61 | /** 62 | A Boolean value that determines whether the image will always fill the available space. Default value is `NO`. 63 | */ 64 | @property (nonatomic, assign) BOOL aspectFill; 65 | 66 | /** 67 | An image for scrolling and zooming. Default value is `nil`. 68 | */ 69 | @property (nonatomic, nullable, strong) UIImage *image; 70 | 71 | /** 72 | The delegate of the image scroll view. 73 | 74 | @discussion The delegate must adopt the `RSKImageScrollViewDelegate` protocol. The `RSKImageScrollView` class, which doesn’t retain the delegate, invokes each protocol method the delegate implements. 75 | */ 76 | @property (nonatomic, nullable, weak) id imageScrollViewDelegate; 77 | 78 | /** 79 | The logical dimensions, in points, of the image. Default value is `CGSizeZero`. 80 | 81 | @discussion Can be set to a value different from `image.size`. 82 | */ 83 | @property (nonatomic, assign) CGSize imageSize; 84 | 85 | /** 86 | The background color of the image view. Default value is `nil`, which results in a transparent color. 87 | 88 | @discussion Changes to this property can be animated. 89 | */ 90 | @property (nonatomic, nullable, strong) UIColor *imageViewBackgroundColor; 91 | 92 | /** 93 | The coordinate space of the image view. 94 | */ 95 | @property (nonatomic, readonly) id imageViewCoordinateSpace; 96 | 97 | /** 98 | The current frame of the image view in the coordinate space of the image scroll view. 99 | */ 100 | @property (nonatomic, readonly) CGRect imageViewFrame; 101 | 102 | /** 103 | Sets the current scale factor applied to the image and offset from the image’s origin to the initial value. 104 | 105 | @param animated `YES` to animate the transition to the new scale and content offset, `NO` to make the transition immediate. 106 | */ 107 | - (void)setInitialZoomScaleAndContentOffsetAnimated:(BOOL)animated; 108 | 109 | /** 110 | Zooms to a specific location in the image so that it’s visible in the image scroll view. 111 | 112 | @param location A point defining a location in the image. The point should be in the coordinate space of the image scroll view. 113 | @param animated `YES` if the scrolling should be animated, `NO` if it should be immediate. 114 | */ 115 | - (void)zoomToLocation:(CGPoint)location animated:(BOOL)animated; 116 | 117 | @end 118 | 119 | NS_HEADER_AUDIT_END(nullability, sendability) 120 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKImageScrollViewDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKImageScrollViewDelegate.h 3 | // 4 | // Copyright © 2022-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | NS_ASSUME_NONNULL_BEGIN 28 | 29 | /** 30 | The interface for the delegate of an image scroll view. 31 | */ 32 | NS_SWIFT_UI_ACTOR 33 | @protocol RSKImageScrollViewDelegate 34 | 35 | @optional 36 | 37 | /** 38 | Tells the delegate when the user scrolls the image within the image scroll view. 39 | */ 40 | - (void)imageScrollViewDidScroll; 41 | 42 | /** 43 | Tells the delegate when the image scroll view is about to start scrolling the image. 44 | */ 45 | - (void)imageScrollViewWillBeginDragging; 46 | 47 | /** 48 | Tells the delegate when dragging ended in the image scroll view. 49 | 50 | @param willDecelerate `YES` if the scrolling movement will continue, but decelerate, after a touch-up gesture during a dragging operation. If the value is `NO`, scrolling stops immediately upon touch-up. 51 | */ 52 | - (void)imageScrollViewDidEndDragging:(BOOL)willDecelerate; 53 | 54 | /** 55 | Tells the delegate that the image scroll view ended decelerating the scrolling movement. 56 | */ 57 | - (void)imageScrollViewDidEndDecelerating; 58 | 59 | /** 60 | Tells the delegate that zooming of the image in the image scroll view is about to commence. 61 | */ 62 | - (void)imageScrollViewWillBeginZooming; 63 | 64 | /** 65 | Tells the delegate when zooming of the image in the image scroll view completed. 66 | */ 67 | - (void)imageScrollViewDidEndZooming; 68 | 69 | @end 70 | 71 | NS_ASSUME_NONNULL_END 72 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKInternalUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKInternalUtility.h 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | NS_HEADER_AUDIT_BEGIN(nullability, sendability) 28 | 29 | /** 30 | Returns a localized version of the string designated by the specified key and residing in the RSKImageCropper table. 31 | 32 | @param key The key for a string in the RSKImageCropper table. 33 | @param comment The comment to place above the key-value pair in the strings file. 34 | 35 | @return A localized version of the string designated by key in the RSKImageCropper table. 36 | */ 37 | FOUNDATION_EXPORT NSString * RSKLocalizedString(NSString *key, NSString *comment); 38 | 39 | @interface RSKInternalUtility : NSObject 40 | 41 | /** 42 | Returns the NSBundle object for returning localized strings. 43 | 44 | @return The NSBundle object for returning localized strings, or nil if the bundle is not found on the system. 45 | 46 | @discussion We assume a convention of a bundle named RSKImageCropperStrings.bundle, otherwise we 47 | return the bundle associated with the RSKInternalUtility class. 48 | */ 49 | + (nullable NSBundle *)bundleForStrings; 50 | 51 | @end 52 | 53 | NS_HEADER_AUDIT_END(nullability, sendability) 54 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKInternalUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKInternalUtility.m 3 | // 4 | // Copyright © 2015-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "RSKInternalUtility.h" 26 | 27 | NSString * RSKLocalizedString(NSString *key, NSString *comment) 28 | { 29 | return [[[RSKInternalUtility class] bundleForStrings] localizedStringForKey:key value:key table:@"RSKImageCropper"]; 30 | } 31 | 32 | @implementation RSKInternalUtility 33 | 34 | + (NSBundle *)bundleForStrings 35 | { 36 | static NSBundle *bundle; 37 | 38 | static dispatch_once_t onceToken; 39 | dispatch_once(&onceToken, ^{ 40 | NSBundle *resourcesBundle; 41 | #ifdef SWIFTPM_MODULE_BUNDLE 42 | resourcesBundle = SWIFTPM_MODULE_BUNDLE; 43 | #else 44 | resourcesBundle = [NSBundle bundleForClass:[self class]]; 45 | #endif 46 | NSString *stringsBundlePath = [resourcesBundle pathForResource:@"RSKImageCropperStrings" ofType:@"bundle"]; 47 | bundle = [NSBundle bundleWithPath:stringsBundlePath] ?: resourcesBundle; 48 | }); 49 | 50 | return bundle; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKTouchView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSKTouchView.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | NS_HEADER_AUDIT_BEGIN(nullability, sendability) 28 | 29 | NS_SWIFT_UI_ACTOR 30 | @interface RSKTouchView : UIView 31 | 32 | @property (weak, nonatomic, nullable) UIView *receiver; 33 | 34 | @end 35 | 36 | NS_HEADER_AUDIT_END(nullability, sendability) 37 | -------------------------------------------------------------------------------- /RSKImageCropper/RSKTouchView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSKTouchView.m 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "RSKTouchView.h" 26 | 27 | @implementation RSKTouchView 28 | 29 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 30 | { 31 | if ([self pointInside:point withEvent:event]) { 32 | return self.receiver; 33 | } 34 | return nil; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /RSKImageCropper/UIImage+RSKImageCropper.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+RSKImageCropper.h 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | NS_ASSUME_NONNULL_BEGIN 28 | 29 | @interface UIImage (RSKImageCropper) 30 | 31 | // Fix the orientation of the image. 32 | - (nullable UIImage *)fixOrientation; 33 | 34 | // Rotate the image clockwise around the center by the angle, in radians. 35 | - (nullable UIImage *)rotateByAngle:(CGFloat)angleInRadians; 36 | 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /RSKImageCropper/UIImage+RSKImageCropper.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+RSKImageCropper.m 3 | // 4 | // Copyright © 2014-present Ruslan Skorb. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import "UIImage+RSKImageCropper.h" 26 | 27 | @implementation UIImage (RSKImageCropper) 28 | 29 | - (UIImage *)fixOrientation 30 | { 31 | // No-op if the orientation is already correct. 32 | if (self.imageOrientation == UIImageOrientationUp) { 33 | return self; 34 | } 35 | 36 | // We need to calculate the proper transformation to make the image upright. 37 | // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 38 | CGAffineTransform transform = CGAffineTransformIdentity; 39 | 40 | switch (self.imageOrientation) { 41 | case UIImageOrientationDown: 42 | case UIImageOrientationDownMirrored: 43 | transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); 44 | transform = CGAffineTransformRotate(transform, M_PI); 45 | break; 46 | 47 | case UIImageOrientationLeft: 48 | case UIImageOrientationLeftMirrored: 49 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 50 | transform = CGAffineTransformRotate(transform, M_PI_2); 51 | break; 52 | 53 | case UIImageOrientationRight: 54 | case UIImageOrientationRightMirrored: 55 | transform = CGAffineTransformTranslate(transform, 0, self.size.height); 56 | transform = CGAffineTransformRotate(transform, -M_PI_2); 57 | break; 58 | case UIImageOrientationUp: 59 | case UIImageOrientationUpMirrored: 60 | break; 61 | } 62 | 63 | switch (self.imageOrientation) { 64 | case UIImageOrientationUpMirrored: 65 | case UIImageOrientationDownMirrored: 66 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 67 | transform = CGAffineTransformScale(transform, -1, 1); 68 | break; 69 | 70 | case UIImageOrientationLeftMirrored: 71 | case UIImageOrientationRightMirrored: 72 | transform = CGAffineTransformTranslate(transform, self.size.height, 0); 73 | transform = CGAffineTransformScale(transform, -1, 1); 74 | break; 75 | case UIImageOrientationUp: 76 | case UIImageOrientationDown: 77 | case UIImageOrientationLeft: 78 | case UIImageOrientationRight: 79 | break; 80 | } 81 | 82 | // Now we draw the underlying CGImage into a new context, applying the transform 83 | // calculated above. 84 | CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, 85 | CGImageGetBitsPerComponent(self.CGImage), 0, 86 | CGImageGetColorSpace(self.CGImage), 87 | CGImageGetBitmapInfo(self.CGImage)); 88 | CGContextConcatCTM(ctx, transform); 89 | switch (self.imageOrientation) { 90 | case UIImageOrientationLeft: 91 | case UIImageOrientationLeftMirrored: 92 | case UIImageOrientationRight: 93 | case UIImageOrientationRightMirrored: 94 | CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage); 95 | break; 96 | 97 | default: 98 | CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage); 99 | break; 100 | } 101 | 102 | // And now we just create a new UIImage from the drawing context. 103 | CGImageRef cgimg = CGBitmapContextCreateImage(ctx); 104 | UIImage *img = [UIImage imageWithCGImage:cgimg]; 105 | CGContextRelease(ctx); 106 | CGImageRelease(cgimg); 107 | 108 | return img; 109 | } 110 | 111 | - (UIImage *)rotateByAngle:(CGFloat)angleInRadians 112 | { 113 | // Calculate the size of the rotated image. 114 | CGRect rotatedImageFrame = CGRectMake(0.0, 0.0, self.size.width, self.size.height); 115 | CGSize rotatedImageSize = CGRectApplyAffineTransform(rotatedImageFrame, CGAffineTransformMakeRotation(angleInRadians)).size; 116 | 117 | // Create a bitmap-based graphics context. 118 | UIGraphicsBeginImageContextWithOptions(rotatedImageSize, NO, self.scale); 119 | 120 | CGContextRef context = UIGraphicsGetCurrentContext(); 121 | 122 | // Move the origin of the user coordinate system in the context to the middle. 123 | CGContextTranslateCTM(context, rotatedImageSize.width / 2, rotatedImageSize.height / 2); 124 | 125 | // Rotates the user coordinate system in the context. 126 | CGContextRotateCTM(context, angleInRadians); 127 | 128 | // Flip the handedness of the user coordinate system in the context. 129 | CGContextScaleCTM(context, 1.0, -1.0); 130 | 131 | // Draw the image into the context. 132 | CGContextDrawImage(context, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), self.CGImage); 133 | 134 | UIImage *rotatedImage = UIGraphicsGetImageFromCurrentImageContext(); 135 | 136 | UIGraphicsEndImageContext(); 137 | 138 | return rotatedImage; 139 | } 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/CGGeometry+RSKImageCropper.h: -------------------------------------------------------------------------------- 1 | ../../CGGeometry+RSKImageCropper.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/RSKImageCropViewController+Protected.h: -------------------------------------------------------------------------------- 1 | ../../RSKImageCropViewController+Protected.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/RSKImageCropViewController.h: -------------------------------------------------------------------------------- 1 | ../../RSKImageCropViewController.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/RSKImageScrollView.h: -------------------------------------------------------------------------------- 1 | ../../RSKImageScrollView.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/RSKImageScrollViewDelegate.h: -------------------------------------------------------------------------------- 1 | ../../RSKImageScrollViewDelegate.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/RSKInternalUtility.h: -------------------------------------------------------------------------------- 1 | ../../RSKInternalUtility.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/RSKTouchView.h: -------------------------------------------------------------------------------- 1 | ../../RSKTouchView.h -------------------------------------------------------------------------------- /RSKImageCropper/include/RSKImageCropper/UIImage+RSKImageCropper.h: -------------------------------------------------------------------------------- 1 | ../../UIImage+RSKImageCropper.h -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruslanskorb/RSKImageCropper/87506690345d0f666bfdabdd8790144c7992589c/Screenshot.png --------------------------------------------------------------------------------