Expensify / react-native-qrcode-svg

A QR Code generator for React Native based on react-native-svg and node-qrcode.
MIT License
1.07k stars 217 forks source link

getRef={ c =>{ c.toDataURL // undefiend } how to shear QrCode as image #148

Open SiddharthAlagesan opened 3 years ago

SiddharthAlagesan commented 3 years ago

_this.svg.toDataURL is not a function

15 | 16 | saveQRCode = () => {

17 | this.svg.toDataURL(this.callback); | ^ 18 | }


  saveQRCode = () => {
    this.svg.toDataURL(this.callback);
  };

  callback(dataURL) {
    console.log(dataURL);
    let shareImageBase64 = {
      title: 'Required Data ',
      url: `data:image/png;base64,${dataURL}`,
      subject: 'Share Link', //  for email
    };
    console.log(dataURL)
    Share.open(shareImageBase64).catch(error => console.log(error));
  }
<TouchableOpacity onPress={this.shareQR}>
          <QRCode
            value={this.state.input }
            size={250} 
            color="#000"
            getRef={ c =>{  
                              this.svg= c;
                             console.log(c)   //Svg {props: {…}, context: {…}, refs: {…}, updater: {…}, _remeasureMetricsOnActivation: ƒ, …}
                             console.log(c.toDataURL )  // undefined
                             }}/>
</TouchableOpacity>
 <Button onPress={this.saveQRCode} title="Shear"  />
 />
schmidi64 commented 3 years ago

I fixed this problem by using react-native-view-shot. I use expo-captureRef in the example.

From "captureRef" you will get the path to the screenshot. For example you can share the screenshot with this path. Apply some padding to the view which is outside the qr-code element - this makes it way better to scan. The prop "collapsable={false}" is needed to get a valid ref from the view element. The function "someFunction" is called onClick in my case.

Something like this:

function QrCode() {
  const viewRef = useRef()

  const someFunction = async () => {
      const path = await captureRef(viewRef.current, {
        quality: 1,
        format: 'png',
      })
   }

  return (
    <View style={styles.xy} collapsable={false} ref={(ref) => viewRef.current = ref}>
              <QRCode
                  color='black'
                  backgroundColor='white'
                  value="Some String"
                  size={Dimensions.get('window').width - 40}
              />
    </View>
  )
}

It is more like a workaround but it works :D

hunghg255 commented 1 year ago

You can assign base64 to ref by this one

const refQrCode = useRef();

  return <>
    <QrCode 
      getRef={c => {
        if (!c?.toDataURL) return;

        c?.toDataURL(base64Image => {
          refQrCode.current = base64Image;
        })
      }}
    />
  </>;
narcismihaitech commented 1 year ago

You can assign base64 to ref by this one

const refQrCode = useRef();

  return <>
    <QrCode 
      getRef={c => {
        if (!c?.toDataURL) return;

        c?.toDataURL(base64Image => {
          refQrCode.current = base64Image;
        })
      }}
    />
  </>;

This worked for me.