项目背景
最近做了个电子报项目,用户可在上传的报刊版面图上划出一个个区域,通过OCR图文识别技术,识别出区域文字信息,然后编辑成一条条新闻,可在PC端和手机端点击版面图,查看新闻详情。
⚠️关键技术点: 用Canvas如何绘制出裁剪框。
本文主要介绍裁剪框的实现过程。
单个裁剪
批量裁剪
Canvas技术点
CanvasRenderingContext2D.drawImage()方法
CanvasRenderingContext2D.save()和CanvasRenderingContext2D.restore()方法的成对使用
CanvasRenderingContext2D.globalCompositeOperation属性
CanvasRenderingContext2D.getImageData()、CanvasRenderingContext2D.putImageData方法
🔥小贴士:如果您对本文有兴趣,期望您先了解以上技术点。
流程简介
读取图片
用Canvas绘制图片
drawImage()的使用
绘制版面图
裁剪操作
基本裁剪流程
裁剪框的绘制
输出裁剪图片
getImageData()的使用
putImageData()的使用
使用Canvas.toDataURL()输出图片
使用OCR识别图片信息
一、读取图片
组件初始化时,通过new Image对象读取图片链接;
若图片是通过本地上传的,可用new FileReader对象读取。
⚠️注意点:
图片的跨域问题;
image.src = url放在图片读取后面,因为会偶发图片读取异常。
🔨实现代码如下:
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Button } from 'antd';
import styles from './index.less';
/**
*file 版面文件
*useOcr true:通过OCR转换成文字;false:转换为图片
*onTransform 转换成文字或图片后调用组件外部方法
*/
export default function ({ file, useOcr, onTransform }) {
const { url } = file;
const [originImg, setOriginImg] = useState(); // 源图片
const [contentNode, setContentNode] = useState(); // 最外层节点
const [canvasNode, setCanvasNode] = useState(); // canvas节点
const [btnGroupNode, setBtnGroupNode] = useState(); // 按钮组
const [startCoordinate, setStartCoordinate] = useState([0, 0]); // 开始坐标
const [dragging, setDragging] = useState(false); // 是否可以裁剪
const [curPoisition, setCurPoisition] = useState(null); // 当前裁剪框坐标信息
const [trimPositionMap, setTrimPositionMap] = useState([]); // 裁剪框坐标信息
const fileSyncUpdating = useSelector(state => state.loading.effects['digital/postImgFileWithAliOcr']);
const dispatch = useDispatch();
const initCanvas = () => {
// url为上传的图片链接
if (url == null) {
return;
}
// 实例化一个Image对象,获取图片宽高,用于设置canvas宽高
const image = new Image();
image.addEventListener('load', () => {
...
});
image.crossOrigin = 'anonymous'; // 解决图片跨域问题
image.src = url;
};
useEffect(() => {
initCanvas();