Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seafile_ocr #6548

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion frontend/src/components/dialog/image-dialog.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import Lightbox from '@seafile/react-image-lightbox';
import Lightbox from '../../react-image-lightbox';
import AIAPI from '../../utils/ai-api';

import '@seafile/react-image-lightbox/style.css';
import { Utils } from '../../utils/utils';
import toaster from '../toast';


const propTypes = {
imageItems: PropTypes.array.isRequired,
Expand All @@ -14,6 +19,19 @@ const propTypes = {

class ImageDialog extends React.Component {

ocrRecognition = (src, successCallBack) => {
const repoIndex = src.indexOf('/repo/') + 6;
const rawIndex = src.indexOf('/raw/');
const repoId = src.slice(repoIndex, rawIndex);
const path = decodeURIComponent(src.slice(rawIndex + 4));
AIAPI.ocrRecognition(repoId, path).then(res => {
successCallBack(res.data.ocr_result);
}).catch(error => {
const errorMessage = Utils.getErrorMsg(error);
toaster.danger(errorMessage);
});
};

render() {
const imageItems = this.props.imageItems;
const imageIndex = this.props.imageIndex;
Expand All @@ -37,6 +55,7 @@ class ImageDialog extends React.Component {
closeLabel={gettext('Close (Esc)')}
zoomInLabel={gettext('Zoom in')}
zoomOutLabel={gettext('Zoom out')}
ocrRecognition={this.ocrRecognition}
/>
);
}
Expand Down
41 changes: 41 additions & 0 deletions frontend/src/react-image-lightbox/constant.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Min image zoom level
export const MIN_ZOOM_LEVEL = 0;

// Max image zoom level
export const MAX_ZOOM_LEVEL = 300;

// Size ratio between previous and next zoom levels
export const ZOOM_RATIO = 1.007;

// How much to increase/decrease the zoom level when the zoom buttons are clicked
export const ZOOM_BUTTON_INCREMENT_SIZE = 100;

// Used to judge the amount of horizontal scroll needed to initiate a image move
export const WHEEL_MOVE_X_THRESHOLD = 200;

// Used to judge the amount of vertical scroll needed to initiate a zoom action
export const WHEEL_MOVE_Y_THRESHOLD = 1;

export const KEYS = {
ESC: 27,
LEFT_ARROW: 37,
UP_ARROW: 38,
RIGHT_ARROW: 39,
DOWN_ARROW: 40,
};

// Actions
export const ACTION_NONE = 0;
export const ACTION_MOVE = 1;
export const ACTION_SWIPE = 2;
export const ACTION_PINCH = 3;
export const ACTION_ROTATE = 4;

// Events source
export const SOURCE_ANY = 0;
export const SOURCE_MOUSE = 1;
export const SOURCE_TOUCH = 2;
export const SOURCE_POINTER = 3;

// Minimal swipe distance
export const MIN_SWIPE_DISTANCE = 200;
3 changes: 3 additions & 0 deletions frontend/src/react-image-lightbox/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Lightbox from './react-image-lightbox';

export default Lightbox;
75 changes: 75 additions & 0 deletions frontend/src/react-image-lightbox/ocr-canvas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useRef, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';

const OCRResultCanvas = ({
className,
data,
style,
}) => {
const ref = useRef(null);

useEffect(() => {

}, []);

useEffect(() => {
// 获取当前dom的位置信息
const dom = document.getElementsByClassName('ril-image-current')[0];
const { clientHeight, clientWidth } = dom;

const canvas = ref.current;
canvas.height = clientHeight;
canvas.width = clientWidth;

const ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, canvas.width, canvas.height);
data.forEach(item => {
console.log(item);
// ctx.font = `${item.location.height / 1.5}px Arial`;
ctx.fillStyle = '#fff';
ctx.opacity = 1;
// 根据位置信息绘制文字
ctx.fillText(item.words, item.location.left, item.location.top);
});
}, [data]);

const handleClick = useCallback((event) => {
const canvas = ref.current;
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const ctx = canvas.getContext('2d');

const selectedText = data.find(item => {
const fontMetrics = ctx.measureText(item.words);
const textWidth = fontMetrics.width;
const textHeight = item.location.height;
const textX = item.location.left;
const textY = item.location.top;

// 判断点击位置是否在文字区域内
return (
x >= textX &&
x <= textX + textWidth &&
y >= textY &&
y <= textY + textHeight
);
});
if (selectedText) {
// 给选中的文字添加背景色
ctx.fillStyle = 'yellow'; // 这里设置背景色为黄色,你可以根据需要修改
ctx.fillRect(selectedText.location.left, selectedText.location.top, ctx.measureText(selectedText.words).width, selectedText.location.height);
}
}, [data]);


return (
// <div style={{ position: 'relative' }}>
// <div style={{ position: 'absolute', zIndex: 1 }}></div>
<canvas ref={ref} className={className} style={{ ...style, opacity: 0 }} onClick={handleClick}/>
// </div>
);
};

export default OCRResultCanvas;
Loading