YanYuanFE / react-native-signature-canvas

:black_nib: React Native Signature Component based WebView Canvas for Android && IOS && expo
MIT License
419 stars 150 forks source link

Save signature to Android gallery #16

Open AlbertoPotter opened 5 years ago

AlbertoPotter commented 5 years ago

Hi YanYuan!

I´m building an app that requires a signature functionality and your component is just great.

Though in your README I can´t find an example where you save the signature to the gallery, and because I´m new in React Native I haven´t been able to implement a hack that lets me save the signature.

Thanks in advanced!

YanYuanFE commented 5 years ago

Thanks! You can try this method。

import RNFetchBlob from 'rn-fetch-blob';
import RNFS from 'react-native-fs';
import { Alert, Platform, CameraRoll } from 'react-native';

export default function (base64Img, success, fail) {
  const dirs = Platform.OS === 'ios' ? RNFS.LibraryDirectoryPath : RNFS.ExternalDirectoryPath; // 外部文件,共享目录的绝对路径(仅限android)
  const downloadDest = `${dirs}/${((Math.random() * 10000000) | 0)}.png`;
  const imageDatas = base64Img.split('data:image/png;base64,');
  const imageData = imageDatas[1];

  RNFetchBlob.fs.writeFile(downloadDest, imageData, 'base64').then((rst) => {
    // console.log('writeFile',downloadDest)
    try {
      CameraRoll.saveToCameraRoll(downloadDest).then((e1) => {
        console.log('suc',e1)
        success && success()
      }).catch((e2) => {
        console.log('fai',e2)
        Alert.alert('没有读写权限。请在[设置]-[应用权限]-[实验助手]开启')
      })
    } catch (e3) {
      // Alert.alert(JSON.stringify(e3))
      console.log('catch',e3)
      fail && fail()
    }
  });
}
AlbertoPotter commented 5 years ago

Hey @YanYuanFE , thank you for your response.

I'll make sure to close this issue once I had implemented this solution and give detailed information on how I did it.

Keep hacking!.

isocra commented 4 years ago

Hi @YanYuanFE,

I've been trying to get this working with Expo (managed flow) but I'm stuck. I need to be able to turn the base64 data into a blob so that I can upload it with AWS AppSync. If I could save the image away as a file, that would be fine too, but every way I've tried seems not to work

// Error is TypeError: Network request failed at XMLHttpRequest.xhr.onerror (whatwg-fetch.js:504) at XMLHttpRequest.dispatchEvent (event-target.js:172) at XMLHttpRequest.setReadyState (XMLHttpRequest.js:580) at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:394)

* I've tried creating the byteArray like this, but I get an error :
```typescript
export function dataURItoBlob(dataURI: string) {
  // convert base64 to raw binary data held in a string
  // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
  const byteString = atob(dataURI.split(',')[1]);

  // separate out the mime component
  const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

  // write the bytes of the string to an ArrayBuffer
  const ab = new ArrayBuffer(byteString.length);

  // create a view into the buffer
  const ia = new Uint8Array(ab);

  // set the bytes of the buffer to the correct values
  for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
  }

  // write the ArrayBuffer to a blob, and you're done
  return new Blob([ab], { type: mimeString });
}

// Error is
Error: Creating blobs from 'ArrayBuffer' and 'ArrayBufferView' are not supported

Thanks!!

YanYuanFE commented 4 years ago

Hi @isocra , Thank you for your attention。 You can try this library instead of rn-fetch-blob for expo.

https://github.com/HCL-HO/react-native-fetch-blob-expo

isocra commented 4 years ago

Hi, with Expo SDK38, I've found a way of doing this. In the handleSignature method that gets the signature as base64, I use

    const newFileUri = `${FileSystem.documentDirectory}${Date.now()}.jpg`;
    const dataPart = signature.split(',', 2);
    await FileSystem.writeAsStringAsync(newFileUri, dataPart[1], {encoding: FileSystem.EncodingType.Base64});