@annotorious/plugin-segment-anything 0.1.0 → 0.1.2

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/dist/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export declare const mountPlugin: (anno: ImageAnnotator, opts?: SAMPluginOpts) =
4
4
  setEnabled: (enabled: boolean) => void;
5
5
  setShowPreview: (showPreview: boolean) => void;
6
6
  };
7
+ export * from './types';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../node_modules/p-debounce/index.js","../src/utils/mask-to-polygon.ts","../src/utils/prepare-sam2-canvas.ts","../src/input-marker-canvas.ts","../src/preview-canvas.ts","../src/index.ts"],"sourcesContent":["const pDebounce = (fn, wait, options = {}) => {\n\tif (!Number.isFinite(wait)) {\n\t\tthrow new TypeError('Expected `wait` to be a finite number');\n\t}\n\n\tlet leadingValue;\n\tlet timeout;\n\tlet resolveList = [];\n\n\treturn function (...arguments_) {\n\t\treturn new Promise(resolve => {\n\t\t\tconst shouldCallNow = options.before && !timeout;\n\n\t\t\tclearTimeout(timeout);\n\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\ttimeout = null;\n\n\t\t\t\tconst result = options.before ? leadingValue : fn.apply(this, arguments_);\n\n\t\t\t\tfor (resolve of resolveList) {\n\t\t\t\t\tresolve(result);\n\t\t\t\t}\n\n\t\t\t\tresolveList = [];\n\t\t\t}, wait);\n\n\t\t\tif (shouldCallNow) {\n\t\t\t\tleadingValue = fn.apply(this, arguments_);\n\t\t\t\tresolve(leadingValue);\n\t\t\t} else {\n\t\t\t\tresolveList.push(resolve);\n\t\t\t}\n\t\t});\n\t};\n};\n\npDebounce.promise = function_ => {\n\tlet currentPromise;\n\n\treturn async function (...arguments_) {\n\t\tif (currentPromise) {\n\t\t\treturn currentPromise;\n\t\t}\n\n\t\ttry {\n\t\t\tcurrentPromise = function_.apply(this, arguments_);\n\t\t\treturn await currentPromise;\n\t\t} finally {\n\t\t\tcurrentPromise = undefined;\n\t\t}\n\t};\n};\n\nexport default pDebounce;\n","import cv from '@techstark/opencv-js';\nimport type { InferenceSession } from 'onnxruntime-web/all';\nimport type { Bounds } from '@/types';\nimport { maskToCanvas } from './mask-to-canvas';\nimport { boundsFromPoints, ShapeType, type Polygon } from '@annotorious/annotorious';\nimport { chaikinSmooth } from './chaikin-smooth';\n\nexport const maskToPolygon = (\n result: InferenceSession.ReturnType, \n bounds: Bounds,\n scale: number\n) => {\n const canvas = maskToCanvas(\n result, \n bounds,\n [255, 255, 255, 255],\n [0, 0, 0, 255]\n );\n\n const src = cv.imread(canvas);\n\n const dst = new cv.Mat();\n const contours = new cv.MatVector();\n const hierarchy = new cv.Mat();\n\n // To grayscale\n cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);\n\n // Smoothing\n const size = new cv.Size(9, 9);\n cv.GaussianBlur(dst, dst, size, 0);\n cv.threshold(dst, dst, 80, 255, cv.THRESH_BINARY);\n\n // Fill small gaps\n const kernel = cv.Mat.ones(3, 3, cv.CV_8U);\n cv.morphologyEx(dst, dst, cv.MORPH_CLOSE, kernel);\n\n // Find countours\n cv.findContours(dst, contours, hierarchy, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);\n\n // Collect polygons\n const polygons: Polygon[] = [];\n\n if (contours.size() > 0) {\n let largestContourIdx = 0;\n let largestContourSize = 0;\n \n for (let i = 0; i < contours.size(); i++) {\n let contourSize = contours.get(i).rows;\n if (contourSize > largestContourSize) {\n largestContourSize = contourSize;\n largestContourIdx = i;\n }\n }\n \n let contour = contours.get(largestContourIdx);\n \n let epsilon = 0.005 * cv.arcLength(contour, true);\n let simplifiedContour = new cv.Mat();\n\n cv.approxPolyDP(contour, simplifiedContour, epsilon, true);\n \n let points: [number, number][] = [];\n\n for (let i = 0; i < simplifiedContour.rows; i++) {\n points.push([\n simplifiedContour.data32S[i * 2] * scale,\n simplifiedContour.data32S[i * 2 + 1] * scale\n ]);\n }\n \n const smoothed = chaikinSmooth(points, 1);\n\n const polygon: Polygon = {\n type: ShapeType.POLYGON,\n geometry: {\n bounds: boundsFromPoints(smoothed),\n points: smoothed\n }\n }\n polygons.push(polygon);\n\n simplifiedContour.delete();\n }\n\n src.delete(); \n dst.delete(); \n contours.delete(); \n hierarchy.delete();\n\n return polygons[0];\n\n}","import type { Bounds } from '@/types';\nimport { getImageBounds } from './get-image-bounds';\n\n// Ported to TS from geronimi73 (MIT license)\n// https://github.com/geronimi73/next-sam/blob/main/lib/imageutils.js\nexport const prepareSAM2Canvas = (\n image: HTMLImageElement\n): Promise<{ canvas: HTMLCanvasElement, bounds: Bounds, scale: number }> => new Promise((resolve, reject) => {\n const copy = new Image();\n copy.crossOrigin = 'anonymous';\n\n copy.onload = () => {\n const { bounds, scale } = getImageBounds(\n { h: copy.naturalHeight, w: copy.naturalWidth },\n { h: 1024, w: 1024 }\n );\n\n const canvas = document.createElement('canvas');\n canvas.width = 1024;\n canvas.height = 1024;\n\n canvas\n .getContext('2d')!\n .drawImage(\n copy,\n 0,\n 0,\n copy.naturalWidth,\n copy.naturalHeight,\n bounds.x,\n bounds.y,\n bounds.w,\n bounds.h\n );\n \n resolve({ canvas, bounds, scale });\n }\n\n copy.onerror = error => {\n reject(error);\n }\n\n copy.src = image.src;\n});","import type { Bounds, Point, SAM2DecoderPrompt } from './types';\n\nconst R = window.devicePixelRatio || 1;\n\nexport const createInputMarkerCanvas = (container: HTMLDivElement, bounds: Bounds, scale: number) => {\n const canvas = document.createElement('canvas');\n canvas.setAttribute('class', 'a9s-sam-input-markers');\n canvas.width = R * container.offsetWidth;\n canvas.height = R * container.offsetHeight;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) throw 'Error initializing canvas'; // Should never happen\n\n container.appendChild(canvas);\n\n const clear = () => {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n const drawPoint = (pt: Point, color: string) => {\n const x = R * (pt.x - bounds.x) * scale;\n const y = R * (pt.y - bounds.y) * scale;\n\n ctx.beginPath();\n ctx.arc(x, y, 5 * R, 0, 2 * Math.PI, false);\n ctx.fillStyle = color;\n ctx.fill();\n ctx.lineWidth = 1 * R;\n ctx.strokeStyle = '#000';\n ctx.stroke();\n }\n\n const setInput = (input: SAM2DecoderPrompt) => {\n clear();\n input.include.forEach(pt => drawPoint(pt, '#33ff33'));\n input.exclude.forEach(pt => drawPoint(pt, '#ff3333'));\n }\n\n return {\n clear,\n setInput\n }\n}","import type { InferenceSession } from 'onnxruntime-web/all';\nimport { maskToCanvas } from './utils';\nimport type { Bounds } from './types';\n\nexport const createPreviewCanvas = (container: HTMLDivElement, bounds: Bounds) => {\n const image = container.querySelector('img');\n if (!image) return;\n\n let _visible = true;\n\n const renderMask = (result: InferenceSession.ReturnType) => {\n if (!_visible) return;\n\n const canvas = maskToCanvas(\n result, \n bounds,\n [0, 114, 189, 255],\n [0, 0, 0, 0]\n );\n\n container.querySelector('.a9s-sam-preview')?.remove();\n container.appendChild(canvas);\n }\n\n const setVisible = (visible: boolean) => {\n _visible = visible;\n\n if (!visible)\n container.querySelector('.a9s-sam-preview')?.remove();\n }\n\n return {\n renderMask,\n setVisible\n }\n}","import pDebounce from 'p-debounce';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { ImageAnnotation, ImageAnnotator } from '@annotorious/annotorious';\nimport SAM2Worker from './sam2/sam2-worker.ts?worker';\nimport type { SAM2WorkerResult } from './sam2';\nimport { canvasToFloat32Array, maskToPolygon, prepareSAM2Canvas } from './utils';\nimport { createInputMarkerCanvas } from './input-marker-canvas';\nimport { createPreviewCanvas } from './preview-canvas';\nimport type { Point, SAM2DecoderPrompt, SAMPluginOpts } from './types';\n\nimport './index.css';\n\nexport const mountPlugin = (anno: ImageAnnotator, opts: SAMPluginOpts = {}) => {\n let _enabled = Boolean(opts.enabled);\n let _showPreview = Boolean(opts.showPreview);\n\n let currentAnnotationId: string;\n\n const container = anno.element;\n\n let input: SAM2DecoderPrompt = {\n\n include: [],\n \n exclude: []\n \n }; \n\n const image = container?.querySelector('img') as HTMLImageElement;\n if (!image) return;\n\n const SAM2 = new SAM2Worker();\n\n let onPointerMove: ((evt: PointerEvent) => void) | null = null;\n let onPointerDown: ((evt: PointerEvent) => void) | null = null;\n\n let inputMarkerCanvas: ReturnType<typeof createInputMarkerCanvas>;\n\n let previewCanvas: ReturnType<typeof createPreviewCanvas>;\n\n const updateEventListeners = () => {\n if (!onPointerMove || !onPointerDown) return;\n \n if (_enabled) {\n container.addEventListener('pointermove', onPointerMove);\n container.addEventListener('pointerdown', onPointerDown);\n } else {\n container.removeEventListener('pointermove', onPointerMove);\n container.removeEventListener('pointerdown', onPointerDown);\n }\n }\n\n const debouncedPreview = pDebounce((pt: Point) => {\n SAM2.postMessage({ type: 'decode_preview', point: pt });\n }, 1);\n\n // Off-screen copy, resized and padded to 1024x1024px.\n prepareSAM2Canvas(image).then(({ canvas: bufferedImage, bounds, scale }) => {\n const viewportToSAM2Coordinates = (evt: PointerEvent) => {\n const scaleX = image.naturalWidth / (scale * image.offsetWidth);\n const scaleY = image.naturalHeight / (scale * image.offsetHeight);\n \n const { offsetX, offsetY } = evt;\n \n const x = (offsetX * scaleX) + bounds.x;\n const y = (offsetY * scaleY) + bounds.y;\n\n return { x, y };\n }\n\n onPointerMove = (evt: PointerEvent) => {\n if (input.include.length + input.exclude.length > 0) return;\n \n const { x, y } = viewportToSAM2Coordinates(evt); \n debouncedPreview({ x, y });\n }\n\n onPointerDown = (evt: PointerEvent) => {\n const { x, y } = viewportToSAM2Coordinates(evt);\n\n if (evt.shiftKey) {\n input.exclude.push({ x, y });\n } else {\n input.include.push({ x, y });\n }\n\n previewCanvas?.setVisible(false);\n\n inputMarkerCanvas?.setInput(input);\n\n SAM2.postMessage({ type: 'decode', input });\n }\n\n previewCanvas = createPreviewCanvas(anno.element, bounds);\n\n inputMarkerCanvas = createInputMarkerCanvas(anno.element, bounds, scale);\n\n SAM2.onmessage = ((message: MessageEvent<SAM2WorkerResult>) => {\n const { type } = message.data;\n \n if (type === 'init_success') {\n // Models loaded - encode the image\n console.log('[annotorious-sam] Encoding image...');\n\n const data = canvasToFloat32Array(bufferedImage);\n SAM2.postMessage({ type: 'encode', data });\n } else if (type === 'encode_success') {\n console.log('[annotorious-sam] Encoding complete');\n\n // Image encoded – add pointer listeners\n updateEventListeners();\n } else if (type === 'decode_preview_success') {\n // Render mask every time the worker has decoded one\n previewCanvas?.renderMask(message.data.result);\n } else if (type === 'decode_success') {\n // Render mask every time the worker has decoded one\n const polygon = maskToPolygon(message.data.result, bounds, scale);\n\n const annotation: ImageAnnotation = {\n id: currentAnnotationId,\n bodies: [],\n target: {\n annotation: currentAnnotationId,\n selector: polygon,\n creator: { id: 'rainer' },\n created: new Date()\n }\n };\n\n const { store, selection } = anno.state;\n\n const exists = store.getAnnotation(currentAnnotationId);\n if (exists) {\n store.updateAnnotation(currentAnnotationId, annotation);\n } else {\n store.addAnnotation(annotation);\n }\n\n // selection.setSelected(currentAnnotationId);\n }\n });\n \n SAM2.postMessage({ type: 'init' });\n });\n\n const setEnabled = (enabled: boolean) => {\n _enabled = enabled;\n\n currentAnnotationId = uuidv4();\n\n updateEventListeners();\n\n previewCanvas?.setVisible(enabled);\n }\n\n const setShowPreview = (showPreview: boolean) => {\n _showPreview = showPreview;\n previewCanvas?.setVisible(showPreview);\n }\n\n return {\n setEnabled,\n setShowPreview\n }\n\n}"],"names":["pDebounce","fn","wait","options","leadingValue","timeout","resolveList","arguments_","resolve","shouldCallNow","result","function_","currentPromise","maskToPolygon","bounds","scale","canvas","maskToCanvas","src","cv","dst","contours","hierarchy","size","kernel","polygons","largestContourIdx","largestContourSize","i","contourSize","contour","epsilon","simplifiedContour","points","smoothed","chaikinSmooth","polygon","ShapeType","boundsFromPoints","prepareSAM2Canvas","image","reject","copy","getImageBounds","error","R","createInputMarkerCanvas","container","ctx","clear","drawPoint","pt","color","x","y","input","createPreviewCanvas","_visible","_a","visible","mountPlugin","anno","opts","_enabled","currentAnnotationId","SAM2","SAM2Worker","onPointerMove","onPointerDown","inputMarkerCanvas","previewCanvas","updateEventListeners","debouncedPreview","bufferedImage","viewportToSAM2Coordinates","evt","scaleX","scaleY","offsetX","offsetY","message","type","data","canvasToFloat32Array","annotation","store","selection","enabled","uuidv4","showPreview"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"index.js","sources":["../node_modules/p-debounce/index.js","../src/utils/mask-to-polygon.ts","../src/utils/prepare-sam2-canvas.ts","../src/input-marker-canvas.ts","../src/preview-canvas.ts","../src/index.ts"],"sourcesContent":["const pDebounce = (fn, wait, options = {}) => {\n\tif (!Number.isFinite(wait)) {\n\t\tthrow new TypeError('Expected `wait` to be a finite number');\n\t}\n\n\tlet leadingValue;\n\tlet timeout;\n\tlet resolveList = [];\n\n\treturn function (...arguments_) {\n\t\treturn new Promise(resolve => {\n\t\t\tconst shouldCallNow = options.before && !timeout;\n\n\t\t\tclearTimeout(timeout);\n\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\ttimeout = null;\n\n\t\t\t\tconst result = options.before ? leadingValue : fn.apply(this, arguments_);\n\n\t\t\t\tfor (resolve of resolveList) {\n\t\t\t\t\tresolve(result);\n\t\t\t\t}\n\n\t\t\t\tresolveList = [];\n\t\t\t}, wait);\n\n\t\t\tif (shouldCallNow) {\n\t\t\t\tleadingValue = fn.apply(this, arguments_);\n\t\t\t\tresolve(leadingValue);\n\t\t\t} else {\n\t\t\t\tresolveList.push(resolve);\n\t\t\t}\n\t\t});\n\t};\n};\n\npDebounce.promise = function_ => {\n\tlet currentPromise;\n\n\treturn async function (...arguments_) {\n\t\tif (currentPromise) {\n\t\t\treturn currentPromise;\n\t\t}\n\n\t\ttry {\n\t\t\tcurrentPromise = function_.apply(this, arguments_);\n\t\t\treturn await currentPromise;\n\t\t} finally {\n\t\t\tcurrentPromise = undefined;\n\t\t}\n\t};\n};\n\nexport default pDebounce;\n","import cv from '@techstark/opencv-js';\nimport type { InferenceSession } from 'onnxruntime-web/all';\nimport type { Bounds } from '@/types';\nimport { maskToCanvas } from './mask-to-canvas';\nimport { boundsFromPoints, ShapeType, type Polygon } from '@annotorious/annotorious';\nimport { chaikinSmooth } from './chaikin-smooth';\n\nexport const maskToPolygon = (\n result: InferenceSession.ReturnType, \n bounds: Bounds,\n scale: number\n) => {\n const canvas = maskToCanvas(\n result, \n bounds,\n [255, 255, 255, 255],\n [0, 0, 0, 255]\n );\n\n const src = cv.imread(canvas);\n\n const dst = new cv.Mat();\n const contours = new cv.MatVector();\n const hierarchy = new cv.Mat();\n\n // To grayscale\n cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);\n\n // Smoothing\n const size = new cv.Size(9, 9);\n cv.GaussianBlur(dst, dst, size, 0);\n cv.threshold(dst, dst, 80, 255, cv.THRESH_BINARY);\n\n // Fill small gaps\n const kernel = cv.Mat.ones(3, 3, cv.CV_8U);\n cv.morphologyEx(dst, dst, cv.MORPH_CLOSE, kernel);\n\n // Find countours\n cv.findContours(dst, contours, hierarchy, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);\n\n // Collect polygons\n const polygons: Polygon[] = [];\n\n if (contours.size() > 0) {\n let largestContourIdx = 0;\n let largestContourSize = 0;\n \n for (let i = 0; i < contours.size(); i++) {\n let contourSize = contours.get(i).rows;\n if (contourSize > largestContourSize) {\n largestContourSize = contourSize;\n largestContourIdx = i;\n }\n }\n \n let contour = contours.get(largestContourIdx);\n \n let epsilon = 0.005 * cv.arcLength(contour, true);\n let simplifiedContour = new cv.Mat();\n\n cv.approxPolyDP(contour, simplifiedContour, epsilon, true);\n \n let points: [number, number][] = [];\n\n for (let i = 0; i < simplifiedContour.rows; i++) {\n points.push([\n simplifiedContour.data32S[i * 2] * scale,\n simplifiedContour.data32S[i * 2 + 1] * scale\n ]);\n }\n \n const smoothed = chaikinSmooth(points, 1);\n\n const polygon: Polygon = {\n type: ShapeType.POLYGON,\n geometry: {\n bounds: boundsFromPoints(smoothed),\n points: smoothed\n }\n }\n polygons.push(polygon);\n\n simplifiedContour.delete();\n }\n\n src.delete(); \n dst.delete(); \n contours.delete(); \n hierarchy.delete();\n\n return polygons[0];\n\n}","import type { Bounds } from '@/types';\nimport { getImageBounds } from './get-image-bounds';\n\n// Ported to TS from geronimi73 (MIT license)\n// https://github.com/geronimi73/next-sam/blob/main/lib/imageutils.js\nexport const prepareSAM2Canvas = (\n image: HTMLImageElement\n): Promise<{ canvas: HTMLCanvasElement, bounds: Bounds, scale: number }> => new Promise((resolve, reject) => {\n const copy = new Image();\n copy.crossOrigin = 'anonymous';\n\n copy.onload = () => {\n const { bounds, scale } = getImageBounds(\n { h: copy.naturalHeight, w: copy.naturalWidth },\n { h: 1024, w: 1024 }\n );\n\n const canvas = document.createElement('canvas');\n canvas.width = 1024;\n canvas.height = 1024;\n\n canvas\n .getContext('2d')!\n .drawImage(\n copy,\n 0,\n 0,\n copy.naturalWidth,\n copy.naturalHeight,\n bounds.x,\n bounds.y,\n bounds.w,\n bounds.h\n );\n \n resolve({ canvas, bounds, scale });\n }\n\n copy.onerror = error => {\n reject(error);\n }\n\n copy.src = image.src;\n});","import type { Bounds, Point, SAM2DecoderPrompt } from './types';\n\nconst R = window.devicePixelRatio || 1;\n\nexport const createInputMarkerCanvas = (container: HTMLDivElement, bounds: Bounds, scale: number) => {\n const canvas = document.createElement('canvas');\n canvas.setAttribute('class', 'a9s-sam-input-markers');\n canvas.width = R * container.offsetWidth;\n canvas.height = R * container.offsetHeight;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) throw 'Error initializing canvas'; // Should never happen\n\n container.appendChild(canvas);\n\n const clear = () => {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n const drawPoint = (pt: Point, color: string) => {\n const x = R * (pt.x - bounds.x) * scale;\n const y = R * (pt.y - bounds.y) * scale;\n\n ctx.beginPath();\n ctx.arc(x, y, 5 * R, 0, 2 * Math.PI, false);\n ctx.fillStyle = color;\n ctx.fill();\n ctx.lineWidth = 1 * R;\n ctx.strokeStyle = '#000';\n ctx.stroke();\n }\n\n const setInput = (input: SAM2DecoderPrompt) => {\n clear();\n input.include.forEach(pt => drawPoint(pt, '#33ff33'));\n input.exclude.forEach(pt => drawPoint(pt, '#ff3333'));\n }\n\n return {\n clear,\n setInput\n }\n}","import type { InferenceSession } from 'onnxruntime-web/all';\nimport { maskToCanvas } from './utils';\nimport type { Bounds } from './types';\n\nexport const createPreviewCanvas = (container: HTMLDivElement, bounds: Bounds) => {\n const image = container.querySelector('img');\n if (!image) return;\n\n let _visible = true;\n\n const renderMask = (result: InferenceSession.ReturnType) => {\n if (!_visible) return;\n\n const canvas = maskToCanvas(\n result, \n bounds,\n [0, 114, 189, 255],\n [0, 0, 0, 0]\n );\n\n container.querySelector('.a9s-sam-preview')?.remove();\n container.appendChild(canvas);\n }\n\n const setVisible = (visible: boolean) => {\n _visible = visible;\n\n if (!visible)\n container.querySelector('.a9s-sam-preview')?.remove();\n }\n\n return {\n renderMask,\n setVisible\n }\n}","import pDebounce from 'p-debounce';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { ImageAnnotation, ImageAnnotator } from '@annotorious/annotorious';\nimport SAM2Worker from './sam2/sam2-worker.ts?worker';\nimport type { SAM2WorkerResult } from './sam2';\nimport { canvasToFloat32Array, maskToPolygon, prepareSAM2Canvas } from './utils';\nimport { createInputMarkerCanvas } from './input-marker-canvas';\nimport { createPreviewCanvas } from './preview-canvas';\nimport type { Point, SAM2DecoderPrompt, SAMPluginOpts } from './types';\n\nimport './index.css';\n\nexport const mountPlugin = (anno: ImageAnnotator, opts: SAMPluginOpts = {}) => {\n let _enabled = Boolean(opts.enabled);\n let _showPreview = Boolean(opts.showPreview);\n\n let currentAnnotationId: string;\n\n const container = anno.element;\n\n let input: SAM2DecoderPrompt = {\n\n include: [],\n \n exclude: []\n \n }; \n\n const image = container?.querySelector('img') as HTMLImageElement;\n if (!image) return;\n\n const SAM2 = new SAM2Worker();\n\n let onPointerMove: ((evt: PointerEvent) => void) | null = null;\n let onPointerDown: ((evt: PointerEvent) => void) | null = null;\n\n let inputMarkerCanvas: ReturnType<typeof createInputMarkerCanvas>;\n\n let previewCanvas: ReturnType<typeof createPreviewCanvas>;\n\n const updateEventListeners = () => {\n if (!onPointerMove || !onPointerDown) return;\n \n if (_enabled) {\n container.addEventListener('pointermove', onPointerMove);\n container.addEventListener('pointerdown', onPointerDown);\n } else {\n container.removeEventListener('pointermove', onPointerMove);\n container.removeEventListener('pointerdown', onPointerDown);\n }\n }\n\n const debouncedPreview = pDebounce((pt: Point) => {\n SAM2.postMessage({ type: 'decode_preview', point: pt });\n }, 1);\n\n // Off-screen copy, resized and padded to 1024x1024px.\n prepareSAM2Canvas(image).then(({ canvas: bufferedImage, bounds, scale }) => {\n const viewportToSAM2Coordinates = (evt: PointerEvent) => {\n const scaleX = image.naturalWidth / (scale * image.offsetWidth);\n const scaleY = image.naturalHeight / (scale * image.offsetHeight);\n \n const { offsetX, offsetY } = evt;\n \n const x = (offsetX * scaleX) + bounds.x;\n const y = (offsetY * scaleY) + bounds.y;\n\n return { x, y };\n }\n\n onPointerMove = (evt: PointerEvent) => {\n if (input.include.length + input.exclude.length > 0) return;\n \n const { x, y } = viewportToSAM2Coordinates(evt); \n debouncedPreview({ x, y });\n }\n\n onPointerDown = (evt: PointerEvent) => {\n const { x, y } = viewportToSAM2Coordinates(evt);\n\n if (evt.shiftKey) {\n input.exclude.push({ x, y });\n } else {\n input.include.push({ x, y });\n }\n\n previewCanvas?.setVisible(false);\n\n inputMarkerCanvas?.setInput(input);\n\n SAM2.postMessage({ type: 'decode', input });\n }\n\n previewCanvas = createPreviewCanvas(anno.element, bounds);\n\n inputMarkerCanvas = createInputMarkerCanvas(anno.element, bounds, scale);\n\n SAM2.onmessage = ((message: MessageEvent<SAM2WorkerResult>) => {\n const { type } = message.data;\n \n if (type === 'init_success') {\n // Models loaded - encode the image\n console.log('[annotorious-sam] Encoding image...');\n\n const data = canvasToFloat32Array(bufferedImage);\n SAM2.postMessage({ type: 'encode', data });\n } else if (type === 'encode_success') {\n console.log('[annotorious-sam] Encoding complete');\n\n // Image encoded – add pointer listeners\n updateEventListeners();\n } else if (type === 'decode_preview_success') {\n // Render mask every time the worker has decoded one\n previewCanvas?.renderMask(message.data.result);\n } else if (type === 'decode_success') {\n // Render mask every time the worker has decoded one\n const polygon = maskToPolygon(message.data.result, bounds, scale);\n\n const annotation: ImageAnnotation = {\n id: currentAnnotationId,\n bodies: [],\n target: {\n annotation: currentAnnotationId,\n selector: polygon,\n creator: { id: 'rainer' },\n created: new Date()\n }\n };\n\n const { store, selection } = anno.state;\n\n const exists = store.getAnnotation(currentAnnotationId);\n if (exists) {\n store.updateAnnotation(currentAnnotationId, annotation);\n } else {\n store.addAnnotation(annotation);\n }\n\n // selection.setSelected(currentAnnotationId);\n }\n });\n \n SAM2.postMessage({ type: 'init' });\n });\n\n const setEnabled = (enabled: boolean) => {\n _enabled = enabled;\n\n currentAnnotationId = uuidv4();\n\n updateEventListeners();\n\n previewCanvas?.setVisible(enabled);\n }\n\n const setShowPreview = (showPreview: boolean) => {\n _showPreview = showPreview;\n previewCanvas?.setVisible(showPreview);\n }\n\n return {\n setEnabled,\n setShowPreview\n }\n\n}\n\nexport * from './types';"],"names":["pDebounce","fn","wait","options","leadingValue","timeout","resolveList","arguments_","resolve","shouldCallNow","result","function_","currentPromise","maskToPolygon","bounds","scale","canvas","maskToCanvas","src","cv","dst","contours","hierarchy","size","kernel","polygons","largestContourIdx","largestContourSize","i","contourSize","contour","epsilon","simplifiedContour","points","smoothed","chaikinSmooth","polygon","ShapeType","boundsFromPoints","prepareSAM2Canvas","image","reject","copy","getImageBounds","error","R","createInputMarkerCanvas","container","ctx","clear","drawPoint","pt","color","x","y","input","createPreviewCanvas","_visible","_a","visible","mountPlugin","anno","opts","_enabled","currentAnnotationId","SAM2","SAM2Worker","onPointerMove","onPointerDown","inputMarkerCanvas","previewCanvas","updateEventListeners","debouncedPreview","bufferedImage","viewportToSAM2Coordinates","evt","scaleX","scaleY","offsetX","offsetY","message","type","data","canvasToFloat32Array","annotation","store","selection","enabled","uuidv4","showPreview"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,6 +1,9 @@
1
1
  import { OpenSeadragonAnnotator } from '@annotorious/openseadragon';
2
+ import { SAMPluginEvents } from '../types';
2
3
  export declare const mountOpenSeadragonPlugin: (anno: OpenSeadragonAnnotator) => {
3
4
  destroy: () => void;
4
5
  setEnabled: (enabled: boolean) => void;
5
- on: any;
6
+ setQueryMode: (mode: "add" | "remove") => "add" | "remove";
7
+ on: (event: keyof SAMPluginEvents, cb: SAMPluginEvents[keyof SAMPluginEvents]) => import('nanoevents').Unsubscribe;
6
8
  };
9
+ export * from '../types';