Giter Club home page Giter Club logo

react-native-image-editor's Introduction

@react-native-community/image-editor

Build Status Version MIT License PRs Welcome Lean Core Badge

Image Editor Native module for React Native.

Originally extracted from React Native issue#23313 and maintained by the community.

Getting started

Install

yarn add @react-native-community/image-editor
# or
npm install @react-native-community/image-editor --save

Install Pods

npx pod-install

Usage

Start by importing the library:

import ImageEditor from '@react-native-community/image-editor';

Crop image

Crop the image specified by the URI param. If URI points to a remote image, it will be downloaded automatically. If the image cannot be loaded/downloaded, the promise will be rejected.

If the cropping process is successful, the resultant cropped image will be stored in the cache path, and the CropResult returned in the promise will point to the image in the cache path. ⚠️ Remember to delete the cropped image from the cache path when you are done with it.

ImageEditor.cropImage(uri, cropData).then((result) => {
  console.log('Cropped image uri:', result.uri);
});

cropData: ImageCropData

Name Type Description
offset { x: number, y: number } The top-left corner of the cropped image, specified in the original image's coordinate space
size { width: number, height: number } Size (dimensions) of the cropped image
displaySize
(optional)
{ width: number, height: number } Size to which you want to scale the cropped image
resizeMode
(optional)
'contain' | 'cover' | 'stretch' | 'center' Resizing mode to use when scaling the image (iOS only, Android resize mode is always 'cover', Web - no support)
Default value: 'cover'
quality
(optional)
number A value in range 0.0 - 1.0 specifying compression level of the result image. 1 means no compression (highest quality) and 0 the highest compression (lowest quality)
Default value: 0.9
format
(optional)
'jpeg' | 'png' | 'webp' The format of the resulting image.
Default value: based on the provided image;
if value determination is not possible, 'jpeg' will be used as a fallback.
'webp' isn't supported by iOS.
includeBase64
(optional)
boolean Indicates if Base64 formatted picture data should also be included in the CropResult.
Default value: false
headers
(optional)
object | Headers An object or Headers interface representing the HTTP headers to send along with the request for a remote image.

result: CropResult

Name Type Description
uri string The path to the image file (example: 'file:///data/user/0/.../image.jpg')
WEB: uri is the data URI string (example 'data:image/jpeg;base64,/4AAQ...AQABAA')
path string The URI of the image (example: '/data/user/0/.../image.jpg')
WEB: path is the blob URL (example 'blob:https://example.com/43ff7a16...e46b1')
name string The name of the image file. (example: 'image.jpg')
width number The width of the image in pixels
height number Height of the image in pixels
size number The size of the image in bytes
type string The MIME type of the image ('image/jpeg', 'image/png', 'image/webp')
base64
(optional)
string The base64-encoded image data example: '/9j/4AAQSkZJRgABAQAAAQABAAD'
if you need data URI as the source for an Image element for example, you can use data:${type};base64,${base64}

For more advanced usage check our example app.

react-native-image-editor's People

Contributors

aaronechiu avatar bestander avatar chenfadafb avatar cpojer avatar davidaurelio avatar dratwas avatar evanbacon avatar faifai21 avatar gre avatar guhungry avatar hramos avatar javache avatar jayu avatar mateusz1913 avatar naturalclar avatar nicklockwood avatar philikon avatar retyui avatar rubennorte avatar shcheuk avatar shergin avatar sohobloo avatar sophiebits avatar souhe avatar sroka avatar thesavior avatar thymikee avatar trancever avatar vonovak avatar wojteg1337 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-image-editor's Issues

Inconsistent handling of EXIF between Android and iOS

Environment

react: "17.0.2"
react-native: "0.66.3"
@react-native-community/image-editor: "^2.3.0",

Description

I'm working on an app that has a camera (using react-native-camera). The camera library creates rotated photos that include EXIF data with the correct orientation. Opening these photos in any viewer displays them correctly. However, I noticed an inconsistent behavior when trying to crop these photos using Image Editor.

On Android, the EXIF data seems to alter the cropping coordinates and dimensions. For example, a photo with EXIF orientation "6" will have the origin (0,0) at the top right corner, the x/width go from bottom to top, and the y/height go from left to right. A photo with EXIF orientation "8" has the origin at the bottom left corner, the x/width go from top to bottom, and the y/height go from right to left. Here's how each photo would look without the EXIF data:

image

On iOS, on the other hand, the origin is always at the top left corner, and the coordinates/dimensions are calculated correctly, regardless of the EXIF orientation (which is probably how everyone would expect it to work).

One workaround I found is to resize the image using another library, and remove the EXIF data. But this takes a couple seconds, making the camera much slower. Alternatively, I can calculate the coordinates and dimensions for Android, taking into account the EXIF orientation, but I'm not sure if this inconsistency is consistent in each platform, or if different devices of the same platform can have different behaviors.

Only IOS: ImageEditor.cropImage method writeToFileError Code=101 "(null)"

Bug

Bug is only happening on ios platform.
When calling cropImage method it gives this error (not always):
image

Environment info

React native info output:

System:
OS: macOS 10.15.1
CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
Memory: 18.79 MB / 8.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.16.3 - /usr/local/bin/node
Yarn: 1.19.1 - /usr/local/bin/yarn
npm: 6.9.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK:
API Levels: 25, 28, 29
Build Tools: 28.0.3, 29.0.2
System Images: android-27 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.5977832
Xcode: 11.2.1/11B500 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.6 => 16.8.6
react-native: 0.60.3 => 0.60.3
npmGlobalPackages:
react-native-cli: 2.0.1

Library version: 2.2.0

Steps To Reproduce

Try to crop image on ios

Unable to find a specification for `React-RCTImage` depended upon by `react-native-image-editor`

Bug

[!] Unable to find a specification for `React-RCTImage` depended upon by `react-native-image-editor`

You have either:
 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.

Environment info

React Native 0.59.10

React native info output:

$ react-native info
info 
  React Native Environment Info:
    System:
      OS: macOS 10.14.5
      CPU: (8) x64 Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
      Memory: 37.52 MB / 16.00 GB
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
      Yarn: 1.13.0 - /usr/local/bin/yarn
      npm: 6.9.0 - ~/.nvm/versions/node/v10.15.3/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
    IDEs:
      Android Studio: 3.4 AI-183.6156.11.34.5692245
      Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.8.3 => 16.8.3 
      react-native: 0.59.10 => 0.59.10 
    npmGlobalPackages:
      react-native-cli: 2.0.1

Library version: 2.0.1

Steps To Reproduce

  1. Upgrade from version 2.0.0 to 2.0.1 with React Native v59
  2. pod install

Describe what you expected to happen:

  1. Successful pod install

Reproducible sample code

This is a podspec problem, which looks like it was introduced in 885669d with the note of fixing it, but the change actually breaks it when it was working for us under 2.0.0. I'm not sure why that change was made but it's breaking our build at the moment.

[Android] bug cropImage with base64 URI

Summary

👋 Hi!

When i am using base64 uri with cropImage function it works perfectly with IOS but in Android i have this issue:

[Error: unknown protocol: data]

Environment info

  • "react-native": "0.62.2",
  • "@react-native-community/image-editor": "^2.3.0",

Reproduce the issue

 const base64Uri =
      'data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAkACQAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACQAAAAAQAAAJAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAZCgAwAEAAAAAQAAAZAAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIAZABkAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDAAYGBgYGBgoGBgoOCgoKDhIODg4OEhcSEhISEhccFxcXFxcXHBwcHBwcHBwiIiIiIiInJycnJywsLCwsLCwsLCz/2wBDAQcHBwsKCxMKChMuHxofLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi7/3QAEABn/2gAMAwEAAhEDEQA/APlWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//Q+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9H5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//0vlWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//T+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9T5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//1flWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//W+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9f5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//0PlWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//R+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9L5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//0/lWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//U+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9X5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//1vlWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//X+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9D5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//0flWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//S+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9P5VooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//1PlWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//V+VaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9b5VooooAKKKKACu18H+HbTVDcanq7FLCyXdJjI3HGcZHPA5OOeg71xVen2/wDo3wvnaPg3Fz8xH+8o/ktefmVScacYU3ZyaV+1/wDgHdl9OMqjlNXUU3bvYIfEfgq9uRp9zosdvaudonBAkXPAZsAEe/zHHvXKeKvD7eHdWazDF4XAkiY9Sh7H3B4/Wubr0/x1+/0Dw/ev/rHt8Me5yiH+ea51T+q4inGm3yyumm29Urp6m7qfWaFSVRK8bNNJLRu1tCeay8O+CbG2/tWzGo6jcJvZHOEQenII4PHQk4PSrGn2/hnxzbz2lpYrpt/Em9DHjaR07AAjJGeM88GvO9G0ttcvTayXUdvtQtvnbC8EDGfXmvT9P0Z/Bem3GsadnVLqSMxh4QDFEvBJPJY888Dt261w4yEaKt7Rus9ndpb9vhSOzCSlVd/ZpUlvom/87ni7KyMUYYKnBHuK2PD+jTa9qsOmxHaHJLt12oOSf8PesYkk5PJNenfDECO7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'

 ImageEditor.cropImage(base64Uri, {
      offset: { x: 0, y: 0 },
      size: { width: 100, height: 100 },
    })
      .then((uri) => { console.log(uri) })
      .catch((error) => { console.log(error) })

`ExifInterface only supports saving attributes on JPEG formats` error when running with react-native-camera

Hi, thank you for the great library. I am getting the following error when use with react-native-camera.
Am I missing something? Thank you in advance.

Bug

image

console.error: "Unhandled promise rejection", {"framesToPop":1,"nativeStackAndroid":[{"methodName":"saveAttributes","lineNumber":1770,"file":"ExifInterface.java"},{"methodName":"copyExif","lineNumber":397,"file":"ImageEditorModule.java"},{"methodName":"access$500","lineNumber":55,"file":"ImageEditorModule.java"},{"methodName":"doInBackgroundGuarded","lineNumber":282,"file":"ImageEditorModule.java"},{"methodName":"doInBackgroundGuarded","lineNumber":202,"file":"ImageEditorModule.java"},{"methodName":"doInBackground","lineNumber":32,"file":"GuardedAsyncTask.java"},{"methodName":"doInBackground","lineNumber":20,"file":"GuardedAsyncTask.java"},{"methodName":"call","lineNumber":333,"file":"AsyncTask.java"},{"methodName":"run","lineNumber":266,"file":"FutureTask.java"},{"methodName":"runWorker","lineNumber":1162,"file":"ThreadPoolExecutor.java"}],"userInfo":null,"code":"EUNSPECIFIED","line":11371,"column":26,"sourceURL":"http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false"}
error
    index.delta?platform=android&dev=true&minify=false:76687:29
<unknown>
    index.delta?platform=android&dev=true&minify=false:207035:38
<unknown>
    index.delta?platform=android&dev=true&minify=false:5993:26
exports
    index.delta?platform=android&dev=true&minify=false:6427:16
<unknown>
    index.delta?platform=android&dev=true&minify=false:5984:25
_callTimer
    index.delta?platform=android&dev=true&minify=false:37010:17
_callImmediatesPass
    index.delta?platform=android&dev=true&minify=false:37046:19
callImmediates
    index.delta?platform=android&dev=true&minify=false:37265:33
callImmediates
    [native code]
__callImmediates
    index.delta?platform=android&dev=true&minify=false:11811:35
<unknown>
    index.delta?platform=android&dev=true&minify=false:11632:34
__guard
    index.delta?platform=android&dev=true&minify=false:11794:15
flushedQueue
    index.delta?platform=android&dev=true&minify=false:11631:21
flushedQueue
    [native code]
invokeCallbackAndReturnFlushedQueue
    [native code]

Environment info

React native info output:

info 
  React Native Environment Info:
    System:
      OS: macOS 10.14.5
      CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
      Memory: 454.87 MB / 16.00 GB
      Shell: 2.7.1 - /usr/local/bin/fish
    Binaries:
      Node: 10.13.0 - ~/.nvm/versions/node/v10.13.0/bin/node
      Yarn: 1.12.3 - ~/.nvm/versions/node/v10.13.0/bin/yarn
      npm: 6.4.1 - ~/.nvm/versions/node/v10.13.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
    IDEs:
      Android Studio: 3.1 AI-173.4819257
      Xcode: 10.1/10B61 - /usr/bin/xcodebuild
    npmGlobalPackages:
      react-native-cli: 2.0.1
      react-native-git-upgrade: 0.2.7

Library version: ^2.0.1

Steps To Reproduce

  1. Install react-native-image-editor and react-native-camera (^2.11.0)
  2. run the code
takePicture = async () => {
    const data = await this.camera.takePictureAsync({ quality: 0.3, base64: false })
    await ImageEditor.cropImage(data.uri, {
      offset: { x: 10, y: 10 },
      size: { width: 10, height: 10 },
    })
}

render() {
    return (
      <View>
        <RNCamera
              ref={ref => {
                this.camera = ref as RNCamera
              }}
              ratio="4:3"
              captureAudio={false}
              type={RNCamera.Constants.Type.back}
          />
          <Button onPress={this.takePicture} title="Snap" />
      </View>
    )
}

Describe what you expected to happen:

  1. can crop image

Reproducible sample code

Call to ImageEditor not working

Bug

Environment info:

Android

My Code:

import {
  Image,
  ScrollView,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
  Platform,
  Button
} from 'react-native';
import ImageEditor from '@react-native-community/image-editor';

class ImageEditorScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      resizedUri: null
    };
  }

  handleSelectField = async () => {
    let { route } = this.props;
    let { imageUri } = route.params;
    const cropData = {
      offset: { x: 0, y: 0 },
      size: { width: 250, height: 250 },
      displaySize: { width: 300, height: 300 },
      resizeMode: 'contain'
    };
    console.log('Image URI from route.params: ', imageUri);
    let resized = await new Promise((resolve, reject) => {
      console.log('Reached in Promise');
      ImageEditor.cropImage(
        imageUri,
        cropData,
        uri => {
          resolve(uri);
          console.log(uri);       **//This Line not printing**
        },
        () => reject()
      );
    });

    this.setState({ resizedUri: resized });
    console.log('object');
  };

  render() {
    let { route } = this.props;
    let { imageUri } = route.params;
    let { resizedUri } = this.state;
    return (
      <View>
        <Image source={{ uri: imageUri }} style={{ width: 250, height: 250 }} />
        <Button title='Select Field Area' onPress={this.handleSelectField} />
        {resizedUri && <Text>{resizedUri}</Text>}
      </View>
    );
  }
}

export default ImageEditorScreen;

Library version: Latest Version (npm install @react-native-community/image-editor --save)

However in the image editor call to crop image the inner console log is not printing only so actually not going inside only. I have checked the image uri is being received correctly.
Please help me to solve this.

Cannot read Propery 'cropImage' of undefined

Cannot read Propery 'cropImage' of undefined

Hi anyone, can help me, I'm having an error. All of my data is present. I don't know why i'm getting this error

import ImageEditor from "@react-native-community/image-editor";

               let cropData={
                    offset: {x: 0,y: 0},
                    size: {width: result.width,height: result.height},
                    displaySize: {width: 100,height: 100},
                    resizeMode: "contain"
                };
                ImageEditor.cropImage(result.uri,cropData).then(url => {
                    console.log("Cropped image uri",url);
                })

//result.uri has data
//cropData has data as well

Any ideas, thanks

Cropped Image filesize is 10 times larger than original image - iOS

Bug

I am using this library to crop a local image.
Image size in Iphone is 1.7MB in size.
After cropping the image to a smaller size, the resulting image is now 16.8MB in size.
I have confirmed this by uploading both images to my PC and getting image info, which I attach.

Environment info

React native info output:

React Native Environment Info:
System:
OS: macOS 10.14.6
CPU: (8) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
Memory: 1.26 GB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 12.9.0 - /usr/local/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.12.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.4, macOS 10.14, tvOS 12.4, watchOS 5.3
Android SDK:
API Levels: 23, 27, 28, 29
Build Tools: 28.0.3, 29.0.2
System Images: android-23 | Google APIs Intel x86 Atom_64
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.5791312
Xcode: 10.3/10G8 - /usr/bin/xcodebuild
npmPackages:
react: ^16.0.0 => 16.11.0
react-native: ^0.57.1 => 0.57.8
npmGlobalPackages:
react-native-cli: 2.0.1

Library version: 2.1.0

Steps To Reproduce

Code to achieve cropped image is simple:

const cropData = {
      offset: { x: image_x, y: image_y },
      size: { width: newCroperImage_Width, height: newCroperImage_Height },
      displaySize: { width: newCroperImage_Width, height: newCroperImage_Height },
      resizeMode: 'contain',
    };

    return ImageEditor.cropImage(imagePath, cropData).then(url => {
      console.log('Cropped image uri', url);
      return url;

Describe what you expected to happen:

Cropped image filesize should be smaller than original image size.

'RCTImageUtils.h' file not found

Bug

Trying to build my project in Xcode after having linked this library. Getting a "'RCTImageUtils.h' file not found" build error.

Environment info

React native info output:

React Native Environment Info:
    System:
      OS: macOS 10.14.5
      CPU: (8) x64 Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
      Memory: 221.55 MB / 16.00 GB
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.14.1 - /usr/local/bin/node
      npm: 6.9.0 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
      Android SDK:
        API Levels: 23, 25, 26, 27, 28
        Build Tools: 27.0.3, 28.0.3
        System Images: android-28 | Intel x86 Atom, android-28 | Intel x86 Atom_64
    IDEs:
      Android Studio: 3.3 AI-182.5107.16.33.5314842
      Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.8.3 => 16.8.3 
      react-native: 0.59.10 => 0.59.10 
    npmGlobalPackages:
      react-native-cli: 2.0.1

Library version: 2.0.0

Steps To Reproduce

  1. install this lib
  2. run react-native link @react-native-community/image-editor
  3. open Xcode, navigate to Product --> Build

Describe what you expected to happen:

  1. the project successfully builds

Notes

I think the problem is that, in RNCImageEditor.m, line 20's if/else is falling back to the else even when RCTImage/RCTImageUitls exists in the project (where RCTImage.xcodeproj is a sibling to RNCImageEditor.xcodeproj)

image

Output size of ImageEditor.cropImage become smaller

Bug

Output size of ImageEditor.cropImage become smaller

Environment info

React native info output:

 // paste it here

Library version: 2.1.0

Steps To Reproduce

my code:

    const cropData = {
      offset: { x, y },
      size: { width, height },
      displaySize:{width,height},
      resizeMode: "cover"
    };
    RNFS.stat(this.props.imageUri).then((value)=>{
      console.warn("this.props.imageUri",value) // size is 2302015
    })
    console.warn("imageUri",this.props.imageUri,this.state.rotation);
    RNImageRotate.rotateImage(
      this.props.imageUri,
      this.state.rotation,
      rotatedUri => {
        ImageEditor.cropImage(
          this.props.imageUri,
          cropData,
          croppedUri => {
           RNFS.stat(croppedUri).then((value)=>{
                 console.warn("croppedUri",value) // size is 818649
            })
            this.props.onDone(croppedUri);
          },
          err => {
            console.log("cropping error");
            console.log(err);
          }
        );

      },
      err => {
        alert(err);
        console.log(err);
      }
    );

Describe what you expected to happen:

when the width and height is origin of the image, output size is 2302015

Reproducible sample code

[iOS] Don't use ImageStore

Since ImageStore is deprecated should migrate out of it. And also it will have consistent behavior between ios and android.

ReactNativeRenderer-dev.js:8905 Warning: ImageStore is deprecated and will be removed in a future release. To get a base64-encoded string from a local image use either of the following third-party libraries:* expo-file-system: readAsStringAsync(filepath, 'base64')* react-native-fs: readFile(filepath, 'base64')

Potential Implementation

https://guides.github.com/features/mastering-markdown/
https://github.com/react-native-community/react-native-camera/blob/master/ios/RN/RNFileSystem.m

https://github.com/react-native-community/react-native-camera/blob/d6a7c625d67e05a783119b7ebcfb937c0232e55f/ios/RN/RNCamera.m#L439-L442

Could not determine MIME TYPE on Android 10

Bug report

Summary

Our bug report system reported a missing MIME type on a Samsung Galaxy A31 SM-A315G phone running Android 10. The exact error message is

Error: Could not determine MIME type

Environment info

react-native info output:

System:
    OS: macOS 10.15.6
    CPU: (8) x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
    Memory: 56.27 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.16.2 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.5 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 22, 23, 24, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 23.0.2, 25.0.0, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 27.0.2, 27.0.3, 28.0.3, 29.0.0, 29.0.2
      System Images: android-24 | Google Play Intel x86 Atom, android-25 | Google APIs Intel x86 Atom_64, android-26 | Google APIs Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
      Android NDK: 21.0.6113669
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6626763
    Xcode: 11.6/11E708 - /usr/bin/xcodebuild
  npmGlobalPackages:
    react-native-cli: 2.0.1
    react-native-create-bridge: 2.0.1
    react-native-git-upgrade: 0.2.7
    react-native-rename: 2.1.5

Library version: 2.3.0

Steps to reproduce

  1. Take picture using react-native-camera
  2. Wait until we have a uri from the taken picture
  3. Calculate the cropping data
  4. Crop picture /react-native-image-editor

Describe what you expected to happen:

  1. Take picture
  2. Wait until we have a uri
  3. Calculate the cropping data
  4. Crop picture (determine the MIME type 100%)

Reproducible sample code

I can see that the error comes from this method

@Override
    protected void doInBackgroundGuarded(Void... params) {
      try {
        BitmapFactory.Options outOptions = new BitmapFactory.Options();
        ...
        String mimeType = outOptions.outMimeType;
        if (mimeType == null || mimeType.isEmpty()) {
          throw new IOException("Could not determine MIME type");
        }
        ...
      } catch (Exception e) {
        mPromise.reject(e);
      }
    }

but I'm wondering why the MIME TYPE is empty or null on some phones but not the other and I'm wondering if the extraction of the MIME TYPE can be handled differently? Something like that:

public static String getMimeTypeFromFile(String filePath) {
    BitmapFactory.Options outOptions = new BitmapFactory.Options();
    outOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, outOptions);
    return opt.outMimeType;
}

According to the docs the official way would be via ContentResolver so something like that would work too I guess

BitmapFactory.Options outOptions = new BitmapFactory.Options();
outOptions.inJustDecodeBounds = true;
InputStream inputStream = mContext.getContentResolver().openInputStream(filePath);
BitmapFactory.decodeStream(inputStream, null, opt);
inputStream.close();

String mimeType = opt.outMimeType;

Add web support

Feature Request

Add web support

Why it is needed

Make module cross-platform

Possible implementation

Hey, I made an investigation on how to implement .cropImage on the web.
In general, a solution could use canvas with 2d context and use drawImage (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage) method to prepare cropped Image, then I could be returned to the user. And here my doubts started.

For native platforms, the return value is URI to a local image which is a result of transformation.
On the web is actually handier and easier to implement if a function would return

In addition, some users may experience issues with CORS when resizing will be implemented using canvas https://blog.codepen.io/2013/10/08/cross-domain-images-tainted-canvas/

I would like to start a discussion on the topic of web support.
Personally I'm not sure if this feature is really needed.

Support react-native 0.63

Hi

First of: Thanks for an awesome library!

Does this library support react-native 0.63? If so, could you please update the react-native peer dependecy in package.json to ">=0.57 =<0.63"? :)

Best regards
Jens

Wrong crop of image

Bug

Wrong crop output.

Environment info

React native info output:

 System:
    OS: Windows 10 10.0.18362
    CPU: (8) x64 Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
    Memory: 16.44 GB / 31.87 GB
  Binaries:
    Node: 12.4.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.17.3 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.9.0 - C:\Program Files\nodejs\npm.CMD
  SDKs:
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3
      System Images: android-22 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom, android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-29 | Google APIs Intel x86 Ato
m, android-29 | Google APIs Intel x86 Atom_64
  IDEs:
    Android Studio: Version  3.4.0.0 AI-183.6156.11.34.5692245
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: 0.61.5 => 0.61.5

Library version:
image

Steps To Reproduce

I have image with sizes:
Original Image
image
Original sizes:
image

Then i prepare a crop data to crop image
image

How i prepare this data:
image

As you can see, target width(1 on image above) of image is smaller than original width(2 on image above) and target height is equal to original height.

Describe what you expected to happen:

So, what i expected after crop:
image

What i actually have after crop:
image

Why i can't install this library?

Environment

"react-native": "0.64.2"

node js: v16.9.1

Description

Failed to install this library.

tg_image_288435651

Reproducible Demo

Execute: npm install @react-native-community/image-editor --save as mentioned on the docs

Cache remote uri

Feature request

Why it is needed

when calling multiple times with remote uri, it downloads multiple times.

it would be great if it only calls first time. and be synced with Image class from react-native

Possible implementation

Code sample

Add typescript types

I think we can follow react-native-paper approach, package will use flow and it will additionally export typescript types.

Support cropping transparent images

Feature Request

Support cropping transparent images. Currently, if you crop a partially transparent image, all the transparent pixels become white.

Why it is needed

I'm upgrading my app from RN 0.59 to 0.61. The old ImageEditor bundled with RN 0.59 supported cropping transparent images.

Possible implementation

Use UIImagePNGRepresentation instead of UIImageJPEGRepresentation? Not sure about Android

Code sample

// localFilePath contains a PNG with partially transparent image. Maybe cropData can take an extra flag to use png

let cropped = await ImageEditor.cropImage(localFilePath, {usePNG: true} )

// cropped should contain a uri with the transparency preserved

TypeError: null is not an object (evaluating 'RNCImageEditor.cropImage')]

Question

I'm running into an issue that I cannot solve. I can't find any examples of using a local file - advanced usage example uses http - but I don't know that that's the issue. The local file URI I'm getting is from React Native Expo Camera.

One thing I noticed is the URI seems to be double URI encoded. Running decodeURI doesn't solve this. So I've had to hard code the expo cache. The two characters that are URI encoded are:
%2540 - @
%252F - /
These chraceters are on either side of anonymous in the Expo Camera cache directory.

The end result is a file URI that looks like: file:///data/data/host.exp.exponent/cache/ExperienceData/@anonymous/expo-template-bare-23a82ea2-a903-4519-a43f-fa02cdb99fc8/Camera/489808c7-2b8a-47af-b48c-6d86644c0a87.jpg

The crop data is something similar to the following - depends on the image.
{ "displaySize": Object { "height": 596.2993774414062, "width": 271.7322692871094, }, "offset": Object { "x": 180.36246299743652, "y": 648.2353515625, }, "resizeMode": "cointain", "size": Object { "height": 596.2993774414062, "width": 271.7322692871094, }, }
My issue is that I'm getting a promise rejection error - I think it's actually a TypeError.

[Unhandled promise rejection: TypeError: null is not an object (evaluating 'RNCImageEditor.cropImage')]

  • node_modules/@react-native-community/image-editor/lib/ImageEditor.js:65:26 in cropImage
  • App.js:180:27 in handleCrop
  • App.js:197:6 in _callee3$
  • node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
  • node_modules/regenerator-runtime/runtime.js:271:30 in invoke
  • node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
  • node_modules/regenerator-runtime/runtime.js:135:28 in invoke
  • node_modules/regenerator-runtime/runtime.js:145:19 in
  • node_modules/promise/setimmediate/core.js:37:14 in tryCallOne
  • node_modules/promise/setimmediate/core.js:123:25 in
  • node_modules/react-native/Libraries/Core/Timers/JSTimers.js:152:14 in _callTimer
  • node_modules/react-native/Libraries/Core/Timers/JSTimers.js:200:17 in _callImmediatesPass
  • node_modules/react-native/Libraries/Core/Timers/JSTimers.js:473:30 in callImmediates
  • [native code]:null in callImmediates
  • node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:337:6 in __callImmediates
  • node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:135:6 in
  • node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:314:10 in __guard
  • node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:134:17 in flushedQueue
  • [native code]:null in flushedQueue
  • [native code]:null in callFunctionReturnFlushedQueue

I modified https://github.com/react-native-community/react-native-image-editor/blob/master/lib/ImageEditor.js#L63 to match the following:
static cropImage(uri: string, cropData: ImageCropData): Promise<string> { console.log( 'Calling RNC Image Editor', uri, cropData ) return RNCImageEditor.cropImage(uri, cropData); }
I used this modification to get the above URI and cropData code.

I don't know what I'm doing wrong.

Here is my system information. In addition I'm using sublime text as my editor. I'm not using xcode.

Expo CLI 3.1.2 environment info: System: OS: macOS High Sierra 10.13.1 Shell: 3.2.57 - /bin/bash Binaries: Node: 8.11.4 - /usr/local/bin/node npm: 6.11.3 - /usr/local/bin/npm IDEs: Xcode: 9.2/9C40b - /usr/bin/xcodebuild npmPackages: expo: ^35.0.0 => 35.0.0 react: 16.8.3 => 16.8.3 react-native: ^0.59.8 => 0.59.10 npmGlobalPackages: expo-cli: 3.1.2

Pass full image source object rather than URI

Feature Request

In the React-Native Image component, we can provide a source object that includes headers, i.e.

<Image source={{uri: '...imageUri', headers: {'Authorization': 'Bearer ...JWT'}} />

Why it is needed

In order to render images that are hosted such that authorization is needed. Currently the Image Editor only accepts the imageUri and cannot pass headers through.

Possible implementation

Update underlying native code to check for whether imageUri is a string (backwards compatability) or object that expects parameters of { uri, headers }. If an object is found, then extract the uri and use as it currently is, and then when making the connection, for each header, call URL.setRequestProperties(key, value)

Code sample

I unfortunately don't know proper syntax for the native code side, but I'm sure psuedo code of:

(while interpreting incoming props from RN):
   is imageUri a string? If so, set local ref to imageuri
   is imageUri an object? If so, set local ref to imageUri.uri and local ref to headers as imageUri.headers

(when making remote connection for remote images)
  if (imageUri is local) do local image stuff
  if (imageUri is not local)
    URLConnection connection = new URL(mUri)
    if (headers) Object.entries(headers).forEach(([key, val]) => connection.setRequestProperty(key, val)
    connection.openConnection()
    stream = connection.getInputStream();

ReactNative 0.62

Question

package.json lists react-native peer dependency with versions ">=0.57 <0.62".
Does this library work with react-native 0.62?
If not, any tips on how to work on an update?

I'm asking because I'm having trouble making it work in an app with react-native 0.62.2 on iOS (on Android it works fine).

Library can't be installed

I created the project using react-native init.
I can't be able to install the library.

react-native info

System:
  OS: Linux 4.15 Ubuntu 18.04.2 LTS
  CPU: (6) x64 AMD FX(tm)-6300 Six-Core Processor
  Memory: 794.44 MB / 3.59 GB
  Shell: 4.4.19 - 
Binaries:
  Node: 8.16.0
  npm: 6.4.1
npmPackages:
  react: 16.6.3 => 16.6.3 
  react-native: 0.58.3 => 0.58.3 
npmGlobalPackages:
  react-native-cli: 2.0.1

image_editor

ReactNative 0.60.3

Hello,

I'm currently using RN0.60.3.
But with the autolinking, I found that the podspec was targeting a wrong library.
'React/RTCImage' needs to be change by 'React-RTCImage'.

Thanks

Output size of ImageEditor.cropImage is incorrect

This issue is moved from react-native repo because the image editor was extracted. See original issue [#22941].

Issue Content

Environment

React Native Environment Info:
System:
OS: Windows 10
CPU: (4) x64 Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
Memory: 1.68 GB / 7.91 GB
Binaries:
Yarn: 1.9.4 - ~\AppData\Roaming\npm\yarn.CMD
npm: 6.5.0 - ~\AppData\Roaming\npm\npm.CMD
IDEs:
Android Studio: Version 3.2.0.0 AI-181.5540.7.32.5056338

Description

Occasionally, output of ImageEditor.cropImage is different from displaySize in cropData, for example setting displaySize to {width: 16, height: 16} will output size {width: 15, height: 15} or {width: 16, height: 16}

Reproducible Demo

Put the code below somewhere in the entry file, or use this snack

import { Image, ImageEditor } from "react-native";

// promisify functions
function cropImage(uri, cropData) {
  return new Promise((resolve, reject) =>
    ImageEditor.cropImage(uri, cropData, resolve, reject)
  );
}
function getSize(uri) {
  return new Promise((resolve, reject) =>
    Image.getSize(uri, (w, h) => resolve({ width: w, height: h }), reject)
  );
}

const width = 2160;
const height = 3840;
const displaySize = { width: 16, height: 16 };

// get a random pic of size 2160x3840
cropImage(`https://source.unsplash.com/random/${width}x${height}`, {
  offset: { x: 0, y: 0 },
  size: { width, height },
  displaySize,
  resizeMode: "cover",
})
  .then(resizedUri => getSize(resizedUri))
  .then(resizedDimensions => console.log(resizedDimensions));

// output:
// Object {
//   "height": 15,
//   "width": 15,
// }

// Expected output:
// Object {
//   "height": 16,
//   "width": 16,
// }

Conversation

@nrator :

After digging into the Android implementation, I believe the bug may be caused by using Math.floor instead of Math.round in these two lines of codes.

int cropWidth = (int) Math.floor(newWidth / (float) outOptions.inSampleSize);
int cropHeight = (int) Math.floor(newHeight / (float) outOptions.inSampleSize);

Since I am not a java developer and I am not familiar with the APIs, e.g. createBitmap, decodeStream, etc, I wish there is someone with more experience could help. Thanks!

@eXist-FraGGer:

@nrator Maybe you have an incorrect result because Image.getSize changed?
Try to use this library: react-native-image-size

@mcgloneleviROOT:

A teammate and I ran into a similar issue in our application. After a few hours of debugging, it looks like the image's size returned from Image.getSize is half the size for some reason. For example, we had a ~4000x3000 px image taken from an iPhone. Image.getSize would return 2000x1500. Scaling the value returned from the function by 2 fixed our problem.

Examples of manual link the library

Hi,

I tried to use react-native link to link the library. Since I'm integrating react native to an existing app, I'm getting errors. Can you show in the docs that about manual integration steps for iOS and Android?

Thanks.

What Mime is supported/returned

Question

The documentation never refers to Mimes.

  • Can all image/* be passed as the uri parameter?
  • Is the returned uri in the same Mime format or is it converted?
  • Is this the same on both platforms?

In the usage example documentation, there is a mismatch between the log uri & the param url:

ImageEditor.cropImage(uri, cropData).then(url => {
   console.log("Cropped image uri", url);
})

The promise probably returns an uri right?

- ImageEditor.cropImage(uri, cropData).then(url => {
+ ImageEditor.cropImage(uri, cropData).then(uri => {
-    console.log("Cropped image uri", url);
+    console.log("Cropped image uri", uri);
})

In the documentation you mention:

Remember to delete the cropped image from the cache path when you are done with it.

The documentation does not give an example for that, neither can I find one in the example app.
It would be welcomed to have such an example 😀.

I'm writing this as an issue instead of a stackoverflow question because this should end up as a PR to at least correct the README usage example uri/url mismatch

Cannot read property 'cropImage' of undefined

Question

Hello, i just install ImageEditor and use it to crop my image. But when i do this action, have warning like this "Cannot read property 'cropImage' of undefined".
This is my code
const cropData = {
offset:{x: 0, y: 0},
size: {width: image.width, height: image.height},
displaySize: {width: image.width, height: image.height},
resizeMode: 'contain'
}

  ImageEditor.cropImage(image.uri, cropData).then(url =>{
    console.log(`LIST ITEM SELECT`, url);
  }).catch(error =>{
    console.log(`ERROR`, error);
  })

Crop on negative offsets creates black content

Question

When I try to crop an image with negative offsets, it does fill the "no content" image with black. It does any way to select which color fill? I'm trying to do a cropper like instagram does, and on small images it does crop the image with negative offset and fills this content with white color if "light" appearance is active or "dark" depending on case

Add CI configuration.

We should run eslint, flow, typescript and unit tests on CI. Later we can think about implementing detox tests.

iOS compilation failures after Expo SDK 44/RN 0.64.3 upgrade

Environment

Expo SDK 44, React Native 0.64.3, XCode 13.2.1, macOS 12.1 Monterey

Worked fine in Expo SDK 43, React Native 0.64.3

Description

XCode errors:

/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:65:35: Implicit declaration of function 'RCTTransformFromTargetRect' is invalid in C99 /Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:65:35: Conflicting types for 'RCTTransformFromTargetRect'
/Users/test/testimageeditor/node_modules/react-native/Libraries/Image/RCTImageUtils.h:29:30: previous declaration is here
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:66:29: Implicit declaration of function 'RCTTransformImage' is invalid in C99
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:66:29: Conflicting types for 'RCTTransformImage'
/Users/test/testimageeditor/node_modules/react-native/Libraries/Image/RCTImageUtils.h:83:32: previous declaration is here
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:72:20: Implicit declaration of function 'RCTTargetRect' is invalid in C99
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:72:20: Conflicting types for 'RCTTargetRect'
/Users/test/testimageeditor/node_modules/react-native/Libraries/Image/RCTImageUtils.h:21:19: previous declaration is here Modules Issue Group
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:65:35: Declaration of 'RCTTransformFromTargetRect' must be imported from module 'React.RCTImageUtils' before it is required
/Users/test/testimageeditor/node_modules/react-native/Libraries/Image/RCTImageUtils.h:29:30: Declaration here is not visible
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:66:29: Declaration of 'RCTTransformImage' must be imported from module 'React.RCTImageUtils' before it is required
/Users/test/testimageeditor/node_modules/react-native/Libraries/Image/RCTImageUtils.h:83:32: Declaration here is not visible
/Users/test/testimageeditor/node_modules/@react-native-community/image-editor/ios/RNCImageEditor.m:72:20: Declaration of 'RCTTargetRect' must be imported from module 'React.RCTImageUtils' before it is required
/Users/test/testimageeditor/node_modules/react-native/Libraries/Image/RCTImageUtils.h:21:19: Declaration here is not visible

Reproducible Demo

  1. expo init testimageeditor
  2. cd testimageditor
  3. expo install @react-native-community/image-editor
  4. expo eject
  5. XCode } Open } ios/testimageeditor.xcworkspace
  6. Product } Build

Yellow box: "Warning: Calling bridge.imageLoader is deprecated and will not work in newer versions of RN. Please update to themoduleForClass API or turboModuleLookupDelegate API."

Bug

This Yellow Box warning appears whenever using the cropImage method of this library. Maybe due to the use of _bridge.imageLoader here.

Simulator Screen Shot - iPhone 11 - 2020-01-30 at 12 53 06

Environment info

React Native info output:

System:
    OS: macOS Mojave 10.14.5
    CPU: (8) x64 Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz
    Memory: 19.75 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.11.0 - ~/.nvm/versions/node/v12.11.0/bin/node
    npm: 6.11.3 - ~/.nvm/versions/node/v12.11.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.0, DriverKit 19.0, macOS 10.15, tvOS 13.0, watchOS 6.0
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.2
      System Images: android-29 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5977832
    Xcode: 11.0/11A420a - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: 0.61.5 => 0.61.5
  npmGlobalPackages:
    react-native-rename: 2.4.1

Library version: ^2.2.0

Steps To Reproduce

  1. Call cropImage with debug mode enabled.
  2. The image is correctly cropped, but the Yellow Box warning appears when the response is returned.

install error usning npm@7

npm install @react-native-community/image-editor --save
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"17.0.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.0" from @react-native-community/[email protected]
npm ERR! node_modules/@react-native-community/image-editor
npm ERR!   @react-native-community/image-editor@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/vemarav/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/vemarav/.npm/_logs/2021-08-04T05_02_55_224Z-debug.log

Version inconsistency

peerDependencies:"react-native": ">=0.57 <0.60",but local projects: "react-native": "0.61.5"

Support base64 Image output not only uri

Feature Request

Support output base64. Currently, when cropping process is successful it return uri, some
people maybe need base64.

Why it is needed

My backend only support base64 for upload images.

Possible implementation

Implement on native modules and create bridging to javascript.

Code sample

ImageEditor.cropImage(image, cropData).then(data => {
console.log("Cropped image base64", data.base64);
})

Getting error : "undefined is not a function (evaluating 'Object.keys(styles)[typof Symbol === "function"? Symbol.iterator : @@iterator"]()')"

I am using the cropImage from https://github.com/react-native-community/react-native-image-editor/issues/new.
Description :
Project created using react-native init

react-native info

React Native Environment Info:
System:
OS: Linux 4.15 Ubuntu 18.04.2 LTS (Bionic Beaver)
CPU: (6) x64 AMD FX(tm)-6300 Six-Core Processor
Memory: 405.62 MB / 3.59 GB
Shell: 4.4.19
Binaries:
Node: 8.16.0
npm: 6.4.1
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.58.3 => 0.58.3
npmGlobalPackages:
react-native-cli: 2.0.1
Code :
_cropImage = async () => {

let resizedUri = await new Promise((resolve, reject) => {
  ImageEditor.cropImage(this.state.image,
    {
      offset: { x: 0, y: 0 },
      size: { width: 100, height: 100 },
      displaySize: { width: 100, height: 100 },
      resizeMode: 'contain',
    },
    (uri) => resolve(uri),
    () => reject(),
  );
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.