├── .gitignore ├── .npmignore ├── .prettierrc.json ├── Example ├── .bundle │ └── config ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── App.tsx ├── Gemfile ├── Gemfile.lock ├── README.md ├── __tests__ │ └── App.test.tsx ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── ReactNativeFlipper.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ ├── rn_edit_text_material.xml │ │ │ │ ├── sticker0.png │ │ │ │ ├── sticker1.png │ │ │ │ ├── sticker10.png │ │ │ │ ├── sticker2.png │ │ │ │ ├── sticker3.png │ │ │ │ ├── sticker4.png │ │ │ │ ├── sticker5.png │ │ │ │ ├── sticker6.png │ │ │ │ ├── sticker7.png │ │ │ │ ├── sticker8.png │ │ │ │ └── sticker9.png │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── ReactNativeFlipper.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── assets │ └── photo.jpg ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Example.xcscheme │ ├── Example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── Example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ ├── ExampleTests │ │ ├── ExampleTests.m │ │ └── Info.plist │ ├── Podfile │ ├── Podfile.lock │ └── Resources │ │ ├── sticker0.png │ │ ├── sticker1.png │ │ ├── sticker10.png │ │ ├── sticker2.png │ │ ├── sticker3.png │ │ ├── sticker4.png │ │ ├── sticker5.png │ │ ├── sticker6.png │ │ ├── sticker7.png │ │ ├── sticker8.png │ │ └── sticker9.png ├── jest.config.js ├── metro.config.js ├── package.json ├── react-native.config.js └── tsconfig.json ├── LICENSE ├── Makefile ├── README.md ├── android ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ ├── com │ │ └── ahmedadeltito │ │ │ └── photoeditor │ │ │ ├── BaseActivity.java │ │ │ ├── ColorPickerAdapter.java │ │ │ ├── EmojiAdapter.java │ │ │ ├── EmojiFragment.java │ │ │ ├── GalleryUtils.java │ │ │ ├── ImageAdapter.java │ │ │ ├── ImageFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── MediaActivity.java │ │ │ ├── PhotoEditorActivity.java │ │ │ ├── TranslationService.java │ │ │ ├── UtilFunctions.java │ │ │ └── widget │ │ │ ├── RealtimeBlurView.java │ │ │ ├── SlidingUpPanelLayout.java │ │ │ └── ViewDragHelper.java │ └── ui │ │ └── photoeditor │ │ ├── RNPhotoEditorModule.java │ │ └── RNPhotoEditorPackage.java │ └── res │ ├── drawable-xhdpi │ ├── aa.png │ ├── bb.png │ ├── c.png │ ├── cc.png │ ├── d.png │ ├── dd.png │ ├── e.png │ ├── ee.png │ ├── i.png │ ├── j.png │ ├── k.png │ ├── l.png │ ├── m.png │ ├── n.png │ ├── o.png │ ├── p.png │ ├── q.png │ ├── r.png │ ├── s.png │ ├── t.png │ ├── u.png │ ├── v.png │ ├── w.png │ ├── x.png │ ├── y.png │ └── z.png │ ├── drawable │ ├── above_shadow.xml │ ├── below_shadow.xml │ ├── fading_shadow.xml │ └── rounded_border_text_view.xml │ ├── layout │ ├── activity_main.xml │ ├── activity_photo_editor.xml │ ├── add_text_popup_window.xml │ ├── color_picker_item_list.xml │ ├── fragment_main_photo_edit_emoji.xml │ ├── fragment_main_photo_edit_image.xml │ ├── fragment_photo_edit_emoji_item_list.xml │ └── fragment_photo_edit_image_item_list.xml │ ├── raw │ ├── emojioneandroid │ ├── eventtusicons │ ├── font_awesome_solid.otf │ └── icomoon.ttf │ └── values │ ├── arrays.xml │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── assets ├── android.gif └── ios.gif ├── index.d.ts ├── index.tsx ├── ios ├── RNImageEditor.podspec ├── RNPhotoEditor.h ├── RNPhotoEditor.m └── RNPhotoEditor.xcodeproj │ └── project.pbxproj ├── package.json ├── photo-editor ├── LICENSE ├── Photo Editor │ ├── LICENSE.md │ ├── Photo Editor.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Photo Editor.xcscheme │ ├── Photo Editor │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ ├── ColorCollectionViewCell.swift │ │ ├── ColorCollectionViewCell.xib │ │ ├── ColorsCollectionViewDelegate.swift │ │ ├── CropRectView.swift │ │ ├── CropView.swift │ │ ├── CropViewController.swift │ │ ├── EmojiCollectionViewCell.swift │ │ ├── EmojiCollectionViewCell.xib │ │ ├── EmojisCollectionViewDelegate.swift │ │ ├── GradientView.swift │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PhotoCropEditorBorder.png │ │ ├── PhotoCropEditorBorder@2x.png │ │ ├── PhotoCropEditorBorder@3x.png │ │ ├── PhotoEditor+Controls.swift │ │ ├── PhotoEditor+Crop.swift │ │ ├── PhotoEditor+Drawing.swift │ │ ├── PhotoEditor+Font.swift │ │ ├── PhotoEditor+Gestures.swift │ │ ├── PhotoEditor+Keyboard.swift │ │ ├── PhotoEditor+StickersViewController.swift │ │ ├── PhotoEditor+UITextView.swift │ │ ├── PhotoEditorViewController.swift │ │ ├── PhotoEditorViewController.xib │ │ ├── Protocols.swift │ │ ├── ResizeControl.swift │ │ ├── StickerCollectionViewCell.swift │ │ ├── StickerCollectionViewCell.xib │ │ ├── StickersViewController.swift │ │ ├── StickersViewController.xib │ │ ├── TranslationService.swift │ │ ├── UIImage+Crop.swift │ │ ├── UIImage+Size.swift │ │ ├── UIImageView+Alpha.swift │ │ ├── UIView+Image.swift │ │ └── icomoon.ttf │ └── iOSPhotoEditor.podspec └── iOSPhotoEditor.podspec └── react-native-image-editor.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # OSX 3 | # 4 | .DS_Store 5 | 6 | # node.js 7 | # 8 | node_modules/ 9 | npm-debug.log 10 | yarn-error.log 11 | package-lock.json 12 | yarn.lock 13 | 14 | # Xcode 15 | # 16 | build/ 17 | *.pbxuser 18 | !default.pbxuser 19 | *.mode1v3 20 | !default.mode1v3 21 | *.mode2v3 22 | !default.mode2v3 23 | *.perspectivev3 24 | !default.perspectivev3 25 | xcuserdata 26 | *.xccheckout 27 | *.moved-aside 28 | DerivedData 29 | *.hmap 30 | *.ipa 31 | *.xcuserstate 32 | project.xcworkspace 33 | 34 | 35 | # Android/IntelliJ 36 | # 37 | build/ 38 | .idea 39 | .gradle 40 | local.properties 41 | *.iml 42 | 43 | # BUCK 44 | buck-out/ 45 | \.buckd/ 46 | *.keystore 47 | 48 | .history/* 49 | ios/Pods/* 50 | ios/Podfile.lock 51 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Example/ 2 | assets/ 3 | android/build 4 | node_modules/ 5 | npm-debug.log 6 | package-lock.json -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "tabWidth": 4, 4 | "semi": false, 5 | "trailingComma": "none", 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": true, 8 | "printWidth": 100 9 | } 10 | -------------------------------------------------------------------------------- /Example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /Example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | /ios/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | -------------------------------------------------------------------------------- /Example/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /Example/App.tsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {StyleSheet, Text, View, TouchableOpacity} from 'react-native'; 3 | import {Image} from 'react-native'; 4 | import ImageEditor from '@thienmd/react-native-image-editor'; 5 | import RNFS from 'react-native-fs'; 6 | import RNFetchBlob from 'react-native-blob-util'; 7 | 8 | type Props = { 9 | path: string; 10 | colors?: string[]; 11 | stickers?: string[]; 12 | hiddenControls?: string[]; 13 | onDone?: (e: any) => void; 14 | onCancel?: (e: any) => void; 15 | }; 16 | 17 | export default class App extends Component { 18 | _onPress = () => { 19 | ImageEditor.Edit({ 20 | path: RNFS.DocumentDirectoryPath + '/photo1.jpg', 21 | stickers: [ 22 | 'sticker0', 23 | 'sticker1', 24 | 'sticker2', 25 | 'sticker3', 26 | 'sticker4', 27 | 'sticker5', 28 | 'sticker6', 29 | 'sticker7', 30 | 'sticker8', 31 | 'sticker9', 32 | 'sticker10', 33 | ], 34 | // hiddenControls: [ 35 | // 'clear', 36 | // 'crop', 37 | // 'draw', 38 | // 'save', 39 | // 'share', 40 | // 'sticker', 41 | // 'text', 42 | // ], 43 | colors: undefined, 44 | onDone: () => { 45 | console.log('on done'); 46 | }, 47 | onCancel: () => { 48 | console.log('on cancel'); 49 | }, 50 | }); 51 | }; 52 | 53 | componentDidMount() { 54 | let photoPath = RNFS.DocumentDirectoryPath + '/photo1.jpg'; 55 | let binaryFile = Image.resolveAssetSource(require('./assets/photo.jpg')); 56 | 57 | RNFetchBlob.config({fileCache: true}) 58 | .fetch('GET', binaryFile.uri) 59 | .then((resp: {path: () => string}) => { 60 | RNFS.moveFile(resp.path(), photoPath) 61 | .then(() => { 62 | console.log('FILE WRITTEN!'); 63 | }) 64 | .catch(err => { 65 | console.log(err.message); 66 | }); 67 | }) 68 | .catch((err: {message: any}) => { 69 | console.log(err.message); 70 | }); 71 | } 72 | 73 | render() { 74 | return ( 75 | 76 | 77 | Click 78 | 79 | 80 | ); 81 | } 82 | } 83 | 84 | const styles = StyleSheet.create({ 85 | container: { 86 | flex: 1, 87 | justifyContent: 'center', 88 | alignItems: 'center', 89 | backgroundColor: '#F5FCFF', 90 | }, 91 | }); 92 | -------------------------------------------------------------------------------- /Example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | gem 'cocoapods', '~> 1.13' 7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' 8 | -------------------------------------------------------------------------------- /Example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (6.1.7.6) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.5) 13 | public_suffix (>= 2.0.2, < 6.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | atomos (0.1.3) 18 | claide (1.1.0) 19 | cocoapods (1.14.3) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.14.3) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 2.1, < 3.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.6.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 2.3.0, < 3.0) 36 | xcodeproj (>= 1.23.0, < 2.0) 37 | cocoapods-core (1.14.3) 38 | activesupport (>= 5.0, < 8) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (2.1) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.2.2) 58 | escape (0.0.4) 59 | ethon (0.16.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.16.3) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.14.1) 67 | concurrent-ruby (~> 1.0) 68 | json (2.6.3) 69 | minitest (5.20.0) 70 | molinillo (0.8.0) 71 | nanaimo (0.3.0) 72 | nap (1.1.0) 73 | netrc (0.11.0) 74 | public_suffix (4.0.7) 75 | rexml (3.2.6) 76 | ruby-macho (2.5.1) 77 | typhoeus (1.4.1) 78 | ethon (>= 0.9.0) 79 | tzinfo (2.0.6) 80 | concurrent-ruby (~> 1.0) 81 | xcodeproj (1.23.0) 82 | CFPropertyList (>= 2.3.3, < 4.0) 83 | atomos (~> 0.1.3) 84 | claide (>= 1.0.2, < 2.0) 85 | colored2 (~> 3.1) 86 | nanaimo (~> 0.3.0) 87 | rexml (~> 3.2.4) 88 | zeitwerk (2.6.12) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | activesupport (>= 6.1.7.3, < 7.1.0) 95 | cocoapods (~> 1.13) 96 | 97 | RUBY VERSION 98 | ruby 2.6.10p210 99 | 100 | BUNDLED WITH 101 | 1.17.2 102 | -------------------------------------------------------------------------------- /Example/README.md: -------------------------------------------------------------------------------- 1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). 2 | 3 | # Getting Started 4 | 5 | >**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. 6 | 7 | ## Step 1: Start the Metro Server 8 | 9 | First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. 10 | 11 | To start Metro, run the following command from the _root_ of your React Native project: 12 | 13 | ```bash 14 | # using npm 15 | npm start 16 | 17 | # OR using Yarn 18 | yarn start 19 | ``` 20 | 21 | ## Step 2: Start your Application 22 | 23 | Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: 24 | 25 | ### For Android 26 | 27 | ```bash 28 | # using npm 29 | npm run android 30 | 31 | # OR using Yarn 32 | yarn android 33 | ``` 34 | 35 | ### For iOS 36 | 37 | ```bash 38 | # using npm 39 | npm run ios 40 | 41 | # OR using Yarn 42 | yarn ios 43 | ``` 44 | 45 | If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. 46 | 47 | This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. 48 | 49 | ## Step 3: Modifying your App 50 | 51 | Now that you have successfully run the app, let's modify it. 52 | 53 | 1. Open `App.tsx` in your text editor of choice and edit some lines. 54 | 2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes! 55 | 56 | For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! 57 | 58 | ## Congratulations! :tada: 59 | 60 | You've successfully run and modified your React Native App. :partying_face: 61 | 62 | ### Now what? 63 | 64 | - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). 65 | - If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). 66 | 67 | # Troubleshooting 68 | 69 | If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. 70 | 71 | # Learn More 72 | 73 | To learn more about React Native, take a look at the following resources: 74 | 75 | - [React Native Website](https://reactnative.dev) - learn more about React Native. 76 | - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. 77 | - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. 78 | - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. 79 | - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. 80 | -------------------------------------------------------------------------------- /Example/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: import explicitly to use the types shiped with jest. 10 | import {it} from '@jest/globals'; 11 | 12 | // Note: test renderer must be required after react-native. 13 | import renderer from 'react-test-renderer'; 14 | 15 | it('renders correctly', () => { 16 | renderer.create(); 17 | }); 18 | -------------------------------------------------------------------------------- /Example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "com.facebook.react" 3 | 4 | /** 5 | * This is the configuration block to customize your React Native Android app. 6 | * By default you don't need to apply any configuration, just uncomment the lines you need. 7 | */ 8 | react { 9 | /* Folders */ 10 | // The root of your project, i.e. where "package.json" lives. Default is '..' 11 | // root = file("../") 12 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 13 | // reactNativeDir = file("../node_modules/react-native") 14 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 15 | // codegenDir = file("../node_modules/@react-native/codegen") 16 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 17 | // cliFile = file("../node_modules/react-native/cli.js") 18 | 19 | /* Variants */ 20 | // The list of variants to that are debuggable. For those we're going to 21 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 22 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 23 | // debuggableVariants = ["liteDebug", "prodDebug"] 24 | 25 | /* Bundling */ 26 | // A list containing the node command and its flags. Default is just 'node'. 27 | // nodeExecutableAndArgs = ["node"] 28 | // 29 | // The command to run when bundling. By default is 'bundle' 30 | // bundleCommand = "ram-bundle" 31 | // 32 | // The path to the CLI configuration file. Default is empty. 33 | // bundleConfig = file(../rn-cli.config.js) 34 | // 35 | // The name of the generated asset file containing your JS bundle 36 | // bundleAssetName = "MyApplication.android.bundle" 37 | // 38 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 39 | // entryFile = file("../js/MyApplication.android.js") 40 | // 41 | // A list of extra flags to pass to the 'bundle' commands. 42 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 43 | // extraPackagerArgs = [] 44 | 45 | /* Hermes Commands */ 46 | // The hermes compiler command to run. By default it is 'hermesc' 47 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 48 | // 49 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 50 | // hermesFlags = ["-O", "-output-source-map"] 51 | } 52 | 53 | /** 54 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 55 | */ 56 | def enableProguardInReleaseBuilds = false 57 | 58 | /** 59 | * The preferred build flavor of JavaScriptCore (JSC) 60 | * 61 | * For example, to use the international variant, you can use: 62 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 63 | * 64 | * The international variant includes ICU i18n library and necessary data 65 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 66 | * give correct results when using with locales other than en-US. Note that 67 | * this variant is about 6MiB larger per architecture than default. 68 | */ 69 | def jscFlavor = 'org.webkit:android-jsc:+' 70 | 71 | android { 72 | ndkVersion rootProject.ext.ndkVersion 73 | 74 | compileSdkVersion rootProject.ext.compileSdkVersion 75 | 76 | namespace "com.example" 77 | defaultConfig { 78 | applicationId "com.example" 79 | minSdkVersion rootProject.ext.minSdkVersion 80 | targetSdkVersion rootProject.ext.targetSdkVersion 81 | versionCode 1 82 | versionName "1.0" 83 | } 84 | signingConfigs { 85 | debug { 86 | storeFile file('debug.keystore') 87 | storePassword 'android' 88 | keyAlias 'androiddebugkey' 89 | keyPassword 'android' 90 | } 91 | } 92 | buildTypes { 93 | debug { 94 | signingConfig signingConfigs.debug 95 | } 96 | release { 97 | // Caution! In production, you need to generate your own keystore file. 98 | // see https://reactnative.dev/docs/signed-apk-android. 99 | signingConfig signingConfigs.debug 100 | minifyEnabled enableProguardInReleaseBuilds 101 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 102 | } 103 | } 104 | } 105 | 106 | dependencies { 107 | // The version of react-native is set by the React Native Gradle Plugin 108 | implementation("com.facebook.react:react-android") 109 | 110 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") 111 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 112 | exclude group:'com.squareup.okhttp3', module:'okhttp' 113 | } 114 | 115 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") 116 | if (hermesEnabled.toBoolean()) { 117 | implementation("com.facebook.react:hermes-android") 118 | } else { 119 | implementation jscFlavor 120 | } 121 | } 122 | 123 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 124 | -------------------------------------------------------------------------------- /Example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/debug.keystore -------------------------------------------------------------------------------- /Example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /Example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Example/android/app/src/debug/java/com/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "Example"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Example/android/app/src/main/java/com/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Application; 4 | import com.facebook.react.PackageList; 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 9 | import com.facebook.react.defaults.DefaultReactNativeHost; 10 | import com.facebook.soloader.SoLoader; 11 | import java.util.List; 12 | 13 | public class MainApplication extends Application implements ReactApplication { 14 | 15 | private final ReactNativeHost mReactNativeHost = 16 | new DefaultReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | @SuppressWarnings("UnnecessaryLocalVariable") 25 | List packages = new PackageList(this).getPackages(); 26 | // Packages that cannot be autolinked yet can be added manually here, for example: 27 | // packages.add(new MyReactNativePackage()); 28 | return packages; 29 | } 30 | 31 | @Override 32 | protected String getJSMainModuleName() { 33 | return "index"; 34 | } 35 | 36 | @Override 37 | protected boolean isNewArchEnabled() { 38 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 39 | } 40 | 41 | @Override 42 | protected Boolean isHermesEnabled() { 43 | return BuildConfig.IS_HERMES_ENABLED; 44 | } 45 | }; 46 | 47 | @Override 48 | public ReactNativeHost getReactNativeHost() { 49 | return mReactNativeHost; 50 | } 51 | 52 | @Override 53 | public void onCreate() { 54 | super.onCreate(); 55 | SoLoader.init(this, /* native exopackage */ false); 56 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 57 | // If you opted-in for the New Architecture, we load the native entry point for this app. 58 | DefaultNewArchitectureEntryPoint.load(); 59 | } 60 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker0.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker1.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker10.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker2.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker3.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker4.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker5.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker6.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker7.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker8.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/drawable/sticker9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/drawable/sticker9.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Example 3 | 4 | -------------------------------------------------------------------------------- /Example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Example/android/app/src/release/java/com/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "33.0.0" 6 | minSdkVersion = 21 7 | compileSdkVersion = 33 8 | targetSdkVersion = 33 9 | 10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 11 | ndkVersion = "23.1.7779620" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath("com.android.tools.build:gradle") 19 | classpath("com.facebook.react:react-native-gradle-plugin") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.182.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=false 41 | 42 | # Use this property to enable or disable the Hermes JS engine. 43 | # If set to false, you will be using JSC instead. 44 | hermesEnabled=true 45 | -------------------------------------------------------------------------------- /Example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /Example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /Example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Example' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /Example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example", 3 | "displayName": "Example" 4 | } 5 | -------------------------------------------------------------------------------- /Example/assets/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/assets/photo.jpg -------------------------------------------------------------------------------- /Example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /Example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /Example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Example/ios/Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/ios/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/ios/Example.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/ios/Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /Example/ios/Example/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"Example"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | #if DEBUG 20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 21 | #else 22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 23 | #endif 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/ios/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Example 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 | NSPhotoLibraryAddUsageDescription 28 | Application needs permission to write photos... 29 | 30 | 31 | NSPhotoLibraryUsageDescription 32 | iOS 10 needs permission to write photos... 33 | 34 | NSAppTransportSecurity 35 | 36 | NSExceptionDomains 37 | 38 | localhost 39 | 40 | NSExceptionAllowsInsecureHTTPLoads 41 | 42 | 43 | 44 | 45 | NSLocationWhenInUseUsageDescription 46 | 47 | UILaunchStoryboardName 48 | LaunchScreen 49 | UIRequiredDeviceCapabilities 50 | 51 | armv7 52 | 53 | UISupportedInterfaceOrientations 54 | 55 | UIInterfaceOrientationPortrait 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | UIViewControllerBasedStatusBarAppearance 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Example/ios/Example/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/ios/Example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Example/ios/ExampleTests/ExampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface ExampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation ExampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Example/ios/ExampleTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command("node", ["-p", 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV["NO_FLIPPER"] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV["USE_FRAMEWORKS"] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | target "Example" do 29 | config = use_native_modules! 30 | 31 | # Flags change depending on the env values. 32 | flags = get_default_flags() 33 | 34 | use_react_native!( 35 | :path => config[:reactNativePath], 36 | # Hermes is now enabled by default. Disable by setting this flag to false. 37 | :hermes_enabled => flags[:hermes_enabled], 38 | :fabric_enabled => flags[:fabric_enabled], 39 | # Enables Flipper. 40 | # 41 | # Note that if you have use_frameworks! enabled, Flipper will not work and 42 | # you should disable the next line. 43 | :flipper_configuration => flipper_config, 44 | # An absolute path to your application root. 45 | :app_path => "#{Pod::Config.instance.installation_root}/..", 46 | ) 47 | pod "iOSPhotoEditor", :git => "https://github.com/ThienMD/photo-editor", :branch => "master" 48 | pod "react-native-blob-util", 49 | :path => "../node_modules/react-native-blob-util" 50 | target "ExampleTests" do 51 | inherit! :complete 52 | # Pods for testing 53 | end 54 | 55 | post_install do |installer| 56 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 57 | react_native_post_install( 58 | installer, 59 | config[:reactNativePath], 60 | :mac_catalyst_enabled => false, 61 | ) 62 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 63 | end 64 | end 65 | 66 | # Follow [Flipper iOS Setup Guidelines][https://fbflipper.com/docs/getting-started/ios-native/] 67 | # This is required because iOSPhotoEditor is implementated using Swift 68 | # $static_framework = ["FlipperKit", "Flipper", "Flipper-Folly", 69 | # "CocoaAsyncSocket", "ComponentKit", "Flipper-DoubleConversion", 70 | # "Flipper-Glog", "Flipper-PeerTalk", "Flipper-RSocket", "Yoga", "YogaKit", 71 | # "CocoaLibEvent", "OpenSSL-Universal", "boost-for-react-native"] 72 | 73 | # pre_install do |installer| 74 | # Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) { } 75 | # installer.pod_targets.each do |pod| 76 | # if $static_framework.include?(pod.name) 77 | # def pod.build_type 78 | # Pod::BuildType.static_library 79 | # end 80 | # end 81 | # end 82 | # end 83 | -------------------------------------------------------------------------------- /Example/ios/Resources/sticker0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker0.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker1.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker10.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker2.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker3.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker4.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker5.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker6.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker7.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker8.png -------------------------------------------------------------------------------- /Example/ios/Resources/sticker9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/Example/ios/Resources/sticker9.png -------------------------------------------------------------------------------- /Example/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /Example/metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://facebook.github.io/metro/docs/configuration 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /Example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest", 11 | "adb": "adb reverse tcp:8081 tcp:8081" 12 | }, 13 | "dependencies": { 14 | "react": "18.2.0", 15 | "react-native": "0.72.7", 16 | "react-native-blob-util": "^0.19.4", 17 | "react-native-fs": "2.18.0", 18 | "@thienmd/react-native-image-editor": "../" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.20.0", 22 | "@babel/preset-env": "^7.20.0", 23 | "@babel/runtime": "^7.20.0", 24 | "@react-native/eslint-config": "^0.72.2", 25 | "@react-native/metro-config": "^0.72.11", 26 | "@tsconfig/react-native": "^3.0.0", 27 | "@types/react": "^18.0.24", 28 | "@types/react-test-renderer": "^18.0.0", 29 | "babel-jest": "^29.2.1", 30 | "eslint": "^8.19.0", 31 | "jest": "^29.2.1", 32 | "metro-react-native-babel-preset": "0.76.8", 33 | "prettier": "^2.4.1", 34 | "react-test-renderer": "18.2.0", 35 | "typescript": "4.8.4" 36 | }, 37 | "engines": { 38 | "node": ">=16" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | dependencies: { 6 | [pak.name]: { 7 | root: path.join(__dirname, '..'), 8 | }, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /Example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/react-native/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # create git tag 2 | VERSION := 0.7.0 3 | GIT_COMMIT_MESSAGE := "Update features and fix bugs" 4 | .PHONY: all git-push-all tag npm-version npm-publish 5 | 6 | npm-version: 7 | @echo "Updating version..." 8 | @jq '.version = "$(VERSION)"' package.json > "tmp.json" && mv "tmp.json" package.json 9 | 10 | tag: 11 | git tag -a $(VERSION) -m "Release $(VERSION)" 12 | git push origin $(VERSION) 13 | 14 | git-push-all: 15 | git add . 16 | git commit -m $(GIT_COMMIT_MESSAGE) 17 | git push origin master 18 | 19 | all: git-push-all tag npm-version npm-publish 20 | 21 | npm-publish: 22 | npm publish -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | def safeExtGet(prop, fallback) { 4 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 5 | } 6 | 7 | buildscript { 8 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 9 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 10 | // module dependency in an application project. 11 | if (project == rootProject) { 12 | repositories { 13 | google() 14 | mavenCentral() 15 | maven { url 'https://www.jitpack.io' } 16 | } 17 | 18 | dependencies { 19 | classpath('com.android.tools.build:gradle:4.2.1') 20 | } 21 | } 22 | } 23 | 24 | android { 25 | compileSdkVersion safeExtGet('compileSdkVersion', 28) 26 | buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3') 27 | 28 | defaultConfig { 29 | minSdkVersion safeExtGet('minSdkVersion', 16) 30 | targetSdkVersion safeExtGet('targetSdkVersion', 28) 31 | versionCode 1 32 | versionName "1.0" 33 | } 34 | lintOptions { 35 | abortOnError false 36 | } 37 | } 38 | 39 | repositories { 40 | google() 41 | mavenCentral() 42 | maven { url 'https://www.jitpack.io' } 43 | } 44 | 45 | dependencies { 46 | implementation 'com.facebook.react:react-native:+' 47 | implementation 'com.github.prscX:photo-editor-android:master' 48 | implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1@aar' 49 | implementation 'com.nineoldandroids:library:2.4.0' 50 | implementation 'com.android.support:design:28.0.0' 51 | implementation 'com.android.support:appcompat-v7:28.0.0' 52 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 53 | implementation 'com.github.yalantis:ucrop:2.2.2-native' 54 | implementation 'com.android.support:exifinterface:27.1.1' 55 | } 56 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if %ERRORLEVEL% equ 0 goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if %ERRORLEVEL% equ 0 goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | set EXIT_CODE=%ERRORLEVEL% 84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 86 | exit /b %EXIT_CODE% 87 | 88 | :mainEnd 89 | if "%OS%"=="Windows_NT" endlocal 90 | 91 | :omega 92 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/ColorPickerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.animation.AnimatorSet; 4 | import android.animation.ObjectAnimator; 5 | import android.content.Context; 6 | import android.graphics.Color; 7 | import android.graphics.Path; 8 | import android.graphics.Rect; 9 | import android.graphics.drawable.Drawable; 10 | import android.graphics.drawable.LayerDrawable; 11 | import android.graphics.drawable.ShapeDrawable; 12 | import android.graphics.drawable.shapes.OvalShape; 13 | import android.graphics.drawable.shapes.PathShape; 14 | import android.view.LayoutInflater; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.view.animation.BounceInterpolator; 18 | import androidx.annotation.NonNull; 19 | import androidx.recyclerview.widget.RecyclerView; 20 | import java.util.List; 21 | import ui.photoeditor.R; 22 | 23 | /** 24 | * Created by Ahmed Adel on 5/8/17. 25 | */ 26 | 27 | public class ColorPickerAdapter extends RecyclerView.Adapter { 28 | 29 | private Context context; 30 | private LayoutInflater inflater; 31 | private List colorPickerColors; 32 | private OnColorPickerClickListener onColorPickerClickListener; 33 | private int selectedPosition = 0; 34 | 35 | public ColorPickerAdapter(@NonNull Context context, @NonNull List colorPickerColors) { 36 | this.context = context; 37 | this.inflater = LayoutInflater.from(context); 38 | this.colorPickerColors = colorPickerColors; 39 | } 40 | 41 | @Override 42 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 43 | View view = inflater.inflate(R.layout.color_picker_item_list, parent, false); 44 | return new ViewHolder(view); 45 | } 46 | 47 | @Override 48 | public void onBindViewHolder(ViewHolder holder, int position) { 49 | boolean isSelected = position == selectedPosition; // replace with your selection logic 50 | buildColorPickerView(holder.colorPickerView, colorPickerColors.get(position), isSelected); 51 | } 52 | 53 | @Override 54 | public int getItemCount() { 55 | return colorPickerColors.size(); 56 | } 57 | 58 | private ShapeDrawable createShapeDrawable(String shapeType, int size, int color) { 59 | ShapeDrawable shapeDrawable; 60 | 61 | if ("diamond".equals(shapeType)) { 62 | Path path = new Path(); 63 | path.moveTo(size / 2f, 0); 64 | path.lineTo(size, size / 2f); 65 | path.lineTo(size / 2f, size); 66 | path.lineTo(0, size / 2f); 67 | path.close(); 68 | 69 | shapeDrawable = new ShapeDrawable(new PathShape(path, size, size)); 70 | } else { 71 | shapeDrawable = new ShapeDrawable(new OvalShape()); 72 | } 73 | 74 | shapeDrawable.setIntrinsicHeight(size); 75 | shapeDrawable.setIntrinsicWidth(size); 76 | shapeDrawable.setBounds(new Rect(0, 0, size, size)); 77 | shapeDrawable.getPaint().setColor(color); 78 | 79 | return shapeDrawable; 80 | } 81 | 82 | private void buildColorPickerView(View view, int colorCode, boolean isSelected) { 83 | view.setVisibility(View.VISIBLE); 84 | String shapeType = isSelected ? "diamond" : "circle"; 85 | ShapeDrawable biggerShape = createShapeDrawable(shapeType, 20, colorCode); 86 | ShapeDrawable smallerShape = createShapeDrawable(shapeType, 5, Color.WHITE); 87 | smallerShape.setPadding(10, 10, 10, 10); 88 | 89 | Drawable[] drawables = { smallerShape, biggerShape }; 90 | 91 | LayerDrawable layerDrawable = new LayerDrawable(drawables); 92 | 93 | view.setBackgroundDrawable(layerDrawable); 94 | } 95 | 96 | public void setOnColorPickerClickListener( 97 | OnColorPickerClickListener onColorPickerClickListener 98 | ) { 99 | this.onColorPickerClickListener = onColorPickerClickListener; 100 | } 101 | 102 | class ViewHolder extends RecyclerView.ViewHolder { 103 | 104 | View colorPickerView; 105 | 106 | public ViewHolder(View itemView) { 107 | super(itemView); 108 | colorPickerView = itemView.findViewById(R.id.color_picker_view); 109 | itemView.setOnClickListener( 110 | new View.OnClickListener() { 111 | @Override 112 | public void onClick(View v) { 113 | if ( 114 | onColorPickerClickListener != null 115 | ) onColorPickerClickListener.onColorPickerClickListener( 116 | colorPickerColors.get(getAdapterPosition()) 117 | ); 118 | selectedPosition = getAdapterPosition(); 119 | notifyDataSetChanged(); 120 | } 121 | } 122 | ); 123 | } 124 | } 125 | 126 | public interface OnColorPickerClickListener { 127 | void onColorPickerClickListener(int colorCode); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/EmojiAdapter.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.content.Context; 4 | import androidx.annotation.NonNull; 5 | import androidx.recyclerview.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import java.util.List; 12 | 13 | import ui.photoeditor.R; 14 | 15 | /** 16 | * Created by Ahmed Adel on 5/5/17. 17 | */ 18 | 19 | public class EmojiAdapter extends RecyclerView.Adapter { 20 | 21 | // private Typeface emojiFont; 22 | private Context context; 23 | private List emojiIds; 24 | private LayoutInflater inflater; 25 | private OnEmojiClickListener onEmojiClickListener; 26 | 27 | public EmojiAdapter(@NonNull Context context, @NonNull List emojiIds) { 28 | this.context = context; 29 | this.inflater = LayoutInflater.from(context); 30 | this.emojiIds = emojiIds; 31 | // emojiFont = Typeface.createFromAsset(context.getAssets(), "emojione-android.ttf"); 32 | } 33 | 34 | @Override 35 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 36 | View view = inflater.inflate(R.layout.fragment_photo_edit_emoji_item_list, parent, false); 37 | return new ViewHolder(view); 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(ViewHolder holder, int position) { 42 | String emojiId = emojiIds.get(position); 43 | holder.emojiTextView.setText(convertEmoji(emojiId)); 44 | } 45 | 46 | @Override 47 | public int getItemCount() { 48 | return emojiIds.size(); 49 | } 50 | 51 | public void setOnEmojiClickListener(OnEmojiClickListener onEmojiClickListener) { 52 | this.onEmojiClickListener = onEmojiClickListener; 53 | } 54 | 55 | private String convertEmoji(String emoji) { 56 | String returnedEmoji = ""; 57 | try { 58 | int convertEmojiToInt = Integer.parseInt(emoji.substring(2), 16); 59 | returnedEmoji = getEmojiByUnicode(convertEmojiToInt); 60 | } catch (NumberFormatException e) { 61 | returnedEmoji = ""; 62 | } 63 | return returnedEmoji; 64 | } 65 | 66 | private String getEmojiByUnicode(int unicode) { 67 | return new String(Character.toChars(unicode)); 68 | } 69 | 70 | // stores and recycles views as they are scrolled off screen 71 | class ViewHolder extends RecyclerView.ViewHolder { 72 | TextView emojiTextView; 73 | 74 | public ViewHolder(View itemView) { 75 | super(itemView); 76 | emojiTextView = (TextView) itemView.findViewById(R.id.fragment_photo_edit_emoji_tv); 77 | emojiTextView.setTypeface(PhotoEditorActivity.emojiFont); 78 | emojiTextView.setOnClickListener(new View.OnClickListener() { 79 | @Override 80 | public void onClick(View v) { 81 | if (onEmojiClickListener != null) 82 | onEmojiClickListener.onEmojiClickListener(emojiIds.get(getAdapterPosition())); 83 | } 84 | }); 85 | } 86 | } 87 | 88 | public interface OnEmojiClickListener { 89 | void onEmojiClickListener(String emojiName); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/EmojiFragment.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.fragment.app.Fragment; 6 | import androidx.recyclerview.widget.GridLayoutManager; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collections; 14 | import ui.photoeditor.R; 15 | 16 | /** 17 | * Created by Ahmed Adel on 5/5/17. 18 | */ 19 | 20 | public class EmojiFragment extends Fragment implements EmojiAdapter.OnEmojiClickListener { 21 | 22 | private ArrayList emojiIds; 23 | private PhotoEditorActivity photoEditorActivity; 24 | RecyclerView emojiRecyclerView; 25 | 26 | @Override 27 | public void onCreate(@Nullable Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | photoEditorActivity = (PhotoEditorActivity) getActivity(); 30 | 31 | String[] emojis = photoEditorActivity.getResources().getStringArray(R.array.photo_editor_emoji); 32 | 33 | emojiIds = new ArrayList<>(); 34 | Collections.addAll(emojiIds, emojis); 35 | } 36 | 37 | @Nullable 38 | @Override 39 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 40 | View rootView = inflater.inflate(R.layout.fragment_main_photo_edit_emoji, container, false); 41 | 42 | emojiRecyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_main_photo_edit_emoji_rv); 43 | emojiRecyclerView.setHasFixedSize(true); 44 | emojiRecyclerView.setLayoutManager(new GridLayoutManager(photoEditorActivity, 4)); 45 | EmojiAdapter adapter = new EmojiAdapter(photoEditorActivity, emojiIds); 46 | adapter.setOnEmojiClickListener(this); 47 | emojiRecyclerView.setAdapter(adapter); 48 | 49 | return rootView; 50 | } 51 | 52 | @Override 53 | public void onEmojiClickListener(String emojiName) { 54 | photoEditorActivity.addEmoji(emojiName); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/GalleryUtils.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.net.Uri; 6 | 7 | public class GalleryUtils { 8 | 9 | /** 10 | * Get the value of the data column for this Uri. This is useful for 11 | * MediaStore Uris, and other file-based ContentProviders. 12 | * 13 | * @param context 14 | * The context. 15 | * @param uri 16 | * The Uri to query. 17 | * @param selection 18 | * (Optional) Filter used in the query. 19 | * @param selectionArgs 20 | * (Optional) Selection arguments used in the query. 21 | * @return The value of the _data column, which is typically a file path. 22 | */ 23 | public static String getDataColumn(Context context, Uri uri, 24 | String selection, String[] selectionArgs) { 25 | 26 | Cursor cursor = null; 27 | final String column = "_data"; 28 | final String[] projection = { column }; 29 | 30 | try { 31 | cursor = context.getContentResolver().query(uri, projection, 32 | selection, selectionArgs, null); 33 | if (cursor != null && cursor.moveToFirst()) { 34 | final int column_index = cursor.getColumnIndexOrThrow(column); 35 | return cursor.getString(column_index); 36 | } 37 | } finally { 38 | if (cursor != null) 39 | cursor.close(); 40 | } 41 | return null; 42 | } 43 | 44 | /** 45 | * @param uri 46 | * The Uri to check. 47 | * @return Whether the Uri authority is ExternalStorageProvider. 48 | */ 49 | public static boolean isExternalStorageDocument(Uri uri) { 50 | return "com.android.externalstorage.documents".equals(uri 51 | .getAuthority()); 52 | } 53 | 54 | /** 55 | * @param uri 56 | * The Uri to check. 57 | * @return Whether the Uri authority is DownloadsProvider. 58 | */ 59 | public static boolean isDownloadsDocument(Uri uri) { 60 | return "com.android.providers.downloads.documents".equals(uri 61 | .getAuthority()); 62 | } 63 | 64 | /** 65 | * @param uri 66 | * The Uri to check. 67 | * @return Whether the Uri authority is MediaProvider. 68 | */ 69 | public static boolean isMediaDocument(Uri uri) { 70 | return "com.android.providers.media.documents".equals(uri 71 | .getAuthority()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/ImageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import androidx.annotation.NonNull; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ImageView; 11 | 12 | import java.util.List; 13 | import ui.photoeditor.R; 14 | 15 | /** 16 | * Created by Ahmed Adel on 5/4/17. 17 | */ 18 | 19 | public class ImageAdapter extends RecyclerView.Adapter { 20 | 21 | private List imageBitmaps; 22 | private LayoutInflater inflater; 23 | private OnImageClickListener onImageClickListener; 24 | 25 | public ImageAdapter(@NonNull Context context, @NonNull List imageBitmaps) { 26 | this.inflater = LayoutInflater.from(context); 27 | this.imageBitmaps = imageBitmaps; 28 | } 29 | 30 | @Override 31 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 32 | View view = inflater.inflate(R.layout.fragment_photo_edit_image_item_list, parent, false); 33 | return new ViewHolder(view); 34 | } 35 | 36 | @Override 37 | public void onBindViewHolder(ViewHolder holder, int position) { 38 | holder.imageView.setImageBitmap(imageBitmaps.get(position)); 39 | } 40 | 41 | @Override 42 | public int getItemCount() { 43 | return imageBitmaps.size(); 44 | } 45 | 46 | public void setOnImageClickListener(OnImageClickListener onImageClickListener) { 47 | this.onImageClickListener = onImageClickListener; 48 | } 49 | 50 | class ViewHolder extends RecyclerView.ViewHolder { 51 | ImageView imageView; 52 | 53 | public ViewHolder(View itemView) { 54 | super(itemView); 55 | imageView = (ImageView) itemView.findViewById(R.id.fragment_photo_edit_image_iv); 56 | imageView.setOnClickListener(new View.OnClickListener() { 57 | @Override 58 | public void onClick(View v) { 59 | if (onImageClickListener != null) 60 | onImageClickListener.onImageClickListener(imageBitmaps.get(getAdapterPosition())); 61 | } 62 | }); 63 | } 64 | } 65 | 66 | public interface OnImageClickListener { 67 | void onImageClickListener(Bitmap image); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/ImageFragment.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.content.res.Resources; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.os.Bundle; 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | import androidx.recyclerview.widget.GridLayoutManager; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | 16 | import java.util.ArrayList; 17 | import ui.photoeditor.R; 18 | /** 19 | * Created by Ahmed Adel on 5/4/17. 20 | */ 21 | 22 | public class ImageFragment extends Fragment implements ImageAdapter.OnImageClickListener { 23 | 24 | private ArrayList stickerBitmaps; 25 | private PhotoEditorActivity photoEditorActivity; 26 | RecyclerView imageRecyclerView; 27 | 28 | @Override 29 | public void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | photoEditorActivity = (PhotoEditorActivity) getActivity(); 32 | 33 | TypedArray images = getResources().obtainTypedArray(R.array.photo_editor_photos); 34 | 35 | ArrayList stickers = (ArrayList) getActivity().getIntent().getExtras().getSerializable("stickers"); 36 | 37 | if (stickers != null && stickers.size() > 0) { 38 | stickerBitmaps = new ArrayList<>(); 39 | 40 | for (int i = 0;i < stickers.size();i++) { 41 | stickerBitmaps.add(decodeSampledBitmapFromResource(getActivity().getResources(), stickers.get(i), 120, 120)); 42 | } 43 | } else { 44 | stickerBitmaps = new ArrayList<>(); 45 | for (int i = 0; i < images.length(); i++) { 46 | stickerBitmaps.add(decodeSampledBitmapFromResource(photoEditorActivity.getResources(), images.getResourceId(i, -1), 120, 120)); 47 | } 48 | } 49 | } 50 | 51 | @Nullable 52 | @Override 53 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 54 | View rootView = inflater.inflate(R.layout.fragment_main_photo_edit_image, container, false); 55 | 56 | imageRecyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_main_photo_edit_image_rv); 57 | imageRecyclerView.setLayoutManager(new GridLayoutManager(photoEditorActivity, 3)); 58 | ImageAdapter adapter = new ImageAdapter(photoEditorActivity, stickerBitmaps); 59 | adapter.setOnImageClickListener(this); 60 | imageRecyclerView.setAdapter(adapter); 61 | 62 | return rootView; 63 | } 64 | 65 | public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { 66 | final BitmapFactory.Options options = new BitmapFactory.Options(); 67 | options.inJustDecodeBounds = true; 68 | BitmapFactory.decodeResource(res, resId, options); 69 | options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 70 | options.inJustDecodeBounds = false; 71 | return BitmapFactory.decodeResource(res, resId, options); 72 | } 73 | 74 | public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 75 | final int height = options.outHeight; 76 | final int width = options.outWidth; 77 | int inSampleSize = 1; 78 | if (height > reqHeight || width > reqWidth) { 79 | final int halfHeight = height / 2; 80 | final int halfWidth = width / 2; 81 | while ((halfHeight / inSampleSize) >= reqHeight 82 | && (halfWidth / inSampleSize) >= reqWidth) { 83 | inSampleSize *= 2; 84 | } 85 | } 86 | return inSampleSize; 87 | } 88 | 89 | @Override 90 | public void onImageClickListener(Bitmap image) { 91 | photoEditorActivity.addImage(image); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import ui.photoeditor.R; 7 | public class MainActivity extends MediaActivity { 8 | 9 | @Override 10 | protected void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | setContentView(R.layout.activity_main); 13 | } 14 | 15 | public void openUserGallery(View view) { 16 | openGallery(); 17 | } 18 | 19 | public void openUserCamera(View view) { 20 | startCameraActivity(); 21 | } 22 | 23 | @Override 24 | protected void onPhotoTaken() { 25 | Intent intent = new Intent(MainActivity.this, PhotoEditorActivity.class); 26 | intent.putExtra("selectedImagePath", selectedImagePath); 27 | startActivity(intent); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/MediaActivity.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.content.Intent; 4 | import android.graphics.BitmapFactory; 5 | import android.net.Uri; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | import androidx.annotation.RequiresApi; 9 | import android.util.Log; 10 | import ui.photoeditor.R; 11 | /** 12 | * Created by Ahmed Adel on 09/06/2017. 13 | */ 14 | 15 | public abstract class MediaActivity extends BaseActivity { 16 | 17 | private Uri selectedImageUri; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | } 23 | 24 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 25 | @Override 26 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 27 | switch (resultCode) { 28 | case RESULT_CANCELED: 29 | break; 30 | case RESULT_OK: 31 | if (requestCode == GALLERY_INTENT_CALLED || requestCode == CAMERA_CODE 32 | || requestCode == GALLERY_KITKAT_INTENT_CALLED) { 33 | if (requestCode == GALLERY_INTENT_CALLED) { 34 | selectedImageUri = data.getData(); 35 | selectedImagePath = getPath(selectedImageUri); 36 | } else if (requestCode == GALLERY_KITKAT_INTENT_CALLED) { 37 | selectedImageUri = data.getData(); 38 | final int takeFlags = data.getFlags() 39 | & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 40 | // Check for the freshest data. 41 | if (selectedImageUri != null) { 42 | getContentResolver().takePersistableUriPermission( 43 | selectedImageUri, takeFlags); 44 | selectedImagePath = getPath(selectedImageUri); 45 | } 46 | } else { 47 | selectedImagePath = selectedOutputPath; 48 | } 49 | 50 | if (UtilFunctions.stringIsNotEmpty(selectedImagePath)) { 51 | // decode image size 52 | BitmapFactory.Options o = new BitmapFactory.Options(); 53 | o.inJustDecodeBounds = true; 54 | BitmapFactory.decodeFile(selectedImagePath, o); 55 | // Find the correct scale value. It should be the power of 56 | // 2. 57 | int width_tmp = o.outWidth, height_tmp = o.outHeight; 58 | Log.d("MediaActivity", "MediaActivity : image size : " 59 | + width_tmp + " ; " + height_tmp); 60 | final int MAX_SIZE = getResources().getDimensionPixelSize( 61 | R.dimen.image_loader_post_width); 62 | int scale = 1; 63 | // while (true) { 64 | // if (width_tmp / 2 < MAX_SIZE 65 | // || height_tmp / 2 < MAX_SIZE) 66 | // break; 67 | // width_tmp /= 2; 68 | // height_tmp /= 2; 69 | // scale *= 2; 70 | // } 71 | if (height_tmp > MAX_SIZE || width_tmp > MAX_SIZE) { 72 | if (width_tmp > height_tmp) { 73 | scale = Math.round((float) height_tmp 74 | / (float) MAX_SIZE); 75 | } else { 76 | scale = Math.round((float) width_tmp 77 | / (float) MAX_SIZE); 78 | } 79 | } 80 | Log.d("MediaActivity", "MediaActivity : scaling image by factor : " + scale); 81 | BitmapFactory.Options options = new BitmapFactory.Options(); 82 | options.inSampleSize = scale; 83 | bitmap = BitmapFactory.decodeFile(selectedImagePath, options); 84 | _taken = true; 85 | onPhotoTaken(); 86 | System.gc(); 87 | } 88 | } 89 | break; 90 | } 91 | super.onActivityResult(requestCode, resultCode, data); 92 | } 93 | 94 | protected abstract void onPhotoTaken(); 95 | } 96 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/TranslationService.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Created by Thien PV on 11/24/23. 7 | */ 8 | public class TranslationService { 9 | 10 | private static TranslationService instance = null; 11 | private HashMap translations; 12 | 13 | private TranslationService() { 14 | translations = new HashMap<>(); 15 | } 16 | 17 | public static TranslationService getInstance() { 18 | if (instance == null) { 19 | instance = new TranslationService(); 20 | } 21 | return instance; 22 | } 23 | 24 | public void init(HashMap translations) { 25 | this.translations = translations; 26 | } 27 | 28 | public String getTranslation(String key) { 29 | return translations.get(key); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /android/src/main/java/com/ahmedadeltito/photoeditor/UtilFunctions.java: -------------------------------------------------------------------------------- 1 | package com.ahmedadeltito.photoeditor; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Bitmap; 6 | import android.os.Build; 7 | import android.text.Html; 8 | import android.util.Base64; 9 | import android.view.View; 10 | import android.view.animation.AlphaAnimation; 11 | import android.view.inputmethod.InputMethodManager; 12 | 13 | import java.io.ByteArrayOutputStream; 14 | import java.util.ArrayList; 15 | import java.util.StringTokenizer; 16 | import java.util.regex.Matcher; 17 | import java.util.regex.Pattern; 18 | public class UtilFunctions { 19 | 20 | // private static final String pattern = 21 | // "\\s*([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})\\s*"; 22 | // private static final String pattern = 23 | // "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}\\@[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25})+"; 24 | 25 | private static final AlphaAnimation enableAnim = new AlphaAnimation(0.6f, 26 | 1.0f); 27 | 28 | private static final AlphaAnimation disableAnim = new AlphaAnimation(1.0f, 29 | 0.6f); 30 | 31 | public static boolean stringIsEmpty(String string) { 32 | 33 | if (string != null) { 34 | if (!string.trim().equals("")) { 35 | return false; 36 | } 37 | } 38 | return true; 39 | } 40 | 41 | public static boolean stringIsNotEmpty(String string) { 42 | if (string != null && !string.equals("null")) { 43 | if (!string.trim().equals("")) { 44 | return true; 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | public static String[] stringTokenizer(String string) { 51 | 52 | StringTokenizer tokens = new StringTokenizer(string, ","); 53 | String[] result = new String[tokens.countTokens()]; 54 | 55 | for (int i = 0; i < tokens.countTokens(); i++) { 56 | result[i] = tokens.nextToken(); 57 | } 58 | 59 | return result; 60 | } 61 | 62 | public static String ArrayToString(ArrayList string) { 63 | 64 | String result = ""; 65 | StringBuilder builder = new StringBuilder(); 66 | int len = string.size() - 1; 67 | if (string.size() > 0) { 68 | for (int i = 0; i < len; i++) { 69 | result += string.get(i) + ", "; 70 | builder.append(string.get(i)); 71 | builder.append(", "); 72 | } 73 | result += string.get(len); 74 | builder.append(string.get(len)); 75 | } 76 | 77 | return builder.toString(); 78 | } 79 | 80 | public static boolean isValidEmail(String s) { 81 | 82 | // return Pattern.matches(pattern, s); 83 | try { 84 | return android.util.Patterns.EMAIL_ADDRESS.matcher(s).matches(); 85 | } catch (NullPointerException exception) { 86 | return false; 87 | } 88 | } 89 | 90 | public static void enableView(View v) { 91 | if (Build.VERSION.SDK_INT >= 11) { 92 | try { 93 | v.setAlpha(1.0f); 94 | return; 95 | } catch (Exception e) { 96 | } 97 | } else { 98 | enableAnim.setDuration(100); 99 | enableAnim.setFillAfter(true); 100 | v.startAnimation(enableAnim); 101 | } 102 | } 103 | 104 | public static void disableView(View v) { 105 | if (Build.VERSION.SDK_INT >= 11) { 106 | try { 107 | v.setAlpha(0.6f); 108 | return; 109 | } catch (Exception e) { 110 | } 111 | } else { 112 | disableAnim.setDuration(100); 113 | disableAnim.setFillAfter(true); 114 | v.startAnimation(disableAnim); 115 | } 116 | 117 | } 118 | 119 | public static String stripHtml(String html) { 120 | String s = Html.fromHtml(html).toString(); 121 | s = s.replaceAll("[\n\r\t]", " "); 122 | return s; 123 | } 124 | 125 | public static boolean containSpace(String s) { 126 | Pattern pattern = Pattern.compile("\\s"); 127 | Matcher matcher = pattern.matcher(s); 128 | return matcher.find(); 129 | } 130 | 131 | public static String getYoutubeVideoId(String youtubeUrl) { 132 | String video_id = ""; 133 | if (youtubeUrl != null && youtubeUrl.trim().length() > 0 134 | && youtubeUrl.startsWith("http")) { 135 | String expression = "^.*((youtu.be" 136 | + "\\/)" 137 | + "|(v\\/)|(\\/u\\/w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#\\&\\?]*).*"; 138 | CharSequence input = youtubeUrl; 139 | Pattern pattern = Pattern.compile(expression, 140 | Pattern.CASE_INSENSITIVE); 141 | Matcher matcher = pattern.matcher(input); 142 | if (matcher.matches()) { 143 | String groupIndex1 = matcher.group(7); 144 | if (groupIndex1 != null && groupIndex1.length() == 11) 145 | video_id = groupIndex1; 146 | } 147 | } 148 | return video_id; 149 | } 150 | 151 | public static String encodeImage(Bitmap bitmap) { 152 | String encodedImage = ""; 153 | try { 154 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 155 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 156 | byte[] b = baos.toByteArray(); 157 | baos.close(); 158 | baos = null; 159 | encodedImage = Base64.encodeToString(b, 160 | Base64.NO_WRAP); 161 | } catch (Exception e) { 162 | 163 | } 164 | return encodedImage; 165 | } 166 | 167 | public static void hideKeyboardFrom(Activity activity) { 168 | InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); 169 | imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); 170 | } 171 | 172 | public static void showKeyboardAt(Activity activity) { 173 | InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); 174 | imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /android/src/main/java/ui/photoeditor/RNPhotoEditorModule.java: -------------------------------------------------------------------------------- 1 | package ui.photoeditor; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.graphics.Color; 6 | import com.ahmedadeltito.photoeditor.PhotoEditorActivity; 7 | import com.ahmedadeltito.photoeditor.TranslationService; 8 | import com.facebook.react.bridge.ActivityEventListener; 9 | import com.facebook.react.bridge.BaseActivityEventListener; 10 | import com.facebook.react.bridge.Callback; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 13 | import com.facebook.react.bridge.ReactMethod; 14 | import com.facebook.react.bridge.ReadableArray; 15 | import com.facebook.react.bridge.ReadableMap; 16 | import java.util.ArrayList; 17 | 18 | public class RNPhotoEditorModule extends ReactContextBaseJavaModule { 19 | 20 | private static final int PHOTO_EDITOR_REQUEST = 1; 21 | private static final String E_PHOTO_EDITOR_CANCELLED = "E_PHOTO_EDITOR_CANCELLED"; 22 | 23 | private Callback mDoneCallback; 24 | private Callback mCancelCallback; 25 | 26 | private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() { 27 | @Override 28 | public void onActivityResult( 29 | Activity activity, 30 | int requestCode, 31 | int resultCode, 32 | Intent intent 33 | ) { 34 | if (requestCode == PHOTO_EDITOR_REQUEST) { 35 | if (mDoneCallback != null) { 36 | if (resultCode == Activity.RESULT_CANCELED) { 37 | mCancelCallback.invoke(resultCode); 38 | } else { 39 | mDoneCallback.invoke(intent.getExtras().getString("imagePath")); 40 | } 41 | } 42 | 43 | mCancelCallback = null; 44 | mDoneCallback = null; 45 | } 46 | } 47 | }; 48 | 49 | public RNPhotoEditorModule(ReactApplicationContext reactContext) { 50 | super(reactContext); 51 | reactContext.addActivityEventListener(mActivityEventListener); 52 | } 53 | 54 | @Override 55 | public String getName() { 56 | return "RNPhotoEditor"; 57 | } 58 | 59 | @ReactMethod 60 | public void Edit(final ReadableMap props, final Callback onDone, final Callback onCancel) { 61 | String path = props.getString("path"); 62 | // print all readable map 63 | TranslationService.getInstance().init(props.getMap("languages").toHashMap()); 64 | 65 | //Process Stickers 66 | ReadableArray stickers = props.getArray("stickers"); 67 | ArrayList stickersIntent = new ArrayList(); 68 | 69 | for (int i = 0; i < stickers.size(); i++) { 70 | int drawableId = getReactApplicationContext() 71 | .getResources() 72 | .getIdentifier( 73 | stickers.getString(i), 74 | "drawable", 75 | getReactApplicationContext().getPackageName() 76 | ); 77 | 78 | stickersIntent.add(drawableId); 79 | } 80 | 81 | //Process Hidden Controls 82 | ReadableArray hiddenControls = props.getArray("hiddenControls"); 83 | ArrayList hiddenControlsIntent = new ArrayList<>(); 84 | 85 | for (int i = 0; i < hiddenControls.size(); i++) { 86 | hiddenControlsIntent.add(hiddenControls.getString(i)); 87 | } 88 | 89 | //Process Colors 90 | ReadableArray colors = props.getArray("colors"); 91 | ArrayList colorPickerColors = new ArrayList<>(); 92 | 93 | for (int i = 0; i < colors.size(); i++) { 94 | colorPickerColors.add(Color.parseColor(colors.getString(i))); 95 | } 96 | 97 | Intent intent = new Intent(getCurrentActivity(), PhotoEditorActivity.class); 98 | intent.putExtra("selectedImagePath", path); 99 | intent.putExtra("colorPickerColors", colorPickerColors); 100 | intent.putExtra("hiddenControls", hiddenControlsIntent); 101 | intent.putExtra("stickers", stickersIntent); 102 | 103 | mCancelCallback = onCancel; 104 | mDoneCallback = onDone; 105 | 106 | getCurrentActivity().startActivityForResult(intent, PHOTO_EDITOR_REQUEST); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /android/src/main/java/ui/photoeditor/RNPhotoEditorPackage.java: -------------------------------------------------------------------------------- 1 | 2 | package ui.photoeditor; 3 | 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.bridge.NativeModule; 10 | import com.facebook.react.bridge.ReactApplicationContext; 11 | import com.facebook.react.uimanager.ViewManager; 12 | import com.facebook.react.bridge.JavaScriptModule; 13 | 14 | public class RNPhotoEditorPackage implements ReactPackage { 15 | @Override 16 | public List createNativeModules(ReactApplicationContext reactContext) { 17 | return Arrays.asList(new RNPhotoEditorModule(reactContext)); 18 | } 19 | 20 | // Deprecated from RN 0.47 21 | public List> createJSModules() { 22 | return Collections.emptyList(); 23 | } 24 | 25 | @Override 26 | public List createViewManagers(ReactApplicationContext reactContext) { 27 | return Collections.emptyList(); 28 | } 29 | } -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/aa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/aa.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/bb.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/c.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/cc.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/d.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/dd.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/e.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/ee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/ee.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/i.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/i.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/j.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/j.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/k.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/l.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/m.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/n.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/o.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/p.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/q.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/q.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/r.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/s.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/t.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/u.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/u.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/v.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/w.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/x.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/y.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienMD/react-native-image-editor/62256a40b137bc91090f65105dc9722eb677b30f/android/src/main/res/drawable-xhdpi/z.png -------------------------------------------------------------------------------- /android/src/main/res/drawable/above_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /android/src/main/res/drawable/below_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /android/src/main/res/drawable/fading_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /android/src/main/res/drawable/rounded_border_text_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 |