Coder Social home page Coder Social logo

expo-image-crop's Introduction

Expo image manipulator

Multi platform ๐Ÿš€





npm version npm version npm version

Open on your device!

Crop and rotate image without detach your expo project!

Expo.ImageManipulator is only an API, so it does not contain a UI. You will have to build your own UI on top of it, or choose to detach your project and use third party linked packages, which is not as good because a pure javascript Expo project is marvelous!

PRs are welcome...

No more flickering while resizing image mask!

Compatible with Expo SDK 36

Atention: squareAspect was removed on this version and will be add in future versions, if you need it, please stay at 0.2.17

Expo Dependences

  • yarn add react-native-vector-icons
  • expo install expo-permissions
  • expo install expo-image-picker
  • expo install expo-file-system
  • expo install expo-image-manipulator

Example

import React from 'react'
import { Dimensions, Button, ImageBackground } from 'react-native'
import { ImageManipulator } from 'expo-image-crop'

export default class App extends React.Component {
  state = {
      isVisible: false,
      uri: 'https://i.pinimg.com/originals/39/42/a1/3942a180299d5b9587c2aa8e09d91ecf.jpg',
  }
  onToggleModal = () => {
      const { isVisible } = this.state
      this.setState({ isVisible: !isVisible })
  }
  render() {
      const { uri, isVisible } = this.state
      const { width, height } = Dimensions.get('window')
      return (
          <ImageBackground
              resizeMode="contain"
              style={{
                  justifyContent: 'center', padding: 20, alignItems: 'center', height, width, backgroundColor: 'black',
              }}
              source={{ uri }}
          >
              <Button title="Open Image Editor" onPress={() => this.setState({ isVisible: true })} />
              <ImageManipulator
                  photo={{ uri }}
                  isVisible={isVisible}
                  onPictureChoosed={({ uri: uriM }) => this.setState({ uri: uriM })}
                  onToggleModal={this.onToggleModal}
              />
          </ImageBackground>
      )
  }
}

Props

Props Type Default Description
isVisible boolean false Show or hide modal with image manipulator UI
onPictureChoosed function Callback where is passed image edited as parameter
photo object { "uri": string } uri of image to be edited
btnTexts object { "crop": string, "done": string, "processing": string} name for crop, done and processing texts
onToggleModal function Callback called when modal is dismissed
borderColor string #a4a4a4 Color for crop mask border
allowRotate boolean true Show rotate option
allowFlip boolean true Show flip option
saveOptions object { "compress": number, "format": string, "base64": boolean} A map defining how modified image should be saved
fixedMask object { "width": number, "height": number } Width and height fixed mask

Return of onPictureChoosed is an object with format:

{
    uri: string,
    base64: string // undefined if base64 is false on saveOptions prop
}

Run the example!

  • Clone this repository
  • cd example/
  • run yarn or npm install
  • enjoy!

The animation is fluid even on dev mode!

Requirements

  • Use it into Expo app (from expo client, Standalone app or ExpoKit app).
  • Because we need to have access to ImageManipulator

Features

  • Crop
  • Rotate
  • Flip (Horizontal and Vertical)
  • Base64

If you have some problem open a issue

expo-image-crop's People

Contributors

brunon80 avatar gabrielmurry avatar jrobber avatar moa-novae avatar prakashbask avatar tawachan 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

expo-image-crop's Issues

squareAspect

Thanks for this valuable tool! I see squareAspect used in this example. When I add it as a prop it doesn't actually force a square aspect ratio.

Error on sending a image uri on iOS

When i take a picture and send to ImageManiputalor using the image URI i get the following error:

No suitable image URL loader found for (null)...

OBS: works fine on Android

Doesn't work with new function based React.useState approach

I think due to the lifecycle design of the component, somehow this doesn't work with the const [stateName,changeStateFunction]=React.useState(default) approach, the state just not changeable even I call the change state function. Please consider refactor.

The tool no matter what I crop, always only crops the upper left side of the image

This on newer code than 0.2.10, I got the code from master branch, just after it was upgraded to expo 35.
Edit: version 0.2.11

This on huawei p30 (I suspect it might happen in newer models of cameras since it used to work fine in my older phone)

So no matter what section of the image I decide to crop, it always only show me the upper left section of the image

This image explain it

cropBug

Rotate functionality doesnt work in recent update

if you press Rotate yo get a black screen and next error.

[Unhandled promise rejection: Error: Cannot load an empty url]
- node_modules/react-native/Libraries/Network/XMLHttpRequest.js:461:22 in open
* src/componentes/TomarFoto.js:188:15 in toDataURL$
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:30 in invoke
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:135:28 in invoke
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:170:17 in <unknown>
- node_modules/promise/setimmediate/core.js:45:7 in tryCallTwo
- node_modules/promise/setimmediate/core.js:200:23 in doResolve
- node_modules/promise/setimmediate/core.js:66:12 in Promise
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:169:27 in callInvokeWithMethodAndArg
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:192:38 in enqueue
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:216:8 in async
* src/componentes/TomarFoto.js:193:14 in getBase64FromUrl$
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
- node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:30 in invoke
- ... 13 more stack frames from framework internals

I did the change of source.uri instead of just source, in my code

ImageManipulator not clearing recent images.

Hi! I'm new in React Native so sorry if it's my ignorance. Well I've found an issue that is really disturbing me, I've an app that you can upload various images. The problem is that when I want to crop the second image, the ImageManipulator component shows me the first image! But an image viewer that is in the same return as the ImageManipulator shows me the right image.

This is happening on a physical IPhone 8 and in a HTC M9 with Android 7.

The code:
`<ImageManipulator
photo={{uri: image.uri}}
isVisible={isVisible}
btnTexts={{crop: 'Cortar', rotate: 'Rotar', done: 'Listo', processing: 'Listo'}}
onPictureChoosed={uriM => setImage({ uri: uriM })}
onToggleModal={() => onToggleModal()}
/>

<TouchableOpacity onPress={() => setVisible(true)}>
<Image source={{uri: image.uri}} style={styles.imagePortrait} />
`

And a screens of the issue so you can see whats happening:
githun

Image Grayscale

How easy would it be to add an option to make the image grayscale and/or have the ability to adjust the exposure/contrast?

warning

Possible Unhandled Promise Rejection (id: 0):
Object {
"code": "EABI36_0_0RCTERRORDOMAIN0",
"domain": "ABI36_0_0RCTErrorDomain",
"message": "Cannot load a photo library asset with no URL",
"nativeStackIOS": Array [
"0 Exponent 0x000000010286becb ABI36_0_0RCTJSErrorFromCodeMessageAndNSError + 79",
"1 Exponent 0x000000010286be49 ABI36_0_0RCTJSErrorFromNSError + 209",
"2 Exponent 0x0000000102828623 __50-[ABI36_0_0RCTModuleMethod processMethodSignature]_block_invoke_4.90 + 70",
"3 Exponent 0x0000000102882e3f __59-[ABI36_0_0RCTImageLoader getImageSizeForURLRequest:block:]_block_invoke + 649",
"4 Exponent 0x000000010287faf3 __127-[ABI36_0_0RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:partialLoadBlock:completionBlock:]_block_invoke + 225",
"5 Exponent 0x00000001028801aa __127-[ABI36_0_0RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:partialLoadBlock:completionBlock:]_block_invoke_2.184 + 43",
"6 Exponent 0x000000010289a0d1 -[ABI36_0_0RCTPhotoLibraryImageLoader loadImageForURL:size:scale:resizeMode:progressHandler:partialLoadHandler:completionHandler:] + 429",
"7 Exponent 0x000000010287ff0f __127-[ABI36_0_0RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:partialLoadBlock:completionBlock:]_block_invoke.183 + 264",
"8 libdispatch.dylib 0x00007fff5223e848 _dispatch_call_block_and_release + 12",
"9 libdispatch.dylib 0x00007fff5223f7b9 _dispatch_client_callout + 8",
"10 libdispatch.dylib 0x00007fff52245526 _dispatch_lane_serial_drain + 707",
"11 libdispatch.dylib 0x00007fff52245f5c _dispatch_lane_invoke + 388",
"12 libdispatch.dylib 0x00007fff5224fff9 _dispatch_workloop_worker_thread + 626",
"13 libsystem_pthread.dylib 0x00007fff524636fc _pthread_wqthread + 290",
"14 libsystem_pthread.dylib 0x00007fff52462827 start_wqthread + 15",
],
"userInfo": Object {
"NSLocalizedDescription": "Cannot load a photo library asset with no URL",
},
}

This library is not compatible with expo 34

Version: 0.2.8

Latest expo versions has been separating modules away from expo module, and this time was the opportunity to imagemanipulator module.

Screenshot_1566765226

I installed this in my project (expo install expo-image-manipulator), but the bug is still there, which I think it means its the library the one that needs to get updated.

So because of this, its not possible to crop any photo.
Can this please be fixed?

[Feature request] Language support

This library is great, but its only in english. If I were able to change it to spanish would be great.

Another option would be for each person to manually translate it manually every time the library is used (through some parameter for each one of 'crop', 'rotate', etc, or through a json like some other libraries does)

Use this Image Crop directly

I want to use this Image Crop library directly wherein I only need to do cropping function.

So instead of putting it in Modal, I want to use it in a "View" instead.

And with this, I am thinking to put the crop overlay getting placed at first only, to its default values over the image

Here is the link of Modified Image Manipulator: https://github.com/keyurpatel8118/Customized-Image-Manipulator/blob/master/manipulator/ImageManipulator.js

If anyone has any suggestions please let me know.

Thank You!

Wrong crop area

On ios, the image after cropping does not have the correct boundaries. It looks like it is shifting the box down by many pixels.As you can see in the attached screenshots, I select a crop area that should almost exactly contain the message box, but then in the next screen, it is cutting off the top of the box and including an area below that wasn't selected.
313354407_3237090773225312_2997301304535308690_n

313337169_1477644912739085_6013363738806337020_n

Divide by zero bug

Screen Shot 2020-05-12 at 8 03 43 PM

If you open the cropper before the image is fully loaded in, you will get this error.

It's because you are dividing zero by zero.

        this.actualSize = {
            width: 0,
            height: 0,
        }

You set that on constructor...so if that doesn't get changed, things will blow up.

Basically you can't launch the cropper until +onConvertImageToEditableSize+ finishes...

So I had to fix it by:

  // @aryk I direct copy/paste from the library except for one line added...
  async onConvertImageToEditableSize() {
    // @ts-ignore
    const { photo: { uri: rawUri } } = this.props;
    RNImage.getSize(rawUri, async (imgW, imgH) => {
      // @ts-ignore
      const { convertedWidth, convertedheight } = this.onGetCorrectSizes(imgW, imgH);
      const { uri, width: w, height } = await ImageManipulator.manipulateAsync(rawUri,
        [
          {
            resize: {
              width: convertedWidth,
              height: convertedheight,
            },
          },
        ]);
      // @ts-ignore
      this.setState({
        uri,
      });
      // @ts-ignore
      this.actualSize.width = w;
      // @ts-ignore
      this.actualSize.height = height;
      // @ts-ignore
      if (this.props.onReady) this.props.onReady(); // this line added
    }, handleError);
  }

Excuse the Typescript ignores...

Basically I added:

     if (this.props.onReady) this.props.onReady(); // this line added

So I put a callback that lets me know when I can actually launch the cropper...there is a 2 second delay about...

Can you make "photo" as a not-mandatory prop?

I'm trying to use "ImageManipulator" as a stan-by modal that's always on the screen and used when there is an image to edit.

When I keep "ImageManipulator" hidden by making isVisible=false, EXPO keeps nagging on me saying that "photo" is needed a prop, please provide some.

Help me.

Failed to get size for image: undefined

When I have applied this with functional component implementation. It pops up with the error: Failed to get size for image: undefined
Defining component like this:

const { width, height } = useWindowDimensions();
const [isVisible, setIsVisible] = useState(true);
const [uri, setUri ] = useState(imageUri);

const onToggleModal = () => {
    setIsVisible(false);
}

<ImageBackground
resizeMode="contain"
style={{...styles.imgBack, ...{width:width, height:height}}}
source={uri}
>
<ImageManipulator
photo={uri}
isVisible={isVisible}
onPictureChoosed={(uriM) => setUri(uriM)}
onToggleModal={onToggleModal}
/>

Stylesheet has:
imgBack:{
justifyContent: 'center',
padding: 20,
alignItems: 'center',
}

ExpoSDK33 issues

Hey, I was able to get this working on an SDK32 project but now i'm on 33 and things aren't working. I just keep getting a bunch of "module not found" errors after importing
import { ImageManipulator } from 'expo-image-crop'
and then I go and add the imports that it mentions and finally I'm left with the error
The Expo SDK requires Expo to run...

onPictureChoosed return Base64?

Hey, thanks for creating this. This isn't an issue but more of a suggestion - can you make it so onPictureChoosed also returns the cropped image base64 value?

It would be very helpful to have both uri and base64.

I know you can set ImageManipulator.manipulateAsync() to return base64 so I don't think this should be too much to ask for :)

Thank you

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.