使用 react-native-pdf 在 react-native 上获取准确的 x 和 y 坐标

Posted

技术标签:

【中文标题】使用 react-native-pdf 在 react-native 上获取准确的 x 和 y 坐标【英文标题】:Getting the exact x and y coordinates on react-native using react-native-pdf 【发布时间】:2021-05-07 07:45:32 【问题描述】:

我试图创建一个 PDF 查看器并通过将项目(文本、图像)插入到我们应用程序的 PDF 上的确切 x 和 y 坐标来修改它。我使用 react-native-pdf 查看 pdf @skynetcmg47/react-native-drag-resize 来拖动和调整大小,并使用 react-native-pdf-lib 来修改/插入文本、图像.. 我尝试使用 pdf-lib 来修改 pdf,但在 android 的发布模式上存在问题。 PDFDocument.load(pdfArrayBuffer) "this.bytes.slice(start, end) undefined" 并导致更改为 react-native-pdf-lib 但没有获取 PDF 大小的选项。

基础参考:

https://medium.com/alameda-dev/react-native-pdf-digital-signature-b63e12cdc714

代码:

 doneSet = async (page, x, y) => 
    let newX = x;
    let newY = y;
    if (Platform.OS == 'ios') 
        newX = x ? !DeviceInfo.isTablet() ? this.state.pageWidth * (x - 12) / Dimensions.get("window").width : x : 0;
        newY = y ? !DeviceInfo.isTablet() ? (this.state.pageHeight - (this.state.pageHeight * (y + 12)) / hp('90%')) :  this.state.pageHeight - y : 0;
        console.log(this.state.pageWidth, this.state.pageHeight, newX, newY, x, y, this.state.pageHeight - y)
     else 
        newX = x ? !DeviceInfo.isTablet() ? (this.state.pageWidth  * x) / this.state.pageWidth : x : 0;
        newY = y ? !DeviceInfo.isTablet() ? (this.state.pageHeight - ((this.state.pageHeight * y) / this.state.pageHeight)) - 25 : this.state.pageHeight - y : 0;
        console.log(this.state.pageWidth, this.state.pageHeight, newX, newY, x, y)
    
    if (this.state.pdfEditMode) 
        this.setState( pdfEditMode: false , () =>  );
        const page1 = PDFPage
            .modify(page - 1)
            .drawImage(this.state.signaturePath, 'png', 
                x: newX, // <- X coordinate location
                y: newY, // <- Y coordinate location
                width: this.state.signatureW,
                height: this.state.signatureH
            );
        PDFDocument
            .modify(this.state.filePath)
            .modifyPages(page1)
            .write()
            .then(data => 
                RNFS.readFile(data, "base64").then((contents) => 
                    let previousDocumentCopy = this.state.previousDocument;
                    previousDocumentCopy.push( filePath: data, pdfBase64: contents, pdfArrayBuffer: this._base64ToArrayBuffer(contents) );
                    this.setState( filePath: data, pdfBase64: contents, pdfArrayBuffer: this._base64ToArrayBuffer(contents), documentIndex: previousDocumentCopy.length - 1, nextDocument: [], previewDocument: previousDocumentCopy, xValue: 0, yValue: 0, cxValue: 0, cyValue: 0, signatureW: 100, signatureH: 100 )
                )
            );
    


render() 
   return(
<SafeAreaView style= flex: 1>
<View style= flex: 1 >
   this.state.filePath ?
                    <View style= flex: 1 >
                        <Pdf
                            minScale=1.0
                            maxScale=1.0
                            scale=1.0
                            spacing=0
                            fitPolicy=2
                            enablePaging=true
                            onTouchStart=(e) => 
                                console.log('touchMove', e.nativeEvent);
                                if (this.state.pdfEditMode) 
                                    this.setState( showDraggrable: false, cxValue: e.nativeEvent.locationX, cyValue: e.nativeEvent.locationY, xValue: e.nativeEvent.locationX, yValue: e.nativeEvent.locationY , () => 
                                        setTimeout(() => 
                                            this.setState( showDraggrable: true, )
                                        , 0)
                                    )
                                
                            
                            usePDFKit=false
                            source= uri: `data:application/pdf;base64,$this.state.pdfBase64` 
                            onLoadComplete=(numberOfPages, filePath,  width, height ) =>  this.setPageWH(width, height) 
                            onPageChanged=(page, numberOfPages) => 
                                console.log(`current page: $page`);
                                this.setState( pageNumber: page );
                            
                            onError=(error) => 
                                console.log(error);
                            
                            onPressLink=(uri) => 
                                console.log(`Link presse: $uri`)
                            
                            // onPageSingleTap=(page, x, y) => 
                            //     console.log(x, y)
                            //     this.handleSingleTap(page, x, y);
                            // 
                            style=styles.pdf
                        />
                       
                        this.state.pdfEditMode && this.state.signaturePath && this.state.showDraggrable ? <DragResizeBlock isResizable isDraggable x=this.state.cxValue y=this.state.cyValue w=this.state.signatureW h=this.state.signatureH
                            onDragEnd=this._dragRelease
                            onResize=this._resizeStart
                            onResizeEnd=this._resizeRelease
                            connectors=['tl', 'tr', 'br', 'bl', 'c'] >
                            <View style= width: '100%', height: '100%', alignContent: 'center', alignItems: 'center' >
                                <View style= flexDirection: 'row', alignItems: 'center', zIndex: 10, position: 'absolute', top: 0, right: 0, backgroundColor: '#FFFFFF' >
                                    <TouchableOpacity style=[styles.message,] onPress=this.removeSignature>
                                        <Icon type='FontAwesome5' name='trash' style= fontSize: hp('1.8%'), margin: 3, color: '#d9534f'  />
                                    </TouchableOpacity>
                                    <TouchableOpacity style=[styles.message,] onPress=() => this.doneSet(this.state.pageNumber, this.state.xValue, this.state.yValue)>
                                        <Icon type='FontAwesome5' name='check-circle' style= fontSize: hp('1.8%'), margin: 3, color: '#5cb85c'  />
                                    </TouchableOpacity>
                                </View>
                                <FastImage
                                    source= uri: `data:image/png;base64,$this.state.signatureBase64` 
                                    style= aspectRatio: 4 / 3, width: '100%', height: '100%', 
                                    resizeMode=FastImage.resizeMode.cover />
                            </View>
                        </DragResizeBlock> : null
                    </View> : null
</View>
</SafeAreaView>
)

库版本:

"react": "16.6.3",
"react-native": "0.58.1",
"react-native-pdf": "^5.1.7",
"rn-fetch-blob": "^0.10.15",
"react-native-pdf-lib": "^1.0.0",
"@skynetcmg47/react-native-drag-resize": "^1.0.3",

【问题讨论】:

【参考方案1】:

这是一个有点不同的库,我使用的是 react-native-pdf。 我用onPress props 包裹组件并获取当前的x 和y。 我必须调整细节的东西,但这样我认为你可以做你想做的事

const onPress = (e) => 
console.log('onpress x: ', e.nativeEvent.locationX)
console.log('onpress y: ', e.nativeEvent.locationY)

【讨论】:

感谢@ykim 的回答。但我已经做到了,它得到的是手机/设备 x 和 y,而不是实际的 pdf x 和 y 坐标。 是的,我后来意识到了:(你能得到 pdf x 和 y 坐标吗? 抱歉回复晚了。没问题...我们使用第三方应用程序来获取 pdf 中填充的确切 x 和 y 坐标。 啊,我明白了,你用什么工具来获得精确的 x,y 坐标? 我们使用了 Mac 版 Skim 或 Mac 版和 windows 版 Gimp。

以上是关于使用 react-native-pdf 在 react-native 上获取准确的 x 和 y 坐标的主要内容,如果未能解决你的问题,请参考以下文章

react-native-pdf iOS 和 Android 构建错误

React-Native-Pdf 无法从应用程序本身设置源

react-native-pdf 库 gradle build 中的问题

React Native PDF 签名

AJAX+REA实现前后台数据交互的加密解密

pl/sql远程连接别人oracle数据库时,报错:ora-01034:oracle not available;ora-27101 shared memory rea