iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0
SideProject30

想要學 50 音!系列 第 13

[DAY-13] 來看你寫的對不對拉!!

  • 分享至 

  • xImage
  •  

GitHub

我要學50音

  • 實作後的成果
  • 隨著每天的更新都會變化唷唷~~

tesseract.js

辨識手寫字的套件(OCR)

  • install
npm install tesseract.js

直接來看 code~~

import React, { useRef, useState } from "react";
import { createWorker } from "tesseract.js";
import { Grid, Button, Paper, Popover } from "@mui/material";
import CanvasDraw from "react-canvas-draw";
import { GithubPicker } from "react-color";
import LinearProgress from "@mui/material/LinearProgress";

//
// IMPORT ZONE
//

const Day13 = () => {
  const canvasRef = useRef(null);
  const [ocrResult, setOcrResult] = useState(undefined);
  const [selectedColor, setSelectedColor] = useState("#000");
  const [colorAnchor, setColorAnchor] = useState(null);
  const [ocrStatus, setOcrStatus] = useState(0); // 0: no start, 1: processing, 2: done

  const resolvePaintingText = async (dataUrl) => {
    const worker = await createWorker();
    await worker.loadLanguage("jpn");
    await worker.initialize("jpn");
    const {
      data: { text },
    } = await worker.recognize(dataUrl);

    await worker.terminate();
    return text;
  };

  const handleSaveOnClick = async () => {
    setOcrStatus(1);
    const dataUrl = canvasRef.current.getDataURL();
    const ocrText = await resolvePaintingText(dataUrl);
    setOcrResult(ocrText);
    setOcrStatus(2);
  };
  const handleUndoOnClick = () => {
    canvasRef.current.undo();
  };
  const handleColorOnClick = (e) => {
    setColorAnchor(e.currentTarget);
  };
  const handleColorOnClose = () => {
    setColorAnchor(null);
  };

  const handleColorOnChange = (color) => {
    // color = {
    //   hex: '#333',
    //   rgb: {
    //     r: 51,
    //     g: 51,
    //     b: 51,
    //     a: 1,
    //   },
    //   hsl: {
    //     h: 0,
    //     s: 0,
    //     l: .20,
    //     a: 1,
    //   },
    // }
    const h = color.hex;
    setSelectedColor(h);
    handleColorOnClose();
  };
  const colorOpen = Boolean(colorAnchor);
  const colorButtonId = colorOpen ? "simple-popover" : undefined;
  return (
    <Grid
      container
      spacing={{ mobile: 1, tablet: 2, laptop: 3 }}
      style={{ textAlign: "center" }}
    >
      <Grid item xs={12}>
        {" "}
        <h3>Day13 畫一下給看一下! </h3>
      </Grid>
      <Grid container xs={12} justifyContent={"center"}>
        <Grid item xs={6}>
          <Paper elevation={2}>
            <CanvasDraw
              style={{ margin: "auto" }}
              brushColor={selectedColor}
              // ref={(rf) => (canvasRef.current = rf)}
              ref={canvasRef}
              canvasWidth={window.innerWidth > 1024 ? 800 : 400}
            />
          </Paper>
        </Grid>
      </Grid>
      <Grid container xs={12} spacing={2} justifyContent={"center"}>
        <Grid item>
          <Button variant="contained" onClick={() => handleSaveOnClick()}>
            看一下我寫的是什麼字!
          </Button>
        </Grid>
        <Grid item>
          <Button
            variant="contained"
            color="success"
            onClick={() => handleUndoOnClick()}
          >
            上一步
          </Button>
        </Grid>
        <Grid item>
          <Button
            variant="contained"
            style={{ backgroundColor: "yellow", color: "black" }}
            onClick={(e) => handleColorOnClick(e)}
            aria-describedby={colorButtonId}
          >
            顏色
          </Button>
          <Popover
            anchorEl={colorAnchor}
            open={colorButtonId}
            onClose={() => handleColorOnClose()}
            anchorOrigin={{
              vertical: "bottom",
              horizontal: "left",
            }}
          >
            <GithubPicker
              color={selectedColor}
              onChange={(color) => handleColorOnChange(color)}
            />
          </Popover>
        </Grid>
      </Grid>
      <Grid container justifyContent={"center"}>
        <Grid item xs={12}>
          <h3>判斷是什麼字 (只有日文唷!!) </h3>
        </Grid>
        <Grid item xs={12}>
          {ocrStatus === 1 ? <LinearProgress color="success" /> : null}
          {ocrStatus === 2 ? (
            <div style={{ fontSize: "18em" }}>{ocrResult}</div>
          ) : null}
        </Grid>
      </Grid>
    </Grid>
  );
};

export default Day13;

Reference


上一篇
[DAY-12] 看 Table 說話~
下一篇
[DAY-14] 我先擱著 準備放假拉~~~~
系列文
想要學 50 音!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言