ppu-ocv 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/canvas-toolkit.d.ts +18 -3
- package/canvas-toolkit.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,7 +77,7 @@ import { CanvasToolkit, ImageProcessor, cv } from "ppu-ocv";
|
|
|
77
77
|
const file = Bun.file("./assets/receipt.jpg");
|
|
78
78
|
const image = await file.arrayBuffer();
|
|
79
79
|
|
|
80
|
-
const canvasToolkit =
|
|
80
|
+
const canvasToolkit = CanvasToolkit.getInstance();
|
|
81
81
|
const canvas = await ImageProcessor.prepareCanvas(image);
|
|
82
82
|
await ImageProcessor.initRuntime();
|
|
83
83
|
|
package/canvas-toolkit.d.ts
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import type { BoundingBox, SKRSContext2D } from "./index";
|
|
2
2
|
import { Canvas, cv } from "./index";
|
|
3
|
+
/**
|
|
4
|
+
* Singleton class for canvas manipulation utilities
|
|
5
|
+
*/
|
|
3
6
|
export declare class CanvasToolkit {
|
|
7
|
+
private static instance;
|
|
4
8
|
private step;
|
|
9
|
+
/**
|
|
10
|
+
* Private constructor to prevent direct instantiation
|
|
11
|
+
*/
|
|
12
|
+
private constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Get the singleton instance of CanvasToolkit
|
|
15
|
+
* @returns The singleton instance
|
|
16
|
+
* @example
|
|
17
|
+
* const canvasToolkit = CanvasToolkit.getInstance();
|
|
18
|
+
*/
|
|
19
|
+
static getInstance(): CanvasToolkit;
|
|
5
20
|
/**
|
|
6
21
|
* Crop a part of source canvas and return a new canvas of the cropped part
|
|
7
22
|
* @param options
|
|
@@ -9,7 +24,7 @@ export declare class CanvasToolkit {
|
|
|
9
24
|
* @param options.canvas Source canvas
|
|
10
25
|
* @returns A new canvas of the cropped part
|
|
11
26
|
* @example
|
|
12
|
-
* const croppedCanvas =
|
|
27
|
+
* const croppedCanvas = CanvasToolkit.getInstance().crop({
|
|
13
28
|
* bbox: { x0: 10, y0: 10, x1: 100, y1: 100 },
|
|
14
29
|
* canvas: sourceCanvas,
|
|
15
30
|
* });
|
|
@@ -26,7 +41,7 @@ export declare class CanvasToolkit {
|
|
|
26
41
|
* @param options.majorColorThreshold Major color threshold (default: 0.97)
|
|
27
42
|
* @returns true if the canvas is dirty, false otherwise
|
|
28
43
|
* @example
|
|
29
|
-
* const isDirty =
|
|
44
|
+
* const isDirty = CanvasToolkit.getInstance().isDirty({
|
|
30
45
|
* canvas: sourceCanvas,
|
|
31
46
|
* threshold: 127.5,
|
|
32
47
|
* majorColorThreshold: 0.97,
|
|
@@ -46,7 +61,7 @@ export declare class CanvasToolkit {
|
|
|
46
61
|
* @param options.path Path to save the image file (default: "out")
|
|
47
62
|
* @returns A promise that resolves when the image is saved
|
|
48
63
|
* @example
|
|
49
|
-
* await
|
|
64
|
+
* await CanvasToolkit.getInstance().saveImage({
|
|
50
65
|
* canvas: sourceCanvas,
|
|
51
66
|
* filename: "output.png",
|
|
52
67
|
* });
|
package/canvas-toolkit.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export class CanvasToolkit{step=0;crop(options){const{bbox,canvas}=options;let croppedCanvas=createCanvas(bbox.x1-bbox.x0,bbox.y1-bbox.y0);let croppedCtx=croppedCanvas.getContext("2d");croppedCtx.drawImage(canvas,bbox.x0,bbox.y0,bbox.x1-bbox.x0,bbox.y1-bbox.y0,0,0,croppedCanvas.width,croppedCanvas.height);return croppedCanvas}isDirty(options){const{canvas,threshold=127.5,majorColorThreshold=0.97}=options;let whiteCount=0;let blackCount=0;let borderlessCanvas=this.crop({bbox:{x0:canvas.width*0.1,y0:canvas.height*0.1,x1:canvas.width*0.9,y1:canvas.height*0.9},canvas});let ctx=borderlessCanvas.getContext("2d");let colorData=ctx.getImageData(0,0,borderlessCanvas.width,borderlessCanvas.height).data;for(let i=0;i<colorData.length;i+=4){let red=colorData[i];let green=colorData[i+1];let blue=colorData[i+2];if(red>=threshold&&green>=threshold&&blue>=threshold){whiteCount++}else{blackCount++}}let majorColorRatio=Math.max(whiteCount,blackCount)/(blackCount+whiteCount);return majorColorRatio<majorColorThreshold}saveImage(options){const{canvas,filename,path="out"}=options;let folderPath=join(process.cwd(),path);if(!existsSync(folderPath)){mkdirSync(folderPath,{recursive:true})}let filePath=join(folderPath,`${this.step++}. ${filename}.png`);let out=createWriteStream(filePath);let buffer=canvas.toBuffer("image/png");return new Promise((res,rej)=>{out.write(buffer,(err)=>{if(err){rej(err)}else{res()}})})}clearOutput(path="out"){let folderPath=join(process.cwd(),path);if(existsSync(folderPath)){let files=readdirSync(folderPath);for(let file of files){if(file===".gitignore")continue;let filePath=join(folderPath,file);unlinkSync(filePath)}}}drawLine(options){const{ctx,x,y,width,height,lineWidth=2,color="blue"}=options;ctx.beginPath();ctx.strokeStyle=color;ctx.lineWidth=lineWidth;ctx.strokeRect(x,y,width,height);ctx.closePath()}drawContour(options){const{ctx,contour,strokeStyle="red",lineWidth=2}=options;let pts=contour.data32S;if(pts.length<4)return;ctx.strokeStyle=strokeStyle;ctx.lineWidth=lineWidth;ctx.beginPath();ctx.moveTo(pts[0],pts[1]);for(let i=2;i<pts.length;i+=2){ctx.lineTo(pts[i],pts[i+1])}ctx.closePath();ctx.stroke()}}import{createCanvas}from"./index";import{createWriteStream,existsSync,mkdirSync,readdirSync,unlinkSync}from"fs";import{join}from"path";
|
|
1
|
+
export class CanvasToolkit{static instance=null;step=0;constructor(){}static getInstance(){if(!CanvasToolkit.instance){CanvasToolkit.instance=new CanvasToolkit}return CanvasToolkit.instance}crop(options){const{bbox,canvas}=options;let croppedCanvas=createCanvas(bbox.x1-bbox.x0,bbox.y1-bbox.y0);let croppedCtx=croppedCanvas.getContext("2d");croppedCtx.drawImage(canvas,bbox.x0,bbox.y0,bbox.x1-bbox.x0,bbox.y1-bbox.y0,0,0,croppedCanvas.width,croppedCanvas.height);return croppedCanvas}isDirty(options){const{canvas,threshold=127.5,majorColorThreshold=0.97}=options;let whiteCount=0;let blackCount=0;let borderlessCanvas=this.crop({bbox:{x0:canvas.width*0.1,y0:canvas.height*0.1,x1:canvas.width*0.9,y1:canvas.height*0.9},canvas});let ctx=borderlessCanvas.getContext("2d");let colorData=ctx.getImageData(0,0,borderlessCanvas.width,borderlessCanvas.height).data;for(let i=0;i<colorData.length;i+=4){let red=colorData[i];let green=colorData[i+1];let blue=colorData[i+2];if(red>=threshold&&green>=threshold&&blue>=threshold){whiteCount++}else{blackCount++}}let majorColorRatio=Math.max(whiteCount,blackCount)/(blackCount+whiteCount);return majorColorRatio<majorColorThreshold}saveImage(options){const{canvas,filename,path="out"}=options;let folderPath=join(process.cwd(),path);if(!existsSync(folderPath)){mkdirSync(folderPath,{recursive:true})}let filePath=join(folderPath,`${this.step++}. ${filename}.png`);let out=createWriteStream(filePath);let buffer=canvas.toBuffer("image/png");return new Promise((res,rej)=>{out.write(buffer,(err)=>{if(err){rej(err)}else{res()}})})}clearOutput(path="out"){let folderPath=join(process.cwd(),path);if(existsSync(folderPath)){let files=readdirSync(folderPath);for(let file of files){if(file===".gitignore")continue;let filePath=join(folderPath,file);unlinkSync(filePath)}}}drawLine(options){const{ctx,x,y,width,height,lineWidth=2,color="blue"}=options;ctx.beginPath();ctx.strokeStyle=color;ctx.lineWidth=lineWidth;ctx.strokeRect(x,y,width,height);ctx.closePath()}drawContour(options){const{ctx,contour,strokeStyle="red",lineWidth=2}=options;let pts=contour.data32S;if(pts.length<4)return;ctx.strokeStyle=strokeStyle;ctx.lineWidth=lineWidth;ctx.beginPath();ctx.moveTo(pts[0],pts[1]);for(let i=2;i<pts.length;i+=2){ctx.lineTo(pts[i],pts[i+1])}ctx.closePath();ctx.stroke()}}import{createCanvas}from"./index";import{createWriteStream,existsSync,mkdirSync,readdirSync,unlinkSync}from"fs";import{join}from"path";
|
package/package.json
CHANGED