因为最近拿到一个很奇怪的需求,因为要同时展示OCR原图和识别结果,而原图往往很高,就希望能够在图片垂直滚动的时候,只动态展示当前可视区域内的识别结果。
原理很简单,ocr的识别结果都是会告知识别框的四角坐标。如下面这样,每两个值一组,分别代表左上、左下,右下、右上,我们根据第2个和第4个值就可以知道这个矩形的y轴上下边界y1和y2。
"bboxes": [[27, 299, 27, 360, 107, 360, 107, 299]]
<img>在滚动时我们可以通过react提供的ref属性知道它当前的滚动位置,然后再根据图片的缩放比,还原出当前可视区域的y轴边界所对应的原图区域y3和y4
有了y1,y2,y3,y4,我们就可以简单的求区间交集,来判断某条ocr识别结果是否在当前页面是可视的,然后展示出来。
网页
准备imageContainerRef,imageRef两个ref,分别应用于存放<img>的容器和<img>。
imageContainerRef用来获取当前滚动的位置,imageRef可以获得原图的宽、高。
容器需要支持垂直滚动'overflow-y-auto'。
最开始我尝试只使用一个<img>,放弃容器,但我发现<img>不支持'overflow-y-auto'进行滚动,直接把整个网页撑得特别高,也可能是我太菜了😭
<div className='flex-grow w-1/2 h-full overflow-y-auto' ref={imageContainerRef}>
<img
className={cn('flex-grow w-full')}
src={'http://balabala.com/1.jpg'}
alt={"图挂了"}
ref={imageRef}
onWheel={handleImgScroll}
onLoad={handleImgScroll}
/>
</div>
滚动函数
const handleImgScroll = () => {
if (imageRef.current && imageContainerRef.current) {
//高度缩放比
const scaleRatio = imageRef.current.naturalHeight / imageContainerRef.current.scrollHeight
//当前滚动位置*缩放比,得到对应的原图位置(可视上界)
const curTopPosition = scaleRatio * imageContainerRef.current.scrollTop
//(滚动位置+显示高度)*缩放比,得到(可视下界)
const curBottomPosition = scaleRatio * (imageContainerRef.current.scrollTop + imageContainerRef.current.clientHeight)
/*
*根据可视区域,筛选ocr结果
*因为一般ocr结果都是从上到下按顺序存放的,所以只需要筛选一个区间[start,end]即可
*/
setImageVisibleArea({ top: curTopPosition, bottom: curBottomPosition })
setOcrResult({ startIndex: start, endIndex: end })
}
}