ppu-ocv 0.0.3 → 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 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 = new CanvasToolkit();
80
+ const canvasToolkit = CanvasToolkit.getInstance();
81
81
  const canvas = await ImageProcessor.prepareCanvas(image);
82
82
  await ImageProcessor.initRuntime();
83
83
 
@@ -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 = canvasToolkit.crop({
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 = canvasToolkit.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 canvasToolkit.saveImage({
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ppu-ocv",
3
- "version": "0.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "A type-safe, modular, chainable image processing library built on top of OpenCV.js with a fluent API leveraging pipeline processing.",
5
5
  "keywords": [
6
6
  "open-cv",