0.0.0 • Published 5 months ago

document_crop_web v0.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

Introduction

Package document_crop_web is a JavaScript library which you can use to create CamScanner-like cropping functionality for web applications. Make use of this declarative, unopinionated, and framework-agnostic library to effortlessly integrate advanced document scanning and cropping features into your web projects.

Key Features:

  • Declarative Approach: Easily define and manipulate document cropping behavior using a declarative syntax.

  • Unopinionated Design: Tons of flexibility and customization options.

  • Framework-Agnostic: Seamlessly integrate with your preferred web framework.

cropper result

Basic Example Usage

import Scanner from "document_crop_web";

const scanner = new Scanner({
  parent: document.getElementById("parent-div"), //must be a HTMLDivElement
  width: 400,
});

scanner.loadImg("path/to/image.jpg");

const croppedImage = await scanner.crop({ format: "base64" });

Vanilla JS Usage

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document Crop Usage</title>
    <script src="./index.js" defer></script>
  </head>
  <body>
    <input
      id="image_input"
      type="file"
      accept="
    image/png,image/jpg,image/jpeg,image/gif
    " />
    <button id="upload_button">Upload</button>
    <button id="crop_button">Crop</button>
    <div id="container"></div>
  </body>
</html>

index.js

import Scanner from "document_crop_web";

const parentDiv = document.getElementById("container");
const imgInput = document.getElementById("image_input");
const uploadBtn = document.getElementById("upload_button");
const cropBtn = document.getElementById("crop_button");

let scanner = new Scanner({
  parent: parentDiv,
  width: 300,
});

uploadBtn.addEventListener("click", () => {
  if (imgInput.files && imgInput.files[0]) {
    const file = imgInput.files[0];
    const reader = new FileReader();
    reader.onload = function (e) {
      console.log(e.target.result);
      scanner.loadImg(e.target.result);
    };
    reader.readAsDataURL(file);
  }
});

cropBtn.addEventListener("click", () => {
  scanner.crop({ format: "file" }).then((file) => {
    const img = document.createElement("img");
    img.src = URL.createObjectURL(file);
    img.width = 200;
    document.body.appendChild(img);
  });
});

ReactJs Usage

import React, { useState, useRef } from 'react';
import Scanner from 'document_crop_web';

const Editor = (props) => {
  const [imgSrc, setImgSrc] = useState("https://picsum.photos/300/600");
  const [scanner, setScanner] = useState(null);
  const divRef = useRef(null);

  useEffect(() => {
    const scan = new Scanner({
      parent: divRef.current,
      width: 300,
      maxHeight: 550,
      cornerRadius: 14,
      cornerColor: "black",
      cropBoxBorderColor: "white" ,
      backdropColor: "rgba(40,40,40,0.5)",
      initialCorners: [
        { x: 15, y: 15 },
        { x: 85, y: 15 },
        { x: 85, y: 85 },
        { x: 15, y: 85 },
      ],
    });
    scan.loadImg(imgSrc);
    setScanner(scan);
    return () => {
      scan.destroy();
      setScanner(null);
    };
  }, [imgSrc]);

  const returnCroppedImage = () => {
    if (scanner) {
      const src = scanner.crop({ format: "base64" });
      return src;
    }
  };

  return (
    <>
      <img src={imgSrc} />
      <div ref={divRef}></div>
      <button onClick={() => setImgSrc("https://picsum.photos/400/600")}>
        Change Image
      </button>
      <button onClick={() => console.log(returnCroppedImage())}>
        Crop
      </button>
    </>
  );
}

What This Library Is

The document_crop_web library is meant for bulding web applications that need to scan documents. Traditional image cropping libraries for the web limit you to rectangular shapes, which might not be sufficent for this usage.

With document_crop_web, you can:

  • Crop any quadrilateral shape area on the image, which is what document scanning needs.
  • Perform perspective wrapping to produce rectangular image output.

What This Library Isn't

  • This library does not apply filters to images to simulate a "document" look automatically.
  • This is not an edge detection library.

However,

  • The library offers interfaces for implementing these such as applying filters or detecting edges in the document.
  • It remains non-opinionated about the usage of external services, allowing you to choose and integrate services of your preference for these functionalities.

See Advanced Usage section for more.

Constructor and Its Parameters

Note: All measurements are in pixels.

Scanner(options)

OptionTypeRequiredDescriptionDefault
parentHTMLDivElementYesThe HTMLDivElement where the scanner will be appended.-
widthnumberNoThe width of the scanner canvas.-
heightnumberNoThe height of the scanner canvas.-
maxWidthnumberNoThe maximum width of the scanner canvas.-
maxHeightnumberNoThe maximum height of the scanner canvas.-
cornerRadiusnumberNoThe corner radius for the crop box.12
cornerColorstringNoThe color of the corner points."lightgreen"
cropBoxColorstringNoThe color of the crop box.-
backdropColorstringNoThe color of the backdrop outside the crop box."rgba(0, 0, 0, 0.5)"
minCropBoxWidthnumberNoThe minimum width of the crop box.100
minCropBoxHeightnumberNoThe minimum height of the crop box.100
cropBoxBorderWidthnumberNoThe border width of the crop box.1
cropBoxBorderColorstringNoThe border color of the crop box."rgba(255, 255, 255)"
initialCorners{x: number, y: number}NoInitial corners for the crop box. See details below.Covers the whole canvas.

Caveats:

  • Setting dimensions: If only one of 'width' or 'height' is set, the other dimension i.e, 'height' and 'width' respectively, will be set preserving the original image's aspect ratio. If none is set, the canvas will take the image's natural width and height.
  • initialCorners: Expects an array of four objects, each having x and y properties as percentage of the canvas size. These objects represent position of the cropbox corners in clockwise order, starting from the top-left corner.

For example, the following 'initalCorners' will create a centered rectangular cropbox.

...
initialCorners: [
{ x: 25, y: 25 }, // top-left
{ x: 75, y: 25 }, // top-right
{ x: 75, y: 75 }, // bottom-right
{ x: 25, y: 75 }  // bottom-left
]
...

Methods

loadImg(imgSrc)

Loads an image into the scanner.

  • imgSrc (string): The source URL of the image. Equivalent to 'src' attribute in HTMLImageElement.

crop(options)

Crops the image within the defined crop box and returns the result.

  • options (object): Optional. An options object.
    • format (string): Optional. The format of the result. Possible values:
      • 'base64': returns String representing base64 encoded image (default)
      • 'blob': returns Promise resolving into the Blob object.
      • 'file': returns Promise resolving into the File object.

destroy()

Destroys the scanner instance and removes its elements from the DOM. Call this method before creating another instance to prevent memory leaks.

Advanced Usage

The library has been written considering the advanced use cases where app might need features such as document edge detection, or filters.

Edge detection: The library is unopinionated about what external library you use for edge detection. The API provides initialCorners option to which you can input the output of the edge detection library. Make sure to map the output to the format of the initalCorners option.

Filters: The library is unopinionated about what external library you use for filters. Just input the output of the filter library to the loadImg method.