diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index d16510015..000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,7 +0,0 @@ -root: true -extends: - - cheminfo-typescript - - cheminfo-typescript/jsdoc - - cheminfo-typescript/unicorn -rules: - '@typescript-eslint/restrict-template-expressions': off diff --git a/.github/workflows/release-head.yml b/.github/workflows/release-head.yml index 6460183bb..2cc3193ae 100644 --- a/.github/workflows/release-head.yml +++ b/.github/workflows/release-head.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' registry-url: 'https://registry.npmjs.org' - name: Install dependencies run: npm install diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml index c14a65099..157c410be 100644 --- a/.github/workflows/typedoc.yml +++ b/.github/workflows/typedoc.yml @@ -8,7 +8,7 @@ on: pull_request: env: - NODE_VERSION: 20.x + NODE_VERSION: 22.x ENTRY_FILE: 'src/index.ts' jobs: diff --git a/.gitignore b/.gitignore index c43b51452..0a2780734 100644 --- a/.gitignore +++ b/.gitignore @@ -124,7 +124,7 @@ yarn.lock .DS_Store lib -lib-esm +lib-cjs # debug images src/**/*.tif @@ -136,3 +136,5 @@ scripts/**/**.png scripts/**/**.json private + +.jest-image-snapshot-touched-files diff --git a/README.md b/README.md index da9dfa2d9..147db2132 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ Image processing and manipulation in JavaScript. ## [API](https://image-js.github.io/image-js-typescript/) -Look at the [examples](./examples) directory for how the API is being designed. - ## Development See [Development documentation](./Development.md). diff --git a/api-extractor.json b/api-extractor.json index 71e870745..97c50b60d 100644 --- a/api-extractor.json +++ b/api-extractor.json @@ -45,7 +45,7 @@ * * SUPPORTED TOKENS: , , */ - "mainEntryPointFilePath": "/lib-esm/index.d.ts", + "mainEntryPointFilePath": "/lib/index.d.ts", /** * A list of NPM package names whose exports should be treated as part of this package. diff --git a/demo/.eslintrc.yml b/demo/.eslintrc.yml index a461af39c..e69de29bb 100644 --- a/demo/.eslintrc.yml +++ b/demo/.eslintrc.yml @@ -1,4 +0,0 @@ -root: true -extends: [cheminfo-react, cheminfo-typescript] -rules: - no-console: off diff --git a/demo/components/App.tsx b/demo/components/App.tsx index 7d3db7a9d..637d461df 100644 --- a/demo/components/App.tsx +++ b/demo/components/App.tsx @@ -1,9 +1,9 @@ import { HashRouter, Route, Routes } from 'react-router-dom'; -import { CameraProvider } from '../contexts/cameraContext'; +import { CameraProvider } from '../contexts/cameraContext.provider.js'; -import Filters from './Filters'; -import Home from './Home'; +import Filters from './Filters.js'; +import Home from './Home.js'; export default function App() { return ( diff --git a/demo/components/CameraFeed.tsx b/demo/components/CameraFeed.tsx index 613c565de..e0a882355 100644 --- a/demo/components/CameraFeed.tsx +++ b/demo/components/CameraFeed.tsx @@ -1,8 +1,8 @@ import { useEffect, useRef } from 'react'; -import { useCameraContext } from '../contexts/cameraContext'; +import { useCameraContext } from '../contexts/cameraContext.js'; -import UnavailableCamera from './UnavailableCamera'; +import UnavailableCamera from './UnavailableCamera.js'; export default function CameraFeed() { const [{ selectedCamera }] = useCameraContext(); @@ -11,8 +11,12 @@ export default function CameraFeed() { const video = videoRef.current; if (!video || !selectedCamera) return; video.srcObject = selectedCamera.stream; - video.onloadedmetadata = () => { - video.play().catch((err: unknown) => console.error(err)); + const onLoadedMetadata = () => { + video.play().catch((error: unknown) => console.error(error)); + }; + video.addEventListener('loadedmetadata', onLoadedMetadata); + return () => { + video.removeEventListener('loadedmetadata', onLoadedMetadata); }; }, [selectedCamera]); if (!selectedCamera) { diff --git a/demo/components/CameraSelector.tsx b/demo/components/CameraSelector.tsx index d0a0337c1..1ced9d719 100644 --- a/demo/components/CameraSelector.tsx +++ b/demo/components/CameraSelector.tsx @@ -1,4 +1,4 @@ -import { useCameraContext } from '../contexts/cameraContext'; +import { useCameraContext } from '../contexts/cameraContext.js'; export default function CameraSelector() { const [{ cameras, selectedCamera }, dispatch] = useCameraContext(); @@ -29,7 +29,7 @@ export default function CameraSelector() { camera: { device, stream }, }); }) - .catch((err: unknown) => console.error(err)); + .catch((error: unknown) => console.error(error)); } }} > diff --git a/demo/components/CameraSnapshotButton.tsx b/demo/components/CameraSnapshotButton.tsx index dbb52f9be..90c473816 100644 --- a/demo/components/CameraSnapshotButton.tsx +++ b/demo/components/CameraSnapshotButton.tsx @@ -1,11 +1,12 @@ -import { MutableRefObject, RefObject } from 'react'; +import type { RefObject } from 'react'; -import { readCanvas, Image } from '../../src'; +import type { Image } from '../../src/index.js'; +import { readCanvas } from '../../src/index.js'; interface CameraSnapshotButtonProps { - snapshotImageRef: MutableRefObject; + snapshotImageRef: RefObject; setSnapshotUrl: (snapshotUrl: string) => void; - canvasInputRef: RefObject; + canvasInputRef: RefObject; } export default function CameraSnapshotButton(props: CameraSnapshotButtonProps) { diff --git a/demo/components/CameraTransform.tsx b/demo/components/CameraTransform.tsx index 8bf73992d..36bc09e91 100644 --- a/demo/components/CameraTransform.tsx +++ b/demo/components/CameraTransform.tsx @@ -1,12 +1,14 @@ -import { RefObject, useEffect, useRef, useState } from 'react'; +import type { RefObject } from 'react'; +import { useEffect, useRef, useState } from 'react'; -import { Image, readCanvas, writeCanvas } from '../../src'; -import { convertColor } from '../../src/operations/convertColor'; -import { useCameraContext } from '../contexts/cameraContext'; +import type { Image } from '../../src/index.js'; +import { readCanvas, writeCanvas } from '../../src/index.js'; +import { convertColor } from '../../src/operations/convertColor.js'; +import { useCameraContext } from '../contexts/cameraContext.js'; -import ErrorAlert from './ErrorAlert'; -import SnapshotImage from './SnapshotImage'; -import UnavailableCamera from './UnavailableCamera'; +import ErrorAlert from './ErrorAlert.js'; +import SnapshotImage from './SnapshotImage.js'; +import UnavailableCamera from './UnavailableCamera.js'; export type TransformFunction = | ((image: Image) => Image) @@ -14,7 +16,7 @@ export type TransformFunction = interface CameraTransformProps { transform: TransformFunction; - canvasInputRef: RefObject; + canvasInputRef: RefObject; snapshotUrl: string; snapshotImageRef: RefObject; } @@ -36,7 +38,7 @@ export default function CameraTransform(props: CameraTransformProps) { const video = videoRef.current as HTMLVideoElement; let nextFrameRequest: number; video.srcObject = selectedCamera.stream; - video.onloadedmetadata = () => { + const onLoadedMetadata = () => { video .play() .then(() => { @@ -60,18 +62,20 @@ export default function CameraTransform(props: CameraTransformProps) { result = convertColor(result, 'RGBA'); } writeCanvas(result, canvasOutput); - } catch (err) { - setError(err.stack); - console.error(err); + } catch (error_) { + setError(error_.stack); + console.error(error_); } nextFrameRequest = requestAnimationFrame(nextFrame); } nextFrameRequest = requestAnimationFrame(nextFrame); }) - .catch((err: unknown) => console.error(err)); + .catch((error_: unknown) => console.error(error_)); }; + video.addEventListener('loadedmetadata', onLoadedMetadata); return () => { + video.removeEventListener('loadedmetadata', onLoadedMetadata); if (nextFrameRequest) { cancelAnimationFrame(nextFrameRequest); } diff --git a/demo/components/Container.tsx b/demo/components/Container.tsx index 64ca654fd..d262787c2 100644 --- a/demo/components/Container.tsx +++ b/demo/components/Container.tsx @@ -1,6 +1,6 @@ -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; -import Navbar from './Navbar'; +import Navbar from './Navbar.js'; interface ContainerProps { title: string; diff --git a/demo/components/ErrorAlert.tsx b/demo/components/ErrorAlert.tsx index 98617b467..1f9daf4d2 100644 --- a/demo/components/ErrorAlert.tsx +++ b/demo/components/ErrorAlert.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; export default function ErrorAlert(props: { children: ReactNode }) { return ( diff --git a/demo/components/Filters.tsx b/demo/components/Filters.tsx index c10e904a2..4f3abef29 100644 --- a/demo/components/Filters.tsx +++ b/demo/components/Filters.tsx @@ -1,4 +1,4 @@ -import Container from './Container'; +import Container from './Container.js'; export default function Filters() { return Filters; diff --git a/demo/components/Home.tsx b/demo/components/Home.tsx index 9333846f4..5deaab562 100644 --- a/demo/components/Home.tsx +++ b/demo/components/Home.tsx @@ -1,12 +1,13 @@ import { useRef, useState } from 'react'; -import { Image } from '../../src'; +import type { Image } from '../../src/index.js'; -import CameraSelector from './CameraSelector'; -import CameraSnapshotButton from './CameraSnapshotButton'; -import CameraTransform, { TransformFunction } from './CameraTransform'; -import Container from './Container'; -import { testGetFastKeypoints } from './testFunctions/testGetFastKeypoints'; +import CameraSelector from './CameraSelector.js'; +import CameraSnapshotButton from './CameraSnapshotButton.js'; +import type { TransformFunction } from './CameraTransform.js'; +import CameraTransform from './CameraTransform.js'; +import Container from './Container.js'; +import { testGetFastKeypoints } from './testFunctions/testGetFastKeypoints.js'; const testTransform: TransformFunction = testGetFastKeypoints; @@ -14,7 +15,6 @@ export default function Home() { const snapshotImageRef = useRef(null); const canvasInputRef = useRef(null); const [snapshotUrl, setSnapshotUrl] = useState(''); - console.log(snapshotUrl); return (
diff --git a/demo/components/SnapshotImage.tsx b/demo/components/SnapshotImage.tsx index f45530ff5..6244fe0e4 100644 --- a/demo/components/SnapshotImage.tsx +++ b/demo/components/SnapshotImage.tsx @@ -4,5 +4,7 @@ interface SnapshotImageProps { export default function SnapshotImage(props: SnapshotImageProps) { const { snapshotUrl: snapshot } = props; - return ; + return snapshot ? ( + snapshot + ) : null; } diff --git a/demo/components/UnavailableCamera.tsx b/demo/components/UnavailableCamera.tsx index a37099ac9..34645e7aa 100644 --- a/demo/components/UnavailableCamera.tsx +++ b/demo/components/UnavailableCamera.tsx @@ -1,4 +1,4 @@ -import ErrorAlert from './ErrorAlert'; +import ErrorAlert from './ErrorAlert.js'; export default function UnavailableCamera() { return Camera is not available.; diff --git a/demo/components/comparisonFunctions/testComputeSsim.ts b/demo/components/comparisonFunctions/testComputeSsim.ts index 84866bff4..c956dac38 100644 --- a/demo/components/comparisonFunctions/testComputeSsim.ts +++ b/demo/components/comparisonFunctions/testComputeSsim.ts @@ -1,10 +1,10 @@ -import { Image } from '../../../src'; -import { computeSsim } from '../../../src/compare/computeSsim'; +import { computeSsim } from '../../../src/compare/computeSsim.js'; +import { Image } from '../../../src/index.js'; /** * Compute the structural similarity of the input image and the image blurred. - * * @param image - Input image. + * @param snapshot * @returns The structural similarity matrix. */ export function testComputeSsim(image: Image, snapshot: Image | null): Image { diff --git a/demo/components/testFunctions/testCannyEdge.ts b/demo/components/testFunctions/testCannyEdge.ts index d8651b610..527263dd7 100644 --- a/demo/components/testFunctions/testCannyEdge.ts +++ b/demo/components/testFunctions/testCannyEdge.ts @@ -1,8 +1,8 @@ -import { convertBinaryToGrey, Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { convertBinaryToGrey } from '../../../src/index.js'; /** * Detect the edges in the image using Canny edge detection - * * @param image - Input image. * @returns The treated image. */ @@ -19,7 +19,6 @@ export function testCannyEdge(image: Image): Image { /** * Detect the edges in the image using Canny edge detection and overlay the edges on the original image. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testColorRois.ts b/demo/components/testFunctions/testColorRois.ts index c2bb0d6fe..c5b7df8f7 100644 --- a/demo/components/testFunctions/testColorRois.ts +++ b/demo/components/testFunctions/testColorRois.ts @@ -1,9 +1,8 @@ -import { Image } from '../../../src'; -import { fromMask, colorRois } from '../../../src/roi'; +import { Image } from '../../../src/index.js'; +import { fromMask, colorRois } from '../../../src/roi/index.js'; /** * Make a mask out of the image and detect all ROIs. Returns only the white ROIs on a black background. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testCopyTo.ts b/demo/components/testFunctions/testCopyTo.ts index 593a4c8a2..e832d4337 100644 --- a/demo/components/testFunctions/testCopyTo.ts +++ b/demo/components/testFunctions/testCopyTo.ts @@ -1,8 +1,7 @@ -import { Image } from '../../../src'; +import { Image } from '../../../src/index.js'; /** * Copy a black and a red square to the source image. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testCorrectColor.ts b/demo/components/testFunctions/testCorrectColor.ts index 331791d37..46e06ab75 100644 --- a/demo/components/testFunctions/testCorrectColor.ts +++ b/demo/components/testFunctions/testCorrectColor.ts @@ -1,15 +1,14 @@ -import { Image } from '../../../src'; -import { polishAltered } from '../../../src/correctColor/__tests__/testUtils/imageColors'; -import { referenceColorCard } from '../../../src/correctColor/__tests__/testUtils/referenceColorCard'; -import { correctColor } from '../../../src/correctColor/correctColor'; +import { polishAltered } from '../../../src/correctColor/__tests__/testUtils/imageColors.js'; +import { referenceColorCard } from '../../../src/correctColor/__tests__/testUtils/referenceColorCard.js'; +import { correctColor } from '../../../src/correctColor/correctColor.js'; import { getMeasuredColors, getReferenceColors, -} from '../../../src/correctColor/utils/formatData'; +} from '../../../src/correctColor/utils/formatData.js'; +import type { Image } from '../../../src/index.js'; /** * Copy a black and a red square to the source image. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testCrop.ts b/demo/components/testFunctions/testCrop.ts index 31b7e0114..de24edab0 100644 --- a/demo/components/testFunctions/testCrop.ts +++ b/demo/components/testFunctions/testCrop.ts @@ -1,4 +1,4 @@ -import { Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; // options const cropImageRatio = 2; // defines the size of the cropped image const interval = 2; // defines the speed diff --git a/demo/components/testFunctions/testDerivativeFilter.ts b/demo/components/testFunctions/testDerivativeFilter.ts index f66b89857..7a2415a98 100644 --- a/demo/components/testFunctions/testDerivativeFilter.ts +++ b/demo/components/testFunctions/testDerivativeFilter.ts @@ -1,8 +1,7 @@ -import { Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; /** * Apply a derivative filter to the source image. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testExtract.ts b/demo/components/testFunctions/testExtract.ts index 5d7f3fff0..be6c521b4 100644 --- a/demo/components/testFunctions/testExtract.ts +++ b/demo/components/testFunctions/testExtract.ts @@ -1,8 +1,7 @@ -import { fromMask, Image } from '../../../src'; +import { fromMask, Image } from '../../../src/index.js'; /** * Extract the pixels of a mask from the image. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testGetBorderPoints.ts b/demo/components/testFunctions/testGetBorderPoints.ts index 0997db278..2a44f23e4 100644 --- a/demo/components/testFunctions/testGetBorderPoints.ts +++ b/demo/components/testFunctions/testGetBorderPoints.ts @@ -1,7 +1,8 @@ -import { fromMask, Image, Mask } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { fromMask, Mask } from '../../../src/index.js'; /** * Paint the border of the larger black ROI on the image. - * @param image The image to process + * @param image - The image to process * @returns The processed image. */ export function testGetBorderPoints(image: Image): Image { diff --git a/demo/components/testFunctions/testGetConvexHull.ts b/demo/components/testFunctions/testGetConvexHull.ts index 23d54f508..46caafacb 100644 --- a/demo/components/testFunctions/testGetConvexHull.ts +++ b/demo/components/testFunctions/testGetConvexHull.ts @@ -1,8 +1,8 @@ -import { fromMask, Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { fromMask } from '../../../src/index.js'; /** * Draw the convex Hull polygon of the largest ROI in green and display the filled ROI in purple. - * * @param image - Input image. * @returns The image with the convex Hull. */ diff --git a/demo/components/testFunctions/testGetFastKeypoints.ts b/demo/components/testFunctions/testGetFastKeypoints.ts index bbabdf5de..c2d56f255 100644 --- a/demo/components/testFunctions/testGetFastKeypoints.ts +++ b/demo/components/testFunctions/testGetFastKeypoints.ts @@ -1,9 +1,8 @@ -import { Image } from '../../../src'; -import { getFastKeypoints } from '../../../src/featureMatching/keypoints/getFastKeypoints'; +import { getFastKeypoints } from '../../../src/featureMatching/keypoints/getFastKeypoints.js'; +import type { Image } from '../../../src/index.js'; /** * Find the FAST keypoints in the video. - * * @param image - Input image. * @returns The image with the fast keypoints. */ diff --git a/demo/components/testFunctions/testGetFeret.ts b/demo/components/testFunctions/testGetFeret.ts index 2e88ecfa5..838cc2777 100644 --- a/demo/components/testFunctions/testGetFeret.ts +++ b/demo/components/testFunctions/testGetFeret.ts @@ -1,8 +1,8 @@ -import { fromMask, Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { fromMask } from '../../../src/index.js'; /** * Draw the Feret diameters of the largest ROI detected in the image. - * * @param image - Input image. * @returns The image with the Feret diameters. */ diff --git a/demo/components/testFunctions/testGetMask.ts b/demo/components/testFunctions/testGetMask.ts index aa345a6c6..2d58f1cf3 100644 --- a/demo/components/testFunctions/testGetMask.ts +++ b/demo/components/testFunctions/testGetMask.ts @@ -1,7 +1,8 @@ -import { fromMask, Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { fromMask } from '../../../src/index.js'; /** * Paint the border of the larger black ROI on the image. - * @param image The image to process + * @param image - The image to process * @returns The processed image. */ export function testGetContourMask(image: Image): Image { diff --git a/demo/components/testFunctions/testGetMbr.ts b/demo/components/testFunctions/testGetMbr.ts index fbde77109..2f1638763 100644 --- a/demo/components/testFunctions/testGetMbr.ts +++ b/demo/components/testFunctions/testGetMbr.ts @@ -1,8 +1,8 @@ -import { fromMask, Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { fromMask } from '../../../src/index.js'; /** * Draw the MBR of the largest ROI. - * * @param image - Input image. * @returns The image with the MBR. */ diff --git a/demo/components/testFunctions/testLevel.ts b/demo/components/testFunctions/testLevel.ts index b0c80d6f3..939cdff11 100644 --- a/demo/components/testFunctions/testLevel.ts +++ b/demo/components/testFunctions/testLevel.ts @@ -1,8 +1,7 @@ -import { Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; /** * Enhance contrast of the source image using level. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/components/testFunctions/testPaintMask.ts b/demo/components/testFunctions/testPaintMask.ts index 2dfe8efae..51b13a3a4 100644 --- a/demo/components/testFunctions/testPaintMask.ts +++ b/demo/components/testFunctions/testPaintMask.ts @@ -1,7 +1,8 @@ -import { fromMask, Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; +import { fromMask } from '../../../src/index.js'; /** * Make the image translucent, excepted where the largest black ROI is. - * @param image Image to process. + * @param image - Image to process. * @returns Processed image. */ export function testPaintMask(image: Image): Image { diff --git a/demo/components/testFunctions/testRotate.ts b/demo/components/testFunctions/testRotate.ts index 23542445d..136b63766 100644 --- a/demo/components/testFunctions/testRotate.ts +++ b/demo/components/testFunctions/testRotate.ts @@ -1,8 +1,7 @@ -import { Image } from '../../../src'; +import type { Image } from '../../../src/index.js'; /** * Apply a derivative filter to the source image. - * * @param image - Input image. * @returns The treated image. */ diff --git a/demo/contexts/cameraContext.provider.tsx b/demo/contexts/cameraContext.provider.tsx new file mode 100644 index 000000000..aa8903924 --- /dev/null +++ b/demo/contexts/cameraContext.provider.tsx @@ -0,0 +1,56 @@ +import type { ReactNode } from 'react'; +import { useEffect, useMemo, useReducer } from 'react'; + +import type { CameraContext } from './cameraContext.js'; +import { + cameraContext, + cameraStateReducer, + defaultCameraState, +} from './cameraContext.js'; + +export function CameraProvider(props: { children: ReactNode }) { + const [cameraState, dispatch] = useReducer( + cameraStateReducer, + defaultCameraState, + ); + const value = useMemo( + () => [cameraState, dispatch], + [cameraState], + ); + useEffect(() => { + async function getCameras() { + const devices = await navigator.mediaDevices.enumerateDevices(); + const cameras = devices.filter((device) => device.kind === 'videoinput'); + if (cameras.length > 0) { + // TODO: handle denied permission + const firstCameraStream = await navigator.mediaDevices.getUserMedia({ + video: { deviceId: cameras[0].deviceId }, + }); + dispatch({ + type: 'SET_CAMERAS', + cameras, + firstCamera: { device: cameras[0], stream: firstCameraStream }, + }); + } + } + + function handleDeviceChange() { + getCameras().catch((error: unknown) => console.error(error)); + } + + navigator.mediaDevices.addEventListener('devicechange', handleDeviceChange); + handleDeviceChange(); + return () => { + navigator.mediaDevices.removeEventListener( + 'devicechange', + handleDeviceChange, + ); + }; + }, []); + + return ( + + {props.children} + + ); +} diff --git a/demo/contexts/cameraContext.tsx b/demo/contexts/cameraContext.tsx index 6a76d609b..115f0e567 100644 --- a/demo/contexts/cameraContext.tsx +++ b/demo/contexts/cameraContext.tsx @@ -1,13 +1,6 @@ import { produce } from 'immer'; -import { - createContext, - Dispatch, - ReactNode, - useContext, - useEffect, - useMemo, - useReducer, -} from 'react'; +import type { Dispatch } from 'react'; +import { createContext, useContext } from 'react'; interface Camera { device: MediaDeviceInfo; @@ -19,11 +12,17 @@ interface CameraState { selectedCamera: Camera | null; } -const defaultCameraState: CameraState = { cameras: [], selectedCamera: null }; +export const defaultCameraState: CameraState = { + cameras: [], + selectedCamera: null, +}; -type CameraContext = [state: CameraState, dispatch: Dispatch]; +export type CameraContext = [ + state: CameraState, + dispatch: Dispatch, +]; -const cameraContext = createContext([ +export const cameraContext = createContext([ defaultCameraState, () => { // Empty @@ -45,7 +44,7 @@ type CameraAction = camera: Camera; }; -const cameraStateReducer = produce( +export const cameraStateReducer = produce( (state: CameraState, action: CameraAction) => { switch (action.type) { case 'SET_CAMERAS': { @@ -55,7 +54,7 @@ const cameraStateReducer = produce( } else if (state.selectedCamera === null) { state.selectedCamera = action.firstCamera; } else if ( - !state.cameras.find( + !state.cameras.some( (camera) => camera.deviceId === action.firstCamera.device.deviceId, ) ) { @@ -73,50 +72,3 @@ const cameraStateReducer = produce( } }, ); - -export function CameraProvider(props: { children: ReactNode }) { - const [cameraState, dispatch] = useReducer( - cameraStateReducer, - defaultCameraState, - ); - const value = useMemo( - () => [cameraState, dispatch], - [cameraState], - ); - useEffect(() => { - async function getCameras() { - const devices = await navigator.mediaDevices.enumerateDevices(); - const cameras = devices.filter((device) => device.kind === 'videoinput'); - if (cameras.length > 0) { - // TODO: handle denied permission - const firstCameraStream = await navigator.mediaDevices.getUserMedia({ - video: { deviceId: cameras[0].deviceId }, - }); - dispatch({ - type: 'SET_CAMERAS', - cameras, - firstCamera: { device: cameras[0], stream: firstCameraStream }, - }); - } - } - - function handleDeviceChange() { - getCameras().catch((err: unknown) => console.error(err)); - } - - navigator.mediaDevices.addEventListener('devicechange', handleDeviceChange); - handleDeviceChange(); - return () => { - navigator.mediaDevices.removeEventListener( - 'devicechange', - handleDeviceChange, - ); - }; - }, []); - - return ( - - {props.children} - - ); -} diff --git a/demo/index.tsx b/demo/index.tsx index acd22de2c..ffc115d5f 100644 --- a/demo/index.tsx +++ b/demo/index.tsx @@ -2,8 +2,8 @@ import { createRoot } from 'react-dom/client'; import './index.css'; -import App from './components/App'; +import App from './components/App.js'; -const root = createRoot(document.getElementById('root') as HTMLElement); +const root = createRoot(document.querySelector('#root') as HTMLElement); root.render(); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..9138fca33 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,16 @@ +import react from 'eslint-config-cheminfo-react/base'; +import typescript from 'eslint-config-cheminfo-typescript'; + +export default [ + ...typescript, + ...react, + { + rules: { + '@typescript-eslint/restrict-template-expressions': 'off', + }, + }, + { + files: ['demo/**'], + rules: { 'no-console': 'off' }, + }, +]; diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 76118692f..000000000 --- a/examples/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# image-js API design - -## Reading and writing images - -## Colors - -## Pixel transformations - -## Regions of interest diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index e098b316b..000000000 --- a/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - collectCoverage: true, - setupFilesAfterEnv: ['/jest.setup.ts'], - testMatch: ['**/?(*.)+(test).[jt]s?(x)'], - reporters: [ - "default", - "jest-image-snapshot/src/outdated-snapshot-reporter.js" - ] -}; diff --git a/jest.setup.ts b/jest.setup.ts deleted file mode 100644 index c56f3ccf8..000000000 --- a/jest.setup.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { toBeDeepCloseTo, toMatchCloseTo } from 'jest-matcher-deep-close-to'; - -import * as jestMatchers from './test/jestMatchers'; -import * as testUtils from './test/testUtils'; - -expect.extend({ - toBeDeepCloseTo, - toMatchCloseTo, - ...jestMatchers, -}); - -globalThis.testUtils = testUtils; diff --git a/package.json b/package.json index df79bccc8..0e5077c1e 100644 --- a/package.json +++ b/package.json @@ -3,34 +3,35 @@ "version": "0.0.0", "description": "Image processing and manipulation in JavaScript", "keywords": [], + "type": "module", "author": "MichaĆ«l Zasso", "license": "MIT", "files": [ "src", "lib", - "lib-esm", + "lib-cjs", "dist-types" ], - "main": "./lib/index.js", - "module": "./lib-esm/index.js", + "main": "./lib-cjs/index.js", + "module": "./lib/index.js", "browser": { - "lib-esm/save/write.js": "./lib-esm/save/write.browser.js", - "lib-esm/load/read.js": "./lib-esm/load/read.browser.js" + "lib/save/write.js": "./lib/save/write.browser.js", + "lib/load/read.js": "./lib/load/read.browser.js" }, "scripts": { "api-extractor": "rimraf dist-types && api-extractor run --local", "check-types": "tsc --noEmit", - "clean": "rimraf lib lib-esm", + "clean": "rimraf lib lib-cjs", "demo": "vite --open", "eslint": "eslint src demo --cache", "eslint-fix": "npm run eslint -- --fix", "prepack": "npm run tsc && npm run api-extractor", "prettier": "prettier --check src demo", "prettier-write": "prettier --write src demo", - "test": "npm run test-only && npm run eslint && npm run prettier && npm run check-types", - "test-only": "cross-env JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest", + "test": "npm run check-types && npm run test-only && npm run eslint && npm run prettier", + "test-only": "cross-env JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 vitest run --coverage", "tsc": "npm run clean && npm run tsc-cjs && npm run tsc-esm", - "tsc-cjs": "tsc --project tsconfig.cjs.json", + "tsc-cjs": "tsc --project tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > lib-cjs/package.json", "tsc-esm": "tsc --project tsconfig.esm.json" }, "repository": { @@ -41,11 +42,8 @@ "url": "https://github.com/image-js/image-js/issues" }, "homepage": "https://github.com/image-js/image-js#readme", - "overrides": { - "jest": "$jest" - }, "dependencies": { - "bresenham-zingl": "^0.1.1", + "bresenham-zingl": "^0.2.0", "colord": "^2.9.3", "fast-bmp": "^2.0.1", "fast-jpeg": "^2.0.1", @@ -56,46 +54,46 @@ "median-quickselect": "^1.0.1", "ml-affine-transform": "^1.0.3", "ml-convolution": "^2.0.0", - "ml-matrix": "^6.11.0", + "ml-matrix": "^6.12.0", "ml-ransac": "^1.0.0", "ml-regression-multivariate-linear": "^2.0.4", - "ml-regression-polynomial-2d": "^0.2.0", - "ml-spectra-processing": "^14.3.0", + "ml-regression-polynomial-2d": "^1.0.0", + "ml-spectra-processing": "^14.9.1", "robust-point-in-polygon": "^1.0.3", "ssim.js": "^3.5.0", - "tiff": "^6.0.0" + "tiff": "^6.1.1", + "ts-pattern": "^5.6.1" }, "devDependencies": { - "@microsoft/api-extractor": "^7.43.1", - "@tailwindcss/forms": "^0.5.7", - "@types/jest": "^29.5.12", + "@microsoft/api-extractor": "^7.49.1", + "@tailwindcss/forms": "^0.5.10", "@types/jest-image-snapshot": "^6.4.0", "@types/js-priority-queue": "^0.0.9", - "@types/node": "^20.12.7", - "@types/picomatch": "^2.3.3", - "@types/react": "^18.2.75", - "@types/react-dom": "^18.2.24", + "@types/node": "^22.10.7", + "@types/react": "^19.0.7", + "@types/react-dom": "^19.0.3", "@types/robust-point-in-polygon": "^1.0.4", - "@vitejs/plugin-react": "^4.2.1", - "autoprefixer": "^10.4.19", - "clsx": "^2.1.0", + "@vitejs/plugin-react": "^4.3.4", + "@vitest/coverage-v8": "^2.1.8", + "@vitest/expect": "^2.1.8", + "autoprefixer": "^10.4.20", + "clsx": "^2.1.1", "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-cheminfo-react": "^11.0.1", - "eslint-config-cheminfo-typescript": "^12.3.0", - "immer": "^10.0.4", - "jest": "^29.7.0", + "eslint": "^9.18.0", + "eslint-config-cheminfo-react": "^15.0.0", + "eslint-config-cheminfo-typescript": "^17.0.0", + "immer": "^10.1.1", "jest-image-snapshot": "^6.4.0", "jest-matcher-deep-close-to": "^3.0.2", - "postcss": "^8.4.38", - "prettier": "^3.2.5", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.22.3", - "rimraf": "^5.0.5", - "tailwindcss": "^3.4.3", - "ts-jest": "^29.1.2", - "typescript": "~5.4.5", - "vite": "^5.2.8" + "postcss": "^8.5.1", + "prettier": "^3.4.2", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-router-dom": "^7.1.3", + "rimraf": "^6.0.1", + "tailwindcss": "^3.4.17", + "typescript": "~5.7.3", + "vite": "^6.0.8", + "vitest": "^2.1.8" } } diff --git a/postcss.config.js b/postcss.config.js index 33ad091d2..2aa7205d4 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ -module.exports = { +export default { plugins: { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/scripts/alignImages/alignImages.ts b/scripts/alignImages/alignImages.ts index 87fa9e7a5..b5b2fec47 100644 --- a/scripts/alignImages/alignImages.ts +++ b/scripts/alignImages/alignImages.ts @@ -1,9 +1,9 @@ -import { writeSync } from '../../src/save/write'; -import { overlapImages } from '../../src/featureMatching/visualize/overlapImages'; -import { readSync } from '../../src/load/read'; +import { writeSync } from '../../src/save/write.js'; +import { overlapImages } from '../../src/featureMatching/visualize/overlapImages.js'; +import { readSync } from '../../src/load/read.js'; import { readFileSync, readdirSync, unlinkSync } from 'fs'; import { join } from 'path'; -import { getAffineTransform } from '../../src'; +import { getAffineTransform } from '../../src/index.js'; // global variables const emptyFolder = true; // results diff --git a/scripts/benchmark/resize.benchmark.ts b/scripts/benchmark/resize.benchmark.ts index 73f5279d8..1cbc5f709 100644 --- a/scripts/benchmark/resize.benchmark.ts +++ b/scripts/benchmark/resize.benchmark.ts @@ -1,6 +1,6 @@ // run with `ts-node-transpile-only scripts/benchmark/resize.benchmark.ts` -import { read } from '../../src'; +import { read } from '../../src/index.js'; import { join } from 'path'; async function doAll() { diff --git a/scripts/featureMatching/featureMatchingTest.ts b/scripts/featureMatching/featureMatchingTest.ts index aee196426..50a7266b2 100644 --- a/scripts/featureMatching/featureMatchingTest.ts +++ b/scripts/featureMatching/featureMatchingTest.ts @@ -10,17 +10,17 @@ import { getCrosscheckMatches, MontageDisposition, getBestKeypointsInRadius, -} from '../../src/featureMatching'; -import { readSync, writeSync } from '../../src'; +} from '../../src/featureMatching.js'; +import { readSync, writeSync } from '../../src/index.js'; import { getBrief, GetBriefOptions, -} from '../../src/featureMatching/descriptors/getBrief'; -import { GetColorsOptions } from '../../src/featureMatching/utils/getColors'; -import { getMinMax } from '../../src/utils/getMinMax'; +} from '../../src/featureMatching/descriptors/getBrief.js'; +import { GetColorsOptions } from '../../src/featureMatching/utils/getColors.js'; +import { getMinMax } from '../../src/utils/getMinMax.js'; import util from 'util'; -import { sliceBrief } from '../../src/featureMatching/descriptors/utils/sliceBrief'; +import { sliceBrief } from '../../src/featureMatching/descriptors/utils/sliceBrief.js'; util.inspect.defaultOptions.depth = 5; const getBriefOptions: GetBriefOptions = { diff --git a/scripts/featureMatching/generateFMtestImages.ts b/scripts/featureMatching/generateFMtestImages.ts index e6dece385..b4af1d0f0 100644 --- a/scripts/featureMatching/generateFMtestImages.ts +++ b/scripts/featureMatching/generateFMtestImages.ts @@ -1,6 +1,6 @@ // generate some variations of the alphabet image for feature matching // run this script with: ts-node --log-error generateFMtestImages.ts -import { readSync, writeSync, Image } from '../../src'; +import { readSync, writeSync, Image } from '../../src/index.js'; import { join } from 'path'; console.log(__dirname); diff --git a/scripts/testHarris.ts b/scripts/testHarris.ts index 58ef3a366..a2c0e56e4 100644 --- a/scripts/testHarris.ts +++ b/scripts/testHarris.ts @@ -1,6 +1,6 @@ // @eslint-ignore -import { Image } from '../src/Image'; -import { getHarrisScore } from '../src/featureMatching/getHarrisScore'; +import { Image } from '../src/Image.js'; +import { getHarrisScore } from '../src/featureMatching/getHarrisScore.js'; const fastRadius = 3; diff --git a/scripts/tophatTest.ts b/scripts/tophatTest.ts index a117cfbaf..13999e77c 100644 --- a/scripts/tophatTest.ts +++ b/scripts/tophatTest.ts @@ -8,7 +8,7 @@ import { RoiKind, readSync, writeSync, -} from '../src/index'; +} from '../src/index.js'; const disk12 = [ [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], diff --git a/src/Image.ts b/src/Image.ts index 403e83b74..ca73c48a4 100644 --- a/src/Image.ts +++ b/src/Image.ts @@ -1,123 +1,135 @@ -import { RgbColor } from 'colord'; - -import { Mask } from './Mask'; -import { add, subtract, SubtractImageOptions } from './compare'; -import { divide, DivideOptions } from './compare/divide'; -import { multiply, MultiplyOptions } from './compare/multiply'; -import { +import type { RgbColor } from 'colord'; +import { match } from 'ts-pattern'; + +import type { Mask } from './Mask.js'; +import type { DivideOptions } from './compare/divide.js'; +import { divide } from './compare/divide.js'; +import { add, subtract } from './compare/index.js'; +import type { SubtractImageOptions } from './compare/index.js'; +import type { MultiplyOptions } from './compare/multiply.js'; +import { multiply } from './compare/multiply.js'; +import type { MedianOptions, MeanOptions, - median, VarianceOptions, - variance, -} from './compute'; -import { correctColor } from './correctColor'; + HistogramOptions, +} from './compute/index.js'; +import { histogram, mean, median, variance } from './compute/index.js'; +import { correctColor } from './correctColor/index.js'; +import type { + DrawCircleOnImageOptions, + DrawLineOnImageOptions, + DrawMarkerOptions, + DrawPointsOptions, + DrawPolygonOnImageOptions, + DrawPolylineOnImageOptions, + DrawRectangleOptions, +} from './draw/index.js'; import { drawCircleOnImage, - DrawCircleOnImageOptions, drawLineOnImage, - DrawLineOnImageOptions, drawMarker, - DrawMarkerOptions, drawMarkers, drawPoints, - DrawPointsOptions, drawPolygonOnImage, - DrawPolygonOnImageOptions, drawPolylineOnImage, - DrawPolylineOnImageOptions, drawRectangle, - DrawRectangleOptions, -} from './draw'; -import { - blur, +} from './draw/index.js'; +import type { BlurOptions, ConvolutionOptions, - derivativeFilter, DerivativeFilterOptions, + FlipOptions, + GaussianBlurOptions, + GradientFilterOptions, + HypotenuseOptions, + IncreaseContrastOptions, + InvertOptions, + LevelOptions, + MedianFilterOptions, + PixelateOptions, +} from './filters/index.js'; +import { + blur, + derivativeFilter, directConvolution, flip, - FlipOptions, gaussianBlur, - GaussianBlurOptions, gradientFilter, - GradientFilterOptions, hypotenuse, - HypotenuseOptions, increaseContrast, - IncreaseContrastOptions, invert, - InvertOptions, level, - LevelOptions, medianFilter, - MedianFilterOptions, pixelate, - PixelateOptions, rawDirectConvolution, separableConvolution, -} from './filters'; -import { +} from './filters/index.js'; +import type { Point, - resize, ResizeOptions, - rotate, RotateAngle, - transform, TransformOptions, - transformRotate, TransformRotateOptions, -} from './geometry'; +} from './geometry/index.js'; import { - bottomHat, + resize, + rotate, + transform, + transformRotate, +} from './geometry/index.js'; +import type { ImageMetadata } from './load/load.types.js'; +import type { BottomHatOptions, - cannyEdgeDetector, CannyEdgeOptions, - close, CloseOptions, - dilate, DilateOptions, - erode, ErodeOptions, - morphologicalGradient, MorphologicalGradientOptions, - open, OpenOptions, - topHat, TopHatOptions, -} from './morphology'; +} from './morphology/index.js'; +import { + bottomHat, + cannyEdgeDetector, + close, + dilate, + erode, + morphologicalGradient, + open, + topHat, +} from './morphology/index.js'; +import type { + ConvertColorOptions, + CopyToOptions, + CropAlphaOptions, + CropOptions, + CropRectangleOptions, + ExtractOptions, + GreyOptions, + PaintMaskOnImageOptions, + ThresholdOptions, +} from './operations/index.js'; import { convertBitDepth, convertColor, - ConvertColorOptions, copyTo, - CopyToOptions, crop, cropAlpha, - CropAlphaOptions, - CropOptions, cropRectangle, - CropRectangleOptions, + extract, grey, paintMaskOnImage, - PaintMaskOnImageOptions, split, -} from './operations'; -import { colorModels, ImageColorModel } from './utils/constants/colorModels'; -import { getMinMax } from './utils/getMinMax'; -import { validateChannel, validateValue } from './utils/validators/validators'; - -import { - extract, - ExtractOptions, - GreyOptions, - histogram, - HistogramOptions, - ImageMetadata, - mean, threshold, - ThresholdOptions, -} from './index'; +} from './operations/index.js'; +import type { ImageColorModel } from './utils/constants/colorModels.js'; +import { colorModels } from './utils/constants/colorModels.js'; +import { getMinMax } from './utils/getMinMax.js'; +import { + validateChannel, + validateValue, +} from './utils/validators/validators.js'; export type ImageDataArray = Uint8Array | Uint16Array | Uint8ClampedArray; @@ -649,8 +661,8 @@ export class Image { * @returns Coordinates of the point in the format [column, row]. */ public getCoordinates(coordinates: ImageCoordinates, round = false): Point { - switch (coordinates) { - case 'center': { + return match(coordinates) + .with('center', () => { const centerX = (this.width - 1) / 2; const centerY = (this.height - 1) / 2; if (round) { @@ -658,18 +670,15 @@ export class Image { } else { return { column: centerX, row: centerY }; } - } - case 'top-left': - return { column: 0, row: 0 }; - case 'top-right': - return { column: this.width - 1, row: 0 }; - case 'bottom-left': - return { column: 0, row: this.height - 1 }; - case 'bottom-right': - return { column: this.width - 1, row: this.height - 1 }; - default: - throw new RangeError(`invalid image coordinates: ${coordinates}`); - } + }) + .with('top-left', () => ({ column: 0, row: 0 })) + .with('top-right', () => ({ column: this.width - 1, row: 0 })) + .with('bottom-left', () => ({ column: 0, row: this.height - 1 })) + .with('bottom-right', () => ({ + column: this.width - 1, + row: this.height - 1, + })) + .exhaustive(); } // COMPARE @@ -1156,17 +1165,12 @@ function createPixelArray( maxValue: number, ): ImageDataArray { const length = channels * size; - let arr; - switch (bitDepth) { - case 8: - arr = new Uint8Array(length); - break; - case 16: - arr = new Uint16Array(length); - break; - default: + const arr = match(bitDepth) + .with(8, () => new Uint8Array(length)) + .with(16, () => new Uint16Array(length)) + .otherwise(() => { throw new RangeError(`invalid bitDepth: ${bitDepth}`); - } + }); // Alpha channel is 100% by default. if (alpha) { diff --git a/src/Mask.ts b/src/Mask.ts index 2c418a50c..c8f226400 100644 --- a/src/Mask.ts +++ b/src/Mask.ts @@ -1,62 +1,65 @@ -import { BitDepth, Image } from './Image'; -import { subtract, SubtractImageOptions } from './compare'; +import type { BitDepth, Image } from './Image.js'; +import type { SubtractImageOptions } from './compare/index.js'; +import { subtract } from './compare/index.js'; import { drawLineOnMask, - DrawLineOnMaskOptions, drawPoints, - DrawPointsOptions, drawPolygonOnMask, - DrawPolygonOnMaskOptions, drawPolylineOnMask, - DrawPolylineOnMaskOptions, drawRectangle, +} from './draw/index.js'; +import type { + DrawLineOnMaskOptions, + DrawPointsOptions, + DrawPolygonOnMaskOptions, + DrawPolylineOnMaskOptions, DrawRectangleOptions, -} from './draw'; -import { - and, - AndOptions, - invert, - InvertOptions, - or, - OrOptions, -} from './filters'; -import { ConvexHull, Feret, GetBorderPointsOptions, Mbr } from './maskAnalysis'; -import { getBorderPoints } from './maskAnalysis/getBorderPoints'; -import { getConvexHull } from './maskAnalysis/getConvexHull'; -import { getFeret } from './maskAnalysis/getFeret'; -import { getMbr } from './maskAnalysis/getMbr'; -import { - bottomHat, +} from './draw/index.js'; +import type { AndOptions, InvertOptions, OrOptions } from './filters/index.js'; +import { and, invert, or } from './filters/index.js'; +import { getBorderPoints } from './maskAnalysis/getBorderPoints.js'; +import { getConvexHull } from './maskAnalysis/getConvexHull.js'; +import { getFeret } from './maskAnalysis/getFeret.js'; +import { getMbr } from './maskAnalysis/getMbr.js'; +import type { + ConvexHull, + Feret, + GetBorderPointsOptions, + Mbr, +} from './maskAnalysis/index.js'; +import type { BottomHatOptions, - clearBorder, ClearBorderOptions, - close, CloseOptions, - dilate, DilateOptions, - erode, ErodeOptions, - floodFill, FloodFillOptions, - morphologicalGradient, MorphologicalGradientOptions, - open, OpenOptions, - solidFill, SolidFillOptions, - topHat, TopHatOptions, -} from './morphology'; +} from './morphology/index.js'; import { - convertColor, - copyTo, + bottomHat, + clearBorder, + close, + dilate, + erode, + floodFill, + morphologicalGradient, + open, + solidFill, + topHat, +} from './morphology/index.js'; +import type { CopyToOptions, - paintMaskOnMask, PaintMaskOnMaskOptions, -} from './operations'; -import { boolToNumber } from './utils/boolToNumber'; -import { colorModels, ImageColorModel } from './utils/constants/colorModels'; -import { Point } from './utils/geometry/points'; +} from './operations/index.js'; +import { convertColor, copyTo, paintMaskOnMask } from './operations/index.js'; +import { boolToNumber } from './utils/boolToNumber.js'; +import type { ImageColorModel } from './utils/constants/colorModels.js'; +import { colorModels } from './utils/constants/colorModels.js'; +import type { Point } from './utils/geometry/points.js'; export type BitValue = 1 | 0 | boolean; diff --git a/src/Stack.ts b/src/Stack.ts index e56f190c4..5ed727164 100644 --- a/src/Stack.ts +++ b/src/Stack.ts @@ -1,18 +1,20 @@ -import { BitDepth } from 'fast-png'; - -import { Image } from './Image'; -import { HistogramOptions } from './compute'; -import { histogram } from './stack/compute/histogram'; -import { maxImage } from './stack/compute/maxImage'; -import { meanImage } from './stack/compute/meanImage'; -import { medianImage } from './stack/compute/medianImage'; -import { minImage } from './stack/compute/minImage'; -import { sum } from './stack/compute/sum'; +import type { BitDepth } from 'fast-png'; + +import type { Image } from './Image.js'; +import type { HistogramOptions } from './compute/index.js'; +import { + histogram, + maxImage, + meanImage, + medianImage, + minImage, + sum, +} from './stack/index.js'; import { checkImagesValid, verifySameDimensions, -} from './stack/utils/checkImagesValid'; -import { ImageColorModel } from './utils/constants/colorModels'; +} from './stack/utils/checkImagesValid.js'; +import type { ImageColorModel } from './utils/constants/colorModels.js'; export class Stack { /** diff --git a/src/__tests__/Image.test.ts b/src/__tests__/Image.test.ts index f7f612cc3..1192ad974 100644 --- a/src/__tests__/Image.test.ts +++ b/src/__tests__/Image.test.ts @@ -1,7 +1,8 @@ import { inspect } from 'node:util'; -import { Image, ImageCoordinates } from '../Image'; -import { Point } from '../geometry'; +import type { ImageCoordinates } from '../Image.js'; +import { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; describe('create new images', () => { it('should create a 8-bit image', () => { @@ -220,9 +221,7 @@ test('getCoordinates - with rounding', () => { test('getCoordinates - bad parameter', () => { const img = new Image(4, 5); // @ts-expect-error bad parameter - expect(() => img.getCoordinates('bad')).toThrow( - /invalid image coordinates: bad/, - ); + expect(() => img.getCoordinates('bad')).toThrow('bad'); }); test('fill with a constant color', () => { diff --git a/src/__tests__/Mask.test.ts b/src/__tests__/Mask.test.ts index e0f5318d4..02a81024f 100644 --- a/src/__tests__/Mask.test.ts +++ b/src/__tests__/Mask.test.ts @@ -1,7 +1,7 @@ import util from 'node:util'; -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; +import { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; describe('create new masks', () => { it('should create a mask', () => { diff --git a/src/__tests__/Stack.test.ts b/src/__tests__/Stack.test.ts index 8e5c7bf7c..ec703cb5a 100644 --- a/src/__tests__/Stack.test.ts +++ b/src/__tests__/Stack.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import { Stack } from '../Stack'; +import { Image } from '../Image.js'; +import { Stack } from '../Stack.js'; describe('Stack constructor', () => { it('create a stack containing one image', () => { diff --git a/src/__tests__/__snapshots__/Image.test.ts.snap b/src/__tests__/__snapshots__/Image.test.ts.snap index dd37fb735..bf79ab7a5 100644 --- a/src/__tests__/__snapshots__/Image.test.ts.snap +++ b/src/__tests__/__snapshots__/Image.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`check custom inspect with image too large 1`] = ` "Image { diff --git a/src/__tests__/__snapshots__/Mask.test.ts.snap b/src/__tests__/__snapshots__/Mask.test.ts.snap index 5c9963bf4..c13c21470 100644 --- a/src/__tests__/__snapshots__/Mask.test.ts.snap +++ b/src/__tests__/__snapshots__/Mask.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`check custom inspect 1`] = ` "Mask { diff --git a/src/align/__tests__/alignMinDifference.test.ts b/src/align/__tests__/alignMinDifference.test.ts index 1ce8df95d..df65d979c 100644 --- a/src/align/__tests__/alignMinDifference.test.ts +++ b/src/align/__tests__/alignMinDifference.test.ts @@ -1,5 +1,5 @@ -import { overlapImages } from '../..'; -import { alignMinDifference } from '../alignMinDifference'; +import { overlapImages } from '../../featureMatching/index.js'; +import { alignMinDifference } from '../alignMinDifference.js'; test('1 pixel source', () => { const source = testUtils.createGreyImage([[255]]); diff --git a/src/align/affineTransfrom/__tests__/applyAffineTransform.test.ts b/src/align/affineTransfrom/__tests__/applyAffineTransform.test.ts index e01f2a2d5..55be4a110 100644 --- a/src/align/affineTransfrom/__tests__/applyAffineTransform.test.ts +++ b/src/align/affineTransfrom/__tests__/applyAffineTransform.test.ts @@ -1,8 +1,8 @@ -import Matrix from 'ml-matrix'; +import { Matrix } from 'ml-matrix'; -import { applyAffineTransfom } from '../applyAffineTransform'; -import { createAffineTransformModel } from '../createAffineTransformModel'; -import { getPointsFromMatrix } from '../getPointsFromMatrix'; +import { applyAffineTransfom } from '../applyAffineTransform.js'; +import { createAffineTransformModel } from '../createAffineTransformModel.js'; +import { getPointsFromMatrix } from '../getPointsFromMatrix.js'; test('6 points aligned', () => { const source = [ diff --git a/src/align/affineTransfrom/__tests__/createAffineTransformModel.test.ts b/src/align/affineTransfrom/__tests__/createAffineTransformModel.test.ts index 2767e8ebf..01ff83cf6 100644 --- a/src/align/affineTransfrom/__tests__/createAffineTransformModel.test.ts +++ b/src/align/affineTransfrom/__tests__/createAffineTransformModel.test.ts @@ -1,4 +1,4 @@ -import { createAffineTransformModel } from '../createAffineTransformModel'; +import { createAffineTransformModel } from '../createAffineTransformModel.js'; test('wrong nb of parameters', () => { expect(() => { diff --git a/src/align/affineTransfrom/__tests__/getAffineTransform.test.ts b/src/align/affineTransfrom/__tests__/getAffineTransform.test.ts index ac9a0906e..1297bab94 100644 --- a/src/align/affineTransfrom/__tests__/getAffineTransform.test.ts +++ b/src/align/affineTransfrom/__tests__/getAffineTransform.test.ts @@ -1,7 +1,7 @@ -import { Image } from '../../..'; -import { TestImagePath } from '../../../../test/TestImagePath'; -import { overlapImages } from '../../../featureMatching/visualize/overlapImages'; -import { getAffineTransform } from '../getAffineTransform'; +import type { TestImagePath } from '../../../../test/TestImagePath.js'; +import { Image } from '../../../Image.js'; +import { overlapImages } from '../../../featureMatching/index.js'; +import { getAffineTransform } from '../getAffineTransform.js'; test('RGB images', () => { const data = { diff --git a/src/align/affineTransfrom/__tests__/getMatrixFromPoints.test.ts b/src/align/affineTransfrom/__tests__/getMatrixFromPoints.test.ts index a6942ca11..279a83611 100644 --- a/src/align/affineTransfrom/__tests__/getMatrixFromPoints.test.ts +++ b/src/align/affineTransfrom/__tests__/getMatrixFromPoints.test.ts @@ -1,4 +1,4 @@ -import { getMatrixFromPoints } from '../getMatrixFromPoints'; +import { getMatrixFromPoints } from '../getMatrixFromPoints.js'; test('4 points', () => { const side = 3; diff --git a/src/align/affineTransfrom/__tests__/ransac.test.ts b/src/align/affineTransfrom/__tests__/ransac.test.ts index 5693665c8..dba3c4b03 100644 --- a/src/align/affineTransfrom/__tests__/ransac.test.ts +++ b/src/align/affineTransfrom/__tests__/ransac.test.ts @@ -1,10 +1,10 @@ import { ransac } from 'ml-ransac'; -import { affineFitFunction } from '../affineFitFunction'; -import { applyAffineTransfom } from '../applyAffineTransform'; -import { createAffineTransformModel } from '../createAffineTransformModel'; -import { drawResult } from '../drawResult'; -import { getEuclideanDistance } from '../getEuclideanDistance'; +import { affineFitFunction } from '../affineFitFunction.js'; +import { applyAffineTransfom } from '../applyAffineTransform.js'; +import { createAffineTransformModel } from '../createAffineTransformModel.js'; +import { drawResult } from '../drawResult.js'; +import { getEuclideanDistance } from '../getEuclideanDistance.js'; describe('2D data (points)', () => { it('6 points perfectly aligned', () => { @@ -33,6 +33,7 @@ describe('2D data (points)', () => { expect(result.modelParameters).toBeDeepCloseTo([180, 0, 4, 1]); }); + it('6 points with outliers', () => { const source = [ { row: 2, column: 2 }, @@ -61,7 +62,7 @@ describe('2D data (points)', () => { expect(result.inliers).toStrictEqual([1, 3, 4, 5]); }); - test('polygon rotated 180 degrees', () => { + it('polygon rotated 180 degrees', () => { const source = [ { column: 4, row: 3 }, { column: 2, row: 5 }, @@ -95,7 +96,8 @@ describe('2D data (points)', () => { expect(image).toMatchImageSnapshot(); }); - test('polygon rotated 90 degrees', () => { + + it('polygon rotated 90 degrees', () => { const source = [ { column: -6, row: -1 }, { column: -4, row: -2 }, diff --git a/src/align/affineTransfrom/affineFitFunction.ts b/src/align/affineTransfrom/affineFitFunction.ts index dced6e042..87544d82f 100644 --- a/src/align/affineTransfrom/affineFitFunction.ts +++ b/src/align/affineTransfrom/affineFitFunction.ts @@ -1,8 +1,8 @@ import { getAffineTransform } from 'ml-affine-transform'; -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; -import { getMatrixFromPoints } from './getMatrixFromPoints'; +import { getMatrixFromPoints } from './getMatrixFromPoints.js'; /** * The fit function for an affine transformation. diff --git a/src/align/affineTransfrom/applyAffineTransform.ts b/src/align/affineTransfrom/applyAffineTransform.ts index f6f07e27d..f4d9f4de6 100644 --- a/src/align/affineTransfrom/applyAffineTransform.ts +++ b/src/align/affineTransfrom/applyAffineTransform.ts @@ -1,6 +1,6 @@ -import { ModelFunction } from 'ml-ransac'; +import type { ModelFunction } from 'ml-ransac'; -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Apply a given transform to a set of points. diff --git a/src/align/affineTransfrom/createAffineTransformModel.ts b/src/align/affineTransfrom/createAffineTransformModel.ts index 0465ed785..8e756c9e9 100644 --- a/src/align/affineTransfrom/createAffineTransformModel.ts +++ b/src/align/affineTransfrom/createAffineTransformModel.ts @@ -1,6 +1,6 @@ -import { ModelFunction } from 'ml-ransac'; +import type { ModelFunction } from 'ml-ransac'; -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Generate a function that applies the given transformation parameters to a point. diff --git a/src/align/affineTransfrom/drawResult.ts b/src/align/affineTransfrom/drawResult.ts index 32fd2c5cd..13d3ca66f 100644 --- a/src/align/affineTransfrom/drawResult.ts +++ b/src/align/affineTransfrom/drawResult.ts @@ -1,4 +1,7 @@ -import { Point, Image, ImageColorModel, Mask } from '../..'; +import { Image } from '../../Image.js'; +import { Mask } from '../../Mask.js'; +import type { Point } from '../../geometry/index.js'; +import { ImageColorModel } from '../../utils/constants/colorModels.js'; /** * Draw source, destination and transformed points on an image. diff --git a/src/align/affineTransfrom/getAffineTransform.ts b/src/align/affineTransfrom/getAffineTransform.ts index 6586238d1..3112787e4 100644 --- a/src/align/affineTransfrom/getAffineTransform.ts +++ b/src/align/affineTransfrom/getAffineTransform.ts @@ -1,23 +1,26 @@ import { getAffineTransform as matrixGetAffineTransform } from 'ml-affine-transform'; import { ransac } from 'ml-ransac'; -import { Point, Image, writeSync, ImageColorModel } from '../..'; +import type { Image } from '../../Image.js'; +import { getBrief } from '../../featureMatching/descriptors/getBrief.js'; +import type { Match } from '../../featureMatching/index.js'; import { - Match, Montage, MontageDisposition, bruteForceOneMatch, getCrosscheckMatches, -} from '../../featureMatching'; -import { getBrief } from '../../featureMatching/descriptors/getBrief'; -import { filterEuclideanDistance } from '../../featureMatching/matching/filterEuclideanDistance'; -import { getMinMax } from '../../utils/getMinMax'; +} from '../../featureMatching/index.js'; +import { filterEuclideanDistance } from '../../featureMatching/matching/filterEuclideanDistance.js'; +import type { Point } from '../../geometry/index.js'; +import { writeSync } from '../../save/index.js'; +import { ImageColorModel } from '../../utils/constants/colorModels.js'; +import { getMinMax } from '../../utils/getMinMax.js'; -import { affineFitFunction } from './affineFitFunction'; -import { createAffineTransformModel } from './createAffineTransformModel'; -import { getEuclideanDistance } from './getEuclideanDistance'; -import { getMatrixFromPoints } from './getMatrixFromPoints'; -import { getSourceWithoutMargins } from './utils/getSourceWithoutMargins'; +import { affineFitFunction } from './affineFitFunction.js'; +import { createAffineTransformModel } from './createAffineTransformModel.js'; +import { getEuclideanDistance } from './getEuclideanDistance.js'; +import { getMatrixFromPoints } from './getMatrixFromPoints.js'; +import { getSourceWithoutMargins } from './utils/getSourceWithoutMargins.js'; export interface GetAffineTransformOptions { /** diff --git a/src/align/affineTransfrom/getEuclideanDistance.ts b/src/align/affineTransfrom/getEuclideanDistance.ts index 81c7eb32f..b5f833b20 100644 --- a/src/align/affineTransfrom/getEuclideanDistance.ts +++ b/src/align/affineTransfrom/getEuclideanDistance.ts @@ -1,4 +1,4 @@ -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Compute the distance between point 1 and point 2. diff --git a/src/align/affineTransfrom/getMatrixFromPoints.ts b/src/align/affineTransfrom/getMatrixFromPoints.ts index c192d9128..38701b11c 100644 --- a/src/align/affineTransfrom/getMatrixFromPoints.ts +++ b/src/align/affineTransfrom/getMatrixFromPoints.ts @@ -1,6 +1,6 @@ -import Matrix from 'ml-matrix'; +import { Matrix } from 'ml-matrix'; -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Convert row/column points to a matrix. diff --git a/src/align/affineTransfrom/getPointsFromMatrix.ts b/src/align/affineTransfrom/getPointsFromMatrix.ts index 9f7b395e5..33dad12d4 100644 --- a/src/align/affineTransfrom/getPointsFromMatrix.ts +++ b/src/align/affineTransfrom/getPointsFromMatrix.ts @@ -1,6 +1,6 @@ -import Matrix from 'ml-matrix'; +import type { Matrix } from 'ml-matrix'; -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Convert matrix to points. diff --git a/src/align/affineTransfrom/utils/__tests__/getSourceWithoutMargins.test.ts b/src/align/affineTransfrom/utils/__tests__/getSourceWithoutMargins.test.ts index d8ea193ca..5eb8bfb15 100644 --- a/src/align/affineTransfrom/utils/__tests__/getSourceWithoutMargins.test.ts +++ b/src/align/affineTransfrom/utils/__tests__/getSourceWithoutMargins.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../../../Image'; -import { getSourceWithoutMargins } from '../getSourceWithoutMargins'; +import { Image } from '../../../../Image.js'; +import { getSourceWithoutMargins } from '../getSourceWithoutMargins.js'; test('destination fully in source', () => { const source = new Image(10, 10); diff --git a/src/align/affineTransfrom/utils/getSourceWithoutMargins.ts b/src/align/affineTransfrom/utils/getSourceWithoutMargins.ts index 0c898b617..70bd73e65 100644 --- a/src/align/affineTransfrom/utils/getSourceWithoutMargins.ts +++ b/src/align/affineTransfrom/utils/getSourceWithoutMargins.ts @@ -1,4 +1,5 @@ -import { Image, Point } from '../../..'; +import type { Image } from '../../../Image.js'; +import type { Point } from '../../../geometry/index.js'; /** * Crop source image for contrast enhancement. diff --git a/src/align/alignMinDifference.ts b/src/align/alignMinDifference.ts index 2bff66db0..4cbd89348 100644 --- a/src/align/alignMinDifference.ts +++ b/src/align/alignMinDifference.ts @@ -1,5 +1,6 @@ -import { Image, Mask } from '..'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface AlignMinDifferenceOptions { /** diff --git a/src/align/index.ts b/src/align/index.ts index 63479151a..00938d676 100644 --- a/src/align/index.ts +++ b/src/align/index.ts @@ -1,2 +1,2 @@ -export * from './affineTransfrom/getAffineTransform'; -export * from './alignMinDifference'; +export * from './affineTransfrom/getAffineTransform.js'; +export * from './alignMinDifference.js'; diff --git a/src/compare/__tests__/add.test.ts b/src/compare/__tests__/add.test.ts index 60647e3ed..666afe725 100644 --- a/src/compare/__tests__/add.test.ts +++ b/src/compare/__tests__/add.test.ts @@ -1,4 +1,4 @@ -import { add } from '../add'; +import { add } from '../add.js'; test('add image to itself', () => { const image = testUtils.createRgbImage([[5, 5, 5, 10, 10, 10, 15, 15, 15]]); diff --git a/src/compare/__tests__/computeDssim.test.ts b/src/compare/__tests__/computeDssim.test.ts index 8bde16ca1..caae37738 100644 --- a/src/compare/__tests__/computeDssim.test.ts +++ b/src/compare/__tests__/computeDssim.test.ts @@ -1,5 +1,5 @@ -import { computeDssim } from '..'; -import { Image } from '../..'; +import { Image } from '../../Image.js'; +import { computeDssim } from '../computeDssim.js'; test('twice the same image', () => { const image = testUtils.createGreyImage([[5, 5, 5, 10, 10, 10, 15, 15, 15]]); diff --git a/src/compare/__tests__/computePsnr.test.ts b/src/compare/__tests__/computePsnr.test.ts index dc6651476..f1764d467 100644 --- a/src/compare/__tests__/computePsnr.test.ts +++ b/src/compare/__tests__/computePsnr.test.ts @@ -1,4 +1,4 @@ -import { computePsnr } from '../computePsnr'; +import { computePsnr } from '../computePsnr.js'; test('twice the same image', () => { const image = testUtils.createRgbImage([[5, 5, 5, 10, 10, 10, 15, 15, 15]]); diff --git a/src/compare/__tests__/computeRmse.test.ts b/src/compare/__tests__/computeRmse.test.ts index ce035ac11..f83129a4e 100644 --- a/src/compare/__tests__/computeRmse.test.ts +++ b/src/compare/__tests__/computeRmse.test.ts @@ -1,4 +1,4 @@ -import { computeMse, computeRmse } from '../computeRmse'; +import { computeMse, computeRmse } from '../computeRmse.js'; test('twice the same image', () => { const image = testUtils.createRgbImage([[5, 5, 5, 10, 10, 10, 15, 15, 15]]); diff --git a/src/compare/__tests__/computeSsim.test.ts b/src/compare/__tests__/computeSsim.test.ts index 514a03616..5fdbd5b03 100644 --- a/src/compare/__tests__/computeSsim.test.ts +++ b/src/compare/__tests__/computeSsim.test.ts @@ -1,6 +1,6 @@ -import { computeMse } from '..'; -import { Image } from '../..'; -import { computeSsim } from '../computeSsim'; +import { Image } from '../../Image.js'; +import { computeMse } from '../computeRmse.js'; +import { computeSsim } from '../computeSsim.js'; test('twice the same image', () => { const image = testUtils.createGreyImage([[5, 5, 5, 10, 10, 10, 15, 15, 15]]); diff --git a/src/compare/__tests__/divide.test.ts b/src/compare/__tests__/divide.test.ts index 9b238581c..b1b6718d7 100644 --- a/src/compare/__tests__/divide.test.ts +++ b/src/compare/__tests__/divide.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { divide } from '../divide'; +import { Image } from '../../Image.js'; +import { divide } from '../divide.js'; test('divide by 2', () => { let image = testUtils.createRgbaImage([ diff --git a/src/compare/__tests__/multiply.test.ts b/src/compare/__tests__/multiply.test.ts index b2c2540bb..db50ee94a 100644 --- a/src/compare/__tests__/multiply.test.ts +++ b/src/compare/__tests__/multiply.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; test('multiply by 2', () => { let image = testUtils.createRgbaImage([ diff --git a/src/compare/add.ts b/src/compare/add.ts index 1b33e79b7..a2ef69026 100644 --- a/src/compare/add.ts +++ b/src/compare/add.ts @@ -1,7 +1,7 @@ -import { Image } from '..'; -import { getClamp } from '../utils/clamp'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateForComparison } from '../utils/validators/validators'; +import { Image } from '../Image.js'; +import { getClamp } from '../utils/clamp.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateForComparison } from '../utils/validators/validators.js'; /** * * Calculate a new image that is the sum between the current image and the otherImage. diff --git a/src/compare/computeDssim.ts b/src/compare/computeDssim.ts index 42922d5bd..938a51064 100644 --- a/src/compare/computeDssim.ts +++ b/src/compare/computeDssim.ts @@ -1,6 +1,7 @@ -import { Image } from '..'; +import type { Image } from '../Image.js'; -import { computeSsim, SsimOptions } from './computeSsim'; +import type { SsimOptions } from './computeSsim.js'; +import { computeSsim } from './computeSsim.js'; /** * Compute the Structural Dissimilarity (DSSIM) of two GREY images. diff --git a/src/compare/computePsnr.ts b/src/compare/computePsnr.ts index 27ced6a90..4e143ee9e 100644 --- a/src/compare/computePsnr.ts +++ b/src/compare/computePsnr.ts @@ -1,6 +1,6 @@ -import { Image } from '..'; +import type { Image } from '../Image.js'; -import { computeRmse } from './computeRmse'; +import { computeRmse } from './computeRmse.js'; /** * Compute the Peak signal-to-noise ratio (PSNR) between two images. diff --git a/src/compare/computeRmse.ts b/src/compare/computeRmse.ts index d0e380223..4d7388694 100644 --- a/src/compare/computeRmse.ts +++ b/src/compare/computeRmse.ts @@ -1,4 +1,4 @@ -import { Image } from '..'; +import type { Image } from '../Image.js'; /** * Compute the Root Mean Square Error (RMSE) between two images. It is just the square root of the MSE. diff --git a/src/compare/computeSsim.ts b/src/compare/computeSsim.ts index 428e2c9c9..7f9867d58 100644 --- a/src/compare/computeSsim.ts +++ b/src/compare/computeSsim.ts @@ -1,8 +1,8 @@ import { ssim as bufferSsim } from 'ssim.js'; -import { Image } from '..'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateForComparison } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateForComparison } from '../utils/validators/validators.js'; export interface SsimOptions { /** diff --git a/src/compare/divide.ts b/src/compare/divide.ts index 1e6b4e1aa..05c3bf7a3 100644 --- a/src/compare/divide.ts +++ b/src/compare/divide.ts @@ -1,6 +1,6 @@ -import { Image } from '../Image'; -import { getOutputImage } from '../utils/getOutputImage'; -import { validateChannels } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { validateChannels } from '../utils/validators/validators.js'; export interface DivideOptions { /** diff --git a/src/compare/index.ts b/src/compare/index.ts index 421722454..7103c6df3 100644 --- a/src/compare/index.ts +++ b/src/compare/index.ts @@ -1,8 +1,8 @@ -export * from './computeDssim'; -export * from './computePsnr'; -export * from './computeRmse'; -export * from './computeSsim'; -export * from './subtract'; -export * from './add'; -export * from './divide'; -export * from './multiply'; +export * from './computeDssim.js'; +export * from './computePsnr.js'; +export * from './computeRmse.js'; +export * from './computeSsim.js'; +export * from './subtract.js'; +export * from './add.js'; +export * from './divide.js'; +export * from './multiply.js'; diff --git a/src/compare/multiply.ts b/src/compare/multiply.ts index 5a3e42bcc..6d18e258e 100644 --- a/src/compare/multiply.ts +++ b/src/compare/multiply.ts @@ -1,6 +1,6 @@ -import { Image } from '../Image'; -import { getOutputImage } from '../utils/getOutputImage'; -import { validateChannels } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { validateChannels } from '../utils/validators/validators.js'; export interface MultiplyOptions { /** diff --git a/src/compare/subtract.ts b/src/compare/subtract.ts index 689408589..323c136bb 100644 --- a/src/compare/subtract.ts +++ b/src/compare/subtract.ts @@ -1,6 +1,7 @@ -import { Image, Mask } from '..'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateForComparison } from '../utils/validators/validators'; +import { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateForComparison } from '../utils/validators/validators.js'; export interface SubtractImageOptions { /** diff --git a/src/compute/__tests__/getExtrema.test.ts b/src/compute/__tests__/getExtrema.test.ts index 9babc8b38..2ee049a28 100644 --- a/src/compute/__tests__/getExtrema.test.ts +++ b/src/compute/__tests__/getExtrema.test.ts @@ -1,4 +1,4 @@ -import { getExtrema } from '../getExtrema'; +import { getExtrema } from '../getExtrema.js'; test('minimum of grey image from legacy code', () => { const image = testUtils.createGreyImage([ diff --git a/src/compute/__tests__/histogram.test.ts b/src/compute/__tests__/histogram.test.ts index df1206363..ca467ce8a 100644 --- a/src/compute/__tests__/histogram.test.ts +++ b/src/compute/__tests__/histogram.test.ts @@ -1,4 +1,4 @@ -import { createImageFromData } from '../../../test/createImageFromData'; +import { createImageFromData } from '../../../test/createImageFromData.js'; test('RGBA image - channel 0', () => { const image = testUtils.createRgbaImage([ diff --git a/src/compute/__tests__/mean.test.ts b/src/compute/__tests__/mean.test.ts index 8a1ea6958..d1aa5291e 100644 --- a/src/compute/__tests__/mean.test.ts +++ b/src/compute/__tests__/mean.test.ts @@ -1,5 +1,5 @@ -import { Point } from '../../geometry'; -import { mean } from '../mean'; +import type { Point } from '../../geometry/index.js'; +import { mean } from '../mean.js'; test('5x1 RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/compute/__tests__/median.test.ts b/src/compute/__tests__/median.test.ts index 026d06bed..3f41b9ee5 100644 --- a/src/compute/__tests__/median.test.ts +++ b/src/compute/__tests__/median.test.ts @@ -1,5 +1,5 @@ -import { Point } from '../../geometry'; -import { median } from '../median'; +import type { Point } from '../../geometry/index.js'; +import { median } from '../median.js'; test('5x1 RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/compute/__tests__/variance.test.ts b/src/compute/__tests__/variance.test.ts index 4fce4a292..7fc127238 100644 --- a/src/compute/__tests__/variance.test.ts +++ b/src/compute/__tests__/variance.test.ts @@ -1,5 +1,5 @@ -import { Point } from '../../geometry'; -import { variance } from '../variance'; +import type { Point } from '../../geometry/index.js'; +import { variance } from '../variance.js'; test('1x1 RGB image', () => { const image = testUtils.createGreyImage([[1, 2, 3]]); diff --git a/src/compute/getExtrema.ts b/src/compute/getExtrema.ts index df739f85c..2c586aab8 100644 --- a/src/compute/getExtrema.ts +++ b/src/compute/getExtrema.ts @@ -1,6 +1,8 @@ -import { Image, Mask, Point } from '..'; -import { assertUnreachable } from '../utils/validators/assert'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../geometry/index.js'; +import { assertUnreachable } from '../utils/validators/assert.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface ExtremaOptions { /** diff --git a/src/compute/histogram.ts b/src/compute/histogram.ts index 5f2de8a1f..4ae105ad6 100644 --- a/src/compute/histogram.ts +++ b/src/compute/histogram.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import { validateChannel } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import { validateChannel } from '../utils/validators/validators.js'; export interface HistogramOptions { /** diff --git a/src/compute/index.ts b/src/compute/index.ts index 14403dc19..c4a57a708 100644 --- a/src/compute/index.ts +++ b/src/compute/index.ts @@ -1,5 +1,5 @@ -export * from './mean'; -export * from './histogram'; -export * from './median'; -export * from './getExtrema'; -export * from './variance'; +export * from './mean.js'; +export * from './histogram.js'; +export * from './median.js'; +export * from './getExtrema.js'; +export * from './variance.js'; diff --git a/src/compute/mean.ts b/src/compute/mean.ts index 5d6bd5e11..d6ebff052 100644 --- a/src/compute/mean.ts +++ b/src/compute/mean.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import { Point } from '../geometry'; +import type { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; export interface MeanOptions { /** diff --git a/src/compute/median.ts b/src/compute/median.ts index 6264566d4..051a3dcf5 100644 --- a/src/compute/median.ts +++ b/src/compute/median.ts @@ -1,8 +1,8 @@ // @ts-expect-error: median-quisckselect has no types import quickMedian from 'median-quickselect'; -import { Image } from '../Image'; -import { Point } from '../geometry'; +import type { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; export interface MedianOptions { /** diff --git a/src/compute/variance.ts b/src/compute/variance.ts index f0ad2277a..dcba08603 100644 --- a/src/compute/variance.ts +++ b/src/compute/variance.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import { Point } from '../geometry'; +import type { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; export interface VarianceOptions { /** diff --git a/src/correctColor/__tests__/correctColor.test.ts b/src/correctColor/__tests__/correctColor.test.ts index 146176165..7ab53d3d1 100644 --- a/src/correctColor/__tests__/correctColor.test.ts +++ b/src/correctColor/__tests__/correctColor.test.ts @@ -1,9 +1,9 @@ -import { correctColor } from '../correctColor'; -import { getMeasuredColors, getReferenceColors } from '../utils/formatData'; -import { getImageColors } from '../utils/getImageColors'; +import { correctColor } from '../correctColor.js'; +import { getMeasuredColors, getReferenceColors } from '../utils/formatData.js'; +import { getImageColors } from '../utils/getImageColors.js'; -import { polish } from './testUtils/imageColors'; -import { referenceColorCard } from './testUtils/referenceColorCard'; +import { polish } from './testUtils/imageColors.js'; +import { referenceColorCard } from './testUtils/referenceColorCard.js'; test('RGB image should not change', () => { const image = testUtils.createRgbImage([[0, 0, 0, 10, 10, 10, 20, 20, 20]]); diff --git a/src/correctColor/__tests__/testUtils/referenceColorCard.ts b/src/correctColor/__tests__/testUtils/referenceColorCard.ts index a7bf93452..c317cbc73 100644 --- a/src/correctColor/__tests__/testUtils/referenceColorCard.ts +++ b/src/correctColor/__tests__/testUtils/referenceColorCard.ts @@ -1,4 +1,4 @@ -import { LabColor } from 'colord'; +import type { LabColor } from 'colord'; export interface ColorCardSquare { /** diff --git a/src/correctColor/correctColor.ts b/src/correctColor/correctColor.ts index ba049d803..4ea57a0d8 100644 --- a/src/correctColor/correctColor.ts +++ b/src/correctColor/correctColor.ts @@ -1,11 +1,14 @@ -import { RgbColor } from 'colord'; +import type { RgbColor } from 'colord'; import MLR from 'ml-regression-multivariate-linear'; -import { Image } from '../Image'; -import { getClamp } from '../utils/clamp'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import { getClamp } from '../utils/clamp.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; -import { formatInputForMlr, formatReferenceForMlr } from './utils/formatData'; +import { + formatInputForMlr, + formatReferenceForMlr, +} from './utils/formatData.js'; /** * Correct the colors in an image using the reference colors. diff --git a/src/correctColor/index.ts b/src/correctColor/index.ts index 69a657f13..902edf032 100644 --- a/src/correctColor/index.ts +++ b/src/correctColor/index.ts @@ -1 +1 @@ -export * from './correctColor'; +export * from './correctColor.js'; diff --git a/src/correctColor/utils/formatData.ts b/src/correctColor/utils/formatData.ts index 11ef62951..34414b881 100644 --- a/src/correctColor/utils/formatData.ts +++ b/src/correctColor/utils/formatData.ts @@ -1,9 +1,13 @@ -import { colord, extend, RgbColor } from 'colord'; +import type { RgbColor } from 'colord'; +import { colord, extend } from 'colord'; import labPlugin from 'colord/plugins/lab'; -import { ColorCard } from '../__tests__/testUtils/referenceColorCard'; -import { getRegressionVariables } from '../correctColor'; +import type { ColorCard } from '../__tests__/testUtils/referenceColorCard.js'; +import { getRegressionVariables } from '../correctColor.js'; +// We can't use ts-expect-error because it's not an error when compiling for CJS. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore Module exports are not correctly typed. extend([labPlugin]); /** diff --git a/src/correctColor/utils/getImageColors.ts b/src/correctColor/utils/getImageColors.ts index 47bfc33fc..d934209ee 100644 --- a/src/correctColor/utils/getImageColors.ts +++ b/src/correctColor/utils/getImageColors.ts @@ -1,6 +1,6 @@ -import { RgbColor } from 'colord'; +import type { RgbColor } from 'colord'; -import { Image } from '../../Image'; +import type { Image } from '../../Image.js'; /** * Extract the colors of an image in order to use them for color correction. Should be used on small images only (smaller than 10x10 pixels), because it is these colors that will be used in the model (MLR). diff --git a/src/draw/__tests__/drawCircleOnImage.test.ts b/src/draw/__tests__/drawCircleOnImage.test.ts index cc53daba4..810202e20 100644 --- a/src/draw/__tests__/drawCircleOnImage.test.ts +++ b/src/draw/__tests__/drawCircleOnImage.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; test('draw circle image', () => { const image = testUtils.createRgbImage([ diff --git a/src/draw/__tests__/drawLineOnImage.test.ts b/src/draw/__tests__/drawLineOnImage.test.ts index 819b6ba21..e19ee1e66 100644 --- a/src/draw/__tests__/drawLineOnImage.test.ts +++ b/src/draw/__tests__/drawLineOnImage.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { drawLineOnImage } from '../drawLineOnImage'; +import { Image } from '../../Image.js'; +import { drawLineOnImage } from '../drawLineOnImage.js'; test('RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/draw/__tests__/drawLineOnMask.test.ts b/src/draw/__tests__/drawLineOnMask.test.ts index 2c95a331f..ea2be6c9c 100644 --- a/src/draw/__tests__/drawLineOnMask.test.ts +++ b/src/draw/__tests__/drawLineOnMask.test.ts @@ -1,5 +1,5 @@ -import { Mask } from '../../Mask'; -import { drawLineOnMask } from '../drawLineOnMask'; +import { Mask } from '../../Mask.js'; +import { drawLineOnMask } from '../drawLineOnMask.js'; test('3x3 mask, diagonal', () => { const mask = testUtils.createMask([ diff --git a/src/draw/__tests__/drawMarker.test.ts b/src/draw/__tests__/drawMarker.test.ts index 3cdaa04af..1e32a54c4 100644 --- a/src/draw/__tests__/drawMarker.test.ts +++ b/src/draw/__tests__/drawMarker.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; test('cross', () => { const image = testUtils.createGreyImage([ diff --git a/src/draw/__tests__/drawMarkers.test.ts b/src/draw/__tests__/drawMarkers.test.ts index 99747c00a..5bb1f708d 100644 --- a/src/draw/__tests__/drawMarkers.test.ts +++ b/src/draw/__tests__/drawMarkers.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; test('square', () => { const image = testUtils.createGreyImage([ diff --git a/src/draw/__tests__/drawPoints.test.ts b/src/draw/__tests__/drawPoints.test.ts index 7dc1c3334..6fca18c4a 100644 --- a/src/draw/__tests__/drawPoints.test.ts +++ b/src/draw/__tests__/drawPoints.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { drawPoints } from '../drawPoints'; +import { Image } from '../../Image.js'; +import { drawPoints } from '../drawPoints.js'; test('RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/draw/__tests__/drawPolygonOnImage.test.ts b/src/draw/__tests__/drawPolygonOnImage.test.ts index 5423226c3..c86b4ab01 100644 --- a/src/draw/__tests__/drawPolygonOnImage.test.ts +++ b/src/draw/__tests__/drawPolygonOnImage.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { drawPolygonOnImage } from '../drawPolygonOnImage'; +import { Image } from '../../Image.js'; +import { drawPolygonOnImage } from '../drawPolygonOnImage.js'; test('RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/draw/__tests__/drawPolygonOnMask.test.ts b/src/draw/__tests__/drawPolygonOnMask.test.ts index 99b3418df..5c9a2da1a 100644 --- a/src/draw/__tests__/drawPolygonOnMask.test.ts +++ b/src/draw/__tests__/drawPolygonOnMask.test.ts @@ -1,5 +1,5 @@ -import { Mask } from '../../Mask'; -import { drawPolygonOnMask } from '../drawPolygonOnMask'; +import { Mask } from '../../Mask.js'; +import { drawPolygonOnMask } from '../drawPolygonOnMask.js'; test('3x3 mask', () => { const mask = testUtils.createMask([ diff --git a/src/draw/__tests__/drawPolylineOnImage.test.ts b/src/draw/__tests__/drawPolylineOnImage.test.ts index 5b56bff0b..1ae5cd248 100644 --- a/src/draw/__tests__/drawPolylineOnImage.test.ts +++ b/src/draw/__tests__/drawPolylineOnImage.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { drawPolylineOnImage } from '../drawPolylineOnImage'; +import { Image } from '../../Image.js'; +import { drawPolylineOnImage } from '../drawPolylineOnImage.js'; test('RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/draw/__tests__/drawPolylineOnMask.test.ts b/src/draw/__tests__/drawPolylineOnMask.test.ts index 21f1076ee..26d1a5292 100644 --- a/src/draw/__tests__/drawPolylineOnMask.test.ts +++ b/src/draw/__tests__/drawPolylineOnMask.test.ts @@ -1,5 +1,5 @@ -import { Mask } from '../../Mask'; -import { drawPolylineOnMask } from '../drawPolylineOnMask'; +import { Mask } from '../../Mask.js'; +import { drawPolylineOnMask } from '../drawPolylineOnMask.js'; test('3x3 mask', () => { const image = new Mask(3, 3); diff --git a/src/draw/__tests__/drawRectangle.test.ts b/src/draw/__tests__/drawRectangle.test.ts index a46d6b914..e90f4652e 100644 --- a/src/draw/__tests__/drawRectangle.test.ts +++ b/src/draw/__tests__/drawRectangle.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { drawRectangle } from '../drawRectangle'; +import { Image } from '../../Image.js'; +import { drawRectangle } from '../drawRectangle.js'; test('RGB image', () => { const image = testUtils.createRgbImage([ diff --git a/src/draw/drawCircleOnImage.ts b/src/draw/drawCircleOnImage.ts index 94cb5be9a..0b1645847 100644 --- a/src/draw/drawCircleOnImage.ts +++ b/src/draw/drawCircleOnImage.ts @@ -1,14 +1,14 @@ import { circle } from 'bresenham-zingl'; -import { Image } from '../Image'; -import { Point } from '../utils/geometry/points'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage } from '../utils/getOutputImage'; -import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateColor } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateColor } from '../utils/validators/validators.js'; -import { roundPoint } from './utils/roundPoint'; +import { roundPoint } from './utils/roundPoint.js'; // Inspired by https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/ diff --git a/src/draw/drawLineOnImage.ts b/src/draw/drawLineOnImage.ts index 7ae0c2dca..2bf4e88c0 100644 --- a/src/draw/drawLineOnImage.ts +++ b/src/draw/drawLineOnImage.ts @@ -1,12 +1,12 @@ import { line } from 'bresenham-zingl'; -import { Image } from '../Image'; -import { Point } from '../utils/geometry/points'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage } from '../utils/getOutputImage'; -import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateColor } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateColor } from '../utils/validators/validators.js'; export interface DrawLineOnImageOptions { /** diff --git a/src/draw/drawLineOnMask.ts b/src/draw/drawLineOnMask.ts index 8c64cddd3..8a8a97771 100644 --- a/src/draw/drawLineOnMask.ts +++ b/src/draw/drawLineOnMask.ts @@ -1,8 +1,8 @@ import { line } from 'bresenham-zingl'; -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { maskToOutputMask } from '../utils/getOutputImage'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; export interface DrawLineOnMaskOptions { /** diff --git a/src/draw/drawMarker.ts b/src/draw/drawMarker.ts index 7aa75ab9d..6bbe9910e 100644 --- a/src/draw/drawMarker.ts +++ b/src/draw/drawMarker.ts @@ -1,9 +1,9 @@ -import { Image } from '../Image'; -import { Point } from '../geometry'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage } from '../utils/getOutputImage'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateColor } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateColor } from '../utils/validators/validators.js'; export interface DrawMarkerOptions { /** diff --git a/src/draw/drawMarkers.ts b/src/draw/drawMarkers.ts index 1500a877a..8cc5c0f98 100644 --- a/src/draw/drawMarkers.ts +++ b/src/draw/drawMarkers.ts @@ -1,8 +1,9 @@ -import { Image } from '../Image'; -import { Point } from '../geometry'; -import { getOutputImage } from '../utils/getOutputImage'; +import type { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; -import { DrawMarkerOptions, drawMarker } from './drawMarker'; +import type { DrawMarkerOptions } from './drawMarker.js'; +import { drawMarker } from './drawMarker.js'; /** * Draw markers on the image. diff --git a/src/draw/drawPoints.ts b/src/draw/drawPoints.ts index ab26d3d32..9430e354f 100644 --- a/src/draw/drawPoints.ts +++ b/src/draw/drawPoints.ts @@ -1,11 +1,11 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage'; -import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateColor } from '../utils/validators/validators'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage.js'; +import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateColor } from '../utils/validators/validators.js'; export interface DrawPointsOptions { /** diff --git a/src/draw/drawPolygonOnImage.ts b/src/draw/drawPolygonOnImage.ts index 27cbd657f..d9bd52750 100644 --- a/src/draw/drawPolygonOnImage.ts +++ b/src/draw/drawPolygonOnImage.ts @@ -1,15 +1,15 @@ import robustPointInPolygon from 'robust-point-in-polygon'; -import { Image } from '../Image'; -import { arrayPointsToObjects } from '../utils/arrayPointsToObjects'; -import { Point } from '../utils/geometry/points'; -import { getOutputImage } from '../utils/getOutputImage'; -import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateColor } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import { arrayPointsToObjects } from '../utils/arrayPointsToObjects.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateColor } from '../utils/validators/validators.js'; -import { DrawPolylineOnImageOptions } from './drawPolylineOnImage'; -import { deleteDuplicates } from './utils/deleteDuplicates'; +import type { DrawPolylineOnImageOptions } from './drawPolylineOnImage.js'; +import { deleteDuplicates } from './utils/deleteDuplicates.js'; export interface DrawPolygonOnImageOptions extends DrawPolylineOnImageOptions { /** diff --git a/src/draw/drawPolygonOnMask.ts b/src/draw/drawPolygonOnMask.ts index f634f619e..d80b31f99 100644 --- a/src/draw/drawPolygonOnMask.ts +++ b/src/draw/drawPolygonOnMask.ts @@ -1,12 +1,12 @@ import robustPointInPolygon from 'robust-point-in-polygon'; -import { Mask } from '../Mask'; -import { arrayPointsToObjects } from '../utils/arrayPointsToObjects'; -import { Point } from '../utils/geometry/points'; -import { maskToOutputMask } from '../utils/getOutputImage'; +import type { Mask } from '../Mask.js'; +import { arrayPointsToObjects } from '../utils/arrayPointsToObjects.js'; +import type { Point } from '../utils/geometry/points.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; -import { DrawPolylineOnMaskOptions } from './drawPolylineOnMask'; -import { deleteDuplicates } from './utils/deleteDuplicates'; +import type { DrawPolylineOnMaskOptions } from './drawPolylineOnMask.js'; +import { deleteDuplicates } from './utils/deleteDuplicates.js'; export interface DrawPolygonOnMaskOptions extends DrawPolylineOnMaskOptions { /** diff --git a/src/draw/drawPolylineOnImage.ts b/src/draw/drawPolylineOnImage.ts index d363a0c97..58c76be84 100644 --- a/src/draw/drawPolylineOnImage.ts +++ b/src/draw/drawPolylineOnImage.ts @@ -1,9 +1,9 @@ -import { Image } from '../Image'; -import { Point } from '../utils/geometry/points'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage } from '../utils/getOutputImage'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateColor } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateColor } from '../utils/validators/validators.js'; export interface DrawPolylineOnImageOptions { /** diff --git a/src/draw/drawPolylineOnMask.ts b/src/draw/drawPolylineOnMask.ts index 3c2f540c5..96dbc785b 100644 --- a/src/draw/drawPolylineOnMask.ts +++ b/src/draw/drawPolylineOnMask.ts @@ -1,6 +1,6 @@ -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { maskToOutputMask } from '../utils/getOutputImage'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; export interface DrawPolylineOnMaskOptions { /** diff --git a/src/draw/drawRectangle.ts b/src/draw/drawRectangle.ts index d688bed0c..5722c9167 100644 --- a/src/draw/drawRectangle.ts +++ b/src/draw/drawRectangle.ts @@ -1,10 +1,10 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage'; -import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage.js'; +import { setBlendedVisiblePixel } from '../utils/setBlendedVisiblePixel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface DrawRectangleOptions { /** diff --git a/src/draw/index.ts b/src/draw/index.ts index 374ac49ed..1caf752d6 100644 --- a/src/draw/index.ts +++ b/src/draw/index.ts @@ -1,11 +1,11 @@ -export * from './drawCircleOnImage'; -export * from './drawLineOnImage'; -export * from './drawLineOnMask'; -export * from './drawPolylineOnImage'; -export * from './drawPolylineOnMask'; -export * from './drawPolygonOnImage'; -export * from './drawPolygonOnMask'; -export * from './drawRectangle'; -export * from './drawPoints'; -export * from './drawMarker'; -export * from './drawMarkers'; +export * from './drawCircleOnImage.js'; +export * from './drawLineOnImage.js'; +export * from './drawLineOnMask.js'; +export * from './drawPolylineOnImage.js'; +export * from './drawPolylineOnMask.js'; +export * from './drawPolygonOnImage.js'; +export * from './drawPolygonOnMask.js'; +export * from './drawRectangle.js'; +export * from './drawPoints.js'; +export * from './drawMarker.js'; +export * from './drawMarkers.js'; diff --git a/src/draw/utils/__tests__/deleteDuplicates.test.ts b/src/draw/utils/__tests__/deleteDuplicates.test.ts index dca081c5b..d2efdc61d 100644 --- a/src/draw/utils/__tests__/deleteDuplicates.test.ts +++ b/src/draw/utils/__tests__/deleteDuplicates.test.ts @@ -1,4 +1,4 @@ -import { deleteDuplicates } from '../deleteDuplicates'; +import { deleteDuplicates } from '../deleteDuplicates.js'; test('should remove duplicate points', () => { const points = [ diff --git a/src/draw/utils/deleteDuplicates.ts b/src/draw/utils/deleteDuplicates.ts index 11468c550..d3a83061b 100644 --- a/src/draw/utils/deleteDuplicates.ts +++ b/src/draw/utils/deleteDuplicates.ts @@ -1,4 +1,4 @@ -import { Point } from '../../utils/geometry/points'; +import type { Point } from '../../utils/geometry/points.js'; /** * Remove duplicate points from array. diff --git a/src/draw/utils/roundPoint.ts b/src/draw/utils/roundPoint.ts index d420b31d8..c9b93d050 100644 --- a/src/draw/utils/roundPoint.ts +++ b/src/draw/utils/roundPoint.ts @@ -1,4 +1,4 @@ -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Round a point to the nearest integer. diff --git a/src/featureMatching/descriptors/__tests__/getBriefDescriptors.test.ts b/src/featureMatching/descriptors/__tests__/getBriefDescriptors.test.ts index 77b7404cd..bb417525c 100644 --- a/src/featureMatching/descriptors/__tests__/getBriefDescriptors.test.ts +++ b/src/featureMatching/descriptors/__tests__/getBriefDescriptors.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { getBriefDescriptors } from '../getBriefDescriptors'; +import { Image } from '../../../Image.js'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { getBriefDescriptors } from '../getBriefDescriptors.js'; test('count occurences of 1 and 0 with default options', () => { const image = testUtils.load('various/alphabet.jpg'); diff --git a/src/featureMatching/descriptors/getBrief.ts b/src/featureMatching/descriptors/getBrief.ts index 47bd6c252..917414370 100644 --- a/src/featureMatching/descriptors/getBrief.ts +++ b/src/featureMatching/descriptors/getBrief.ts @@ -1,8 +1,9 @@ -import { getBestKeypointsInRadius } from '..'; -import { Image } from '../..'; -import { getOrientedFastKeypoints } from '../keypoints/getOrientedFastKeypoints'; +import type { Image } from '../../Image.js'; +import { getBestKeypointsInRadius } from '../keypoints/getBestKeypointsInRadius.js'; +import { getOrientedFastKeypoints } from '../keypoints/getOrientedFastKeypoints.js'; -import { Brief, getBriefDescriptors } from './getBriefDescriptors'; +import type { Brief } from './getBriefDescriptors.js'; +import { getBriefDescriptors } from './getBriefDescriptors.js'; export interface GetBriefOptions { centroidPatchDiameter?: number; diff --git a/src/featureMatching/descriptors/getBriefDescriptors.ts b/src/featureMatching/descriptors/getBriefDescriptors.ts index deb6275e9..3ad0c3b35 100644 --- a/src/featureMatching/descriptors/getBriefDescriptors.ts +++ b/src/featureMatching/descriptors/getBriefDescriptors.ts @@ -1,12 +1,12 @@ -import { Image } from '../../Image'; -import { GaussianBlurSigmaOptions } from '../../filters'; -import { GetGaussianPointsOptions } from '../../utils/utils.types'; -import checkProcessable from '../../utils/validators/checkProcessable'; -import { OrientedFastKeypoint } from '../keypoints/getOrientedFastKeypoints'; -import { compareIntensity } from '../utils/compareIntensity'; -import { getGaussianPoints } from '../utils/getGaussianPoints'; +import type { Image } from '../../Image.js'; +import type { GaussianBlurSigmaOptions } from '../../filters/index.js'; +import type { GetGaussianPointsOptions } from '../../utils/utils.types.js'; +import checkProcessable from '../../utils/validators/checkProcessable.js'; +import type { OrientedFastKeypoint } from '../keypoints/getOrientedFastKeypoints.js'; +import { compareIntensity } from '../utils/compareIntensity.js'; +import { getGaussianPoints } from '../utils/getGaussianPoints.js'; -import { getKeypointPatch } from './utils/getKeypointPatch'; +import { getKeypointPatch } from './utils/getKeypointPatch.js'; export interface GetBriefDescriptorsOptions { /** diff --git a/src/featureMatching/descriptors/utils/__tests__/getKeypointPatch.test.ts b/src/featureMatching/descriptors/utils/__tests__/getKeypointPatch.test.ts index 4eebf5471..c917af808 100644 --- a/src/featureMatching/descriptors/utils/__tests__/getKeypointPatch.test.ts +++ b/src/featureMatching/descriptors/utils/__tests__/getKeypointPatch.test.ts @@ -1,7 +1,7 @@ -import { TestImagePath } from '../../../../../test/TestImagePath'; -import { getOrientedFastKeypoints } from '../../../keypoints/getOrientedFastKeypoints'; -import { drawKeypoints } from '../../../visualize/drawKeypoints'; -import { getKeypointPatch } from '../getKeypointPatch'; +import type { TestImagePath } from '../../../../../test/TestImagePath.js'; +import { getOrientedFastKeypoints } from '../../../keypoints/getOrientedFastKeypoints.js'; +import { drawKeypoints } from '../../../visualize/drawKeypoints.js'; +import { getKeypointPatch } from '../getKeypointPatch.js'; test.each([ { diff --git a/src/featureMatching/descriptors/utils/__tests__/sliceBrief.test.ts b/src/featureMatching/descriptors/utils/__tests__/sliceBrief.test.ts index 2da65a588..d26a1f2d8 100644 --- a/src/featureMatching/descriptors/utils/__tests__/sliceBrief.test.ts +++ b/src/featureMatching/descriptors/utils/__tests__/sliceBrief.test.ts @@ -1,6 +1,6 @@ -import { getOrientedFastKeypoints } from '../../../keypoints/getOrientedFastKeypoints'; -import { getBriefDescriptors } from '../../getBriefDescriptors'; -import { sliceBrief } from '../sliceBrief'; +import { getOrientedFastKeypoints } from '../../../keypoints/getOrientedFastKeypoints.js'; +import { getBriefDescriptors } from '../../getBriefDescriptors.js'; +import { sliceBrief } from '../sliceBrief.js'; test('default options', () => { const image = testUtils diff --git a/src/featureMatching/descriptors/utils/getKeypointPatch.ts b/src/featureMatching/descriptors/utils/getKeypointPatch.ts index 249ac05df..7b41963c7 100644 --- a/src/featureMatching/descriptors/utils/getKeypointPatch.ts +++ b/src/featureMatching/descriptors/utils/getKeypointPatch.ts @@ -1,8 +1,8 @@ -import { Image } from '../../../Image'; -import { getRadius } from '../../../utils/getRadius'; -import { OrientedFastKeypoint } from '../../keypoints/getOrientedFastKeypoints'; -import { checkBorderDistance } from '../../utils/checkBorderDistance'; -import { extractSquareImage } from '../../utils/extractSquareImage'; +import type { Image } from '../../../Image.js'; +import { getRadius } from '../../../utils/getRadius.js'; +import type { OrientedFastKeypoint } from '../../keypoints/getOrientedFastKeypoints.js'; +import { checkBorderDistance } from '../../utils/checkBorderDistance.js'; +import { extractSquareImage } from '../../utils/extractSquareImage.js'; export interface GetKeypointPatchOptions { /** diff --git a/src/featureMatching/descriptors/utils/sliceBrief.ts b/src/featureMatching/descriptors/utils/sliceBrief.ts index d298afbde..d9beb9c7b 100644 --- a/src/featureMatching/descriptors/utils/sliceBrief.ts +++ b/src/featureMatching/descriptors/utils/sliceBrief.ts @@ -1,4 +1,4 @@ -import { Brief } from '../..'; +import type { Brief } from '../getBriefDescriptors.js'; export interface SliceBriefOptions { /** diff --git a/src/featureMatching/index.ts b/src/featureMatching/index.ts index 82fcb805a..fb7b21273 100644 --- a/src/featureMatching/index.ts +++ b/src/featureMatching/index.ts @@ -1,12 +1,12 @@ -export * from './descriptors/getBriefDescriptors'; -export * from './featureMatching.types'; -export * from './keypoints/getFastKeypoints'; -export * from './keypoints/getIntensityCentroid'; -export * from './keypoints/getOrientedFastKeypoints'; -export * from './keypoints/getBestKeypointsInRadius'; -export * from './matching/bruteForceMatch'; -export * from './matching/getCrosscheckMatches'; -export * from './visualize/drawKeypoints'; -export * from './visualize/drawMatches'; -export * from './visualize/Montage'; -export * from './visualize/overlapImages'; +export * from './descriptors/getBriefDescriptors.js'; +export * from './featureMatching.types.js'; +export * from './keypoints/getFastKeypoints.js'; +export * from './keypoints/getIntensityCentroid.js'; +export * from './keypoints/getOrientedFastKeypoints.js'; +export * from './keypoints/getBestKeypointsInRadius.js'; +export * from './matching/bruteForceMatch.js'; +export * from './matching/getCrosscheckMatches.js'; +export * from './visualize/drawKeypoints.js'; +export * from './visualize/drawMatches.js'; +export * from './visualize/Montage.js'; +export * from './visualize/overlapImages.js'; diff --git a/src/featureMatching/keypoints/__tests__/getBestKeypointsInRadius.test.ts b/src/featureMatching/keypoints/__tests__/getBestKeypointsInRadius.test.ts index 863ce71b2..0dcd999a0 100644 --- a/src/featureMatching/keypoints/__tests__/getBestKeypointsInRadius.test.ts +++ b/src/featureMatching/keypoints/__tests__/getBestKeypointsInRadius.test.ts @@ -1,9 +1,7 @@ -import { drawKeypoints } from '../../visualize/drawKeypoints'; -import { getBestKeypointsInRadius } from '../getBestKeypointsInRadius'; -import { - getOrientedFastKeypoints, - OrientedFastKeypoint, -} from '../getOrientedFastKeypoints'; +import { drawKeypoints } from '../../visualize/drawKeypoints.js'; +import { getBestKeypointsInRadius } from '../getBestKeypointsInRadius.js'; +import type { OrientedFastKeypoint } from '../getOrientedFastKeypoints.js'; +import { getOrientedFastKeypoints } from '../getOrientedFastKeypoints.js'; test('array of 3 keypoints', () => { const keypoints: OrientedFastKeypoint[] = [ diff --git a/src/featureMatching/keypoints/__tests__/getFastKeypoints.test.ts b/src/featureMatching/keypoints/__tests__/getFastKeypoints.test.ts index c081050ea..f822942b6 100644 --- a/src/featureMatching/keypoints/__tests__/getFastKeypoints.test.ts +++ b/src/featureMatching/keypoints/__tests__/getFastKeypoints.test.ts @@ -1,5 +1,5 @@ -import { drawKeypoints } from '../../visualize/drawKeypoints'; -import { getFastKeypoints } from '../getFastKeypoints'; +import { drawKeypoints } from '../../visualize/drawKeypoints.js'; +import { getFastKeypoints } from '../getFastKeypoints.js'; test('alphabet image, default options', () => { const image = testUtils.load('various/alphabet.jpg'); @@ -75,5 +75,5 @@ test('undefined score algorithm error', () => { expect(() => { // @ts-expect-error: test for js users getFastKeypoints(grey, { scoreAlgorithm: 'test' }); - }).toThrow('invalid score algorithm: test'); + }).toThrow('test'); }); diff --git a/src/featureMatching/keypoints/__tests__/getHarrisScore.test.ts b/src/featureMatching/keypoints/__tests__/getHarrisScore.test.ts index e6ed4e02f..50d0c4114 100644 --- a/src/featureMatching/keypoints/__tests__/getHarrisScore.test.ts +++ b/src/featureMatching/keypoints/__tests__/getHarrisScore.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../../Image'; -import { getHarrisScore } from '../getHarrisScore'; +import { Image } from '../../../Image.js'; +import { getHarrisScore } from '../getHarrisScore.js'; const fastRadius = 3; const fastDiameter = 2 * fastRadius + 1; diff --git a/src/featureMatching/keypoints/__tests__/getIntensityCentroid.test.ts b/src/featureMatching/keypoints/__tests__/getIntensityCentroid.test.ts index 041cc9cf1..9cbd7d597 100644 --- a/src/featureMatching/keypoints/__tests__/getIntensityCentroid.test.ts +++ b/src/featureMatching/keypoints/__tests__/getIntensityCentroid.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../../Image'; -import { getIntensityCentroid } from '../getIntensityCentroid'; +import { Image } from '../../../Image.js'; +import { getIntensityCentroid } from '../getIntensityCentroid.js'; test('3x3 empty image', () => { const image = new Image(3, 3, { colorModel: 'GREY' }); diff --git a/src/featureMatching/keypoints/__tests__/getIntensityMoment.test.ts b/src/featureMatching/keypoints/__tests__/getIntensityMoment.test.ts index 5a23aac6a..a7f8fbb69 100644 --- a/src/featureMatching/keypoints/__tests__/getIntensityMoment.test.ts +++ b/src/featureMatching/keypoints/__tests__/getIntensityMoment.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../../Image'; -import { getIntensityMoment } from '../getIntensityMoment'; +import { Image } from '../../../Image.js'; +import { getIntensityMoment } from '../getIntensityMoment.js'; test('3x3 empty image, 00', () => { const image = new Image(3, 3, { colorModel: 'GREY' }); diff --git a/src/featureMatching/keypoints/__tests__/getOrientedFastKeypoints.test.ts b/src/featureMatching/keypoints/__tests__/getOrientedFastKeypoints.test.ts index 6fc43d2e5..8fce2dde2 100644 --- a/src/featureMatching/keypoints/__tests__/getOrientedFastKeypoints.test.ts +++ b/src/featureMatching/keypoints/__tests__/getOrientedFastKeypoints.test.ts @@ -1,6 +1,6 @@ -import { TestImagePath } from '../../../../test/TestImagePath'; -import { drawKeypoints } from '../../visualize/drawKeypoints'; -import { getOrientedFastKeypoints } from '../getOrientedFastKeypoints'; +import type { TestImagePath } from '../../../../test/TestImagePath.js'; +import { drawKeypoints } from '../../visualize/drawKeypoints.js'; +import { getOrientedFastKeypoints } from '../getOrientedFastKeypoints.js'; test('7x7 image, angle = -90Ā°', () => { const image = testUtils.createGreyImage([ diff --git a/src/featureMatching/keypoints/__tests__/getPatchIntensityCentroid.test.ts b/src/featureMatching/keypoints/__tests__/getPatchIntensityCentroid.test.ts index 22056f305..64b71ce37 100644 --- a/src/featureMatching/keypoints/__tests__/getPatchIntensityCentroid.test.ts +++ b/src/featureMatching/keypoints/__tests__/getPatchIntensityCentroid.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { round, sum } from '../../../utils/geometry/points'; -import { getPatchIntensityCentroid } from '../getPatchIntensityCentroid'; +import { Image } from '../../../Image.js'; +import { round, sum } from '../../../utils/geometry/points.js'; +import { getPatchIntensityCentroid } from '../getPatchIntensityCentroid.js'; test('3x3 empty image', () => { const image = new Image(7, 7, { colorModel: 'GREY' }); diff --git a/src/featureMatching/keypoints/__tests__/getPatchIntensityMoment.test.ts b/src/featureMatching/keypoints/__tests__/getPatchIntensityMoment.test.ts index 95bda5c80..b1aef66bb 100644 --- a/src/featureMatching/keypoints/__tests__/getPatchIntensityMoment.test.ts +++ b/src/featureMatching/keypoints/__tests__/getPatchIntensityMoment.test.ts @@ -1,4 +1,4 @@ -import { getPatchIntensityMoment } from '../getPatchIntensityMoment'; +import { getPatchIntensityMoment } from '../getPatchIntensityMoment.js'; test('5x5 image, 01, radius = 1', () => { const image = testUtils.createGreyImage([ diff --git a/src/featureMatching/keypoints/__tests__/isFastKeypoint.test.ts b/src/featureMatching/keypoints/__tests__/isFastKeypoint.test.ts index b1511c744..c99fd8565 100644 --- a/src/featureMatching/keypoints/__tests__/isFastKeypoint.test.ts +++ b/src/featureMatching/keypoints/__tests__/isFastKeypoint.test.ts @@ -1,9 +1,9 @@ -import { Image } from '../../../Image'; +import { Image } from '../../../Image.js'; import { getCirclePoints, getCompassPoints, -} from '../../../utils/geometry/getCirclePoints'; -import { isFastKeypoint } from '../isFastKeypoint'; +} from '../../../utils/geometry/getCirclePoints.js'; +import { isFastKeypoint } from '../isFastKeypoint.js'; const fastRadius = 3; const fastDiameter = 2 * fastRadius + 1; diff --git a/src/featureMatching/keypoints/getBestKeypointsInRadius.ts b/src/featureMatching/keypoints/getBestKeypointsInRadius.ts index 5a9afadd3..bed12925c 100644 --- a/src/featureMatching/keypoints/getBestKeypointsInRadius.ts +++ b/src/featureMatching/keypoints/getBestKeypointsInRadius.ts @@ -1,5 +1,5 @@ -import { OrientedFastKeypoint } from './getOrientedFastKeypoints'; -import { getKeypointsInRadius } from './utils/getKeypointsInRadius'; +import type { OrientedFastKeypoint } from './getOrientedFastKeypoints.js'; +import { getKeypointsInRadius } from './utils/getKeypointsInRadius.js'; /** * Return the best keypoints within the given radius in pixels. diff --git a/src/featureMatching/keypoints/getFastKeypoints.ts b/src/featureMatching/keypoints/getFastKeypoints.ts index 5c448282e..d67afc566 100644 --- a/src/featureMatching/keypoints/getFastKeypoints.ts +++ b/src/featureMatching/keypoints/getFastKeypoints.ts @@ -1,17 +1,20 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import { match } from 'ts-pattern'; + +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; import { getCirclePoints, getCompassPoints, -} from '../../utils/geometry/getCirclePoints'; -import { getIndex } from '../../utils/getIndex'; -import { surroundingPixels } from '../../utils/surroundingPixels'; -import checkProcessable from '../../utils/validators/checkProcessable'; -import { GetHarrisScoreOptions } from '../featureMatching.types'; +} from '../../utils/geometry/getCirclePoints.js'; +import { getIndex } from '../../utils/getIndex.js'; +import { surroundingPixels } from '../../utils/surroundingPixels.js'; +import checkProcessable from '../../utils/validators/checkProcessable.js'; +import type { GetHarrisScoreOptions } from '../featureMatching.types.js'; -import { getFastScore } from './getFastScore'; -import { getHarrisScore } from './getHarrisScore'; -import { isFastKeypoint, IsFastKeypointOptions } from './isFastKeypoint'; +import { getFastScore } from './getFastScore.js'; +import { getHarrisScore } from './getHarrisScore.js'; +import type { IsFastKeypointOptions } from './isFastKeypoint.js'; +import { isFastKeypoint } from './isFastKeypoint.js'; export interface GetFastKeypointsOptions extends IsFastKeypointOptions { /** @@ -87,6 +90,17 @@ export function getFastKeypoints( alpha: false, }); + const getScore = match(scoreAlgorithm) + .with('HARRIS', () => { + return (image: Image, corner: Point) => + getHarrisScore(image, corner, harrisScoreOptions); + }) + .with('FAST', () => { + return (image: Image, corner: Point) => + getFastScore(image, corner, threshold, circlePoints); + }) + .exhaustive(); + const allKeypoints: FastKeypoint[] = []; const scoreArray = new Float64Array(image.size).fill( @@ -101,17 +115,7 @@ export function getFastKeypoints( threshold, }) ) { - let score = 0; - switch (scoreAlgorithm) { - case 'HARRIS': - score = getHarrisScore(image, corner, harrisScoreOptions); - break; - case 'FAST': - score = getFastScore(image, corner, threshold, circlePoints); - break; - default: - throw new RangeError(`invalid score algorithm: ${scoreAlgorithm}`); - } + const score = getScore(image, corner); scoreArray[getIndex(corner.column, corner.row, image, 0)] = score; allKeypoints.push({ origin: corner, score }); } diff --git a/src/featureMatching/keypoints/getFastScore.ts b/src/featureMatching/keypoints/getFastScore.ts index bd3370aa8..8068adcdc 100644 --- a/src/featureMatching/keypoints/getFastScore.ts +++ b/src/featureMatching/keypoints/getFastScore.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; /** * Compute the score of a keypoint using the function described in the FAST article. diff --git a/src/featureMatching/keypoints/getHarrisScore.ts b/src/featureMatching/keypoints/getHarrisScore.ts index aae863b00..7acb9ce22 100644 --- a/src/featureMatching/keypoints/getHarrisScore.ts +++ b/src/featureMatching/keypoints/getHarrisScore.ts @@ -1,9 +1,9 @@ -import Matrix, { EigenvalueDecomposition, WrapperMatrix1D } from 'ml-matrix'; +import { Matrix, EigenvalueDecomposition, WrapperMatrix1D } from 'ml-matrix'; -import { Image } from '../../Image'; -import { Point } from '../../geometry'; -import { SOBEL_X, SOBEL_Y } from '../../utils/constants/kernels'; -import { GetHarrisScoreOptions } from '../featureMatching.types'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; +import { SOBEL_X, SOBEL_Y } from '../../utils/constants/kernels.js'; +import type { GetHarrisScoreOptions } from '../featureMatching.types.js'; /** * Get the Harris score of a corner. The idea behind the algorithm is that a diff --git a/src/featureMatching/keypoints/getIntensityCentroid.ts b/src/featureMatching/keypoints/getIntensityCentroid.ts index fc13a7728..12c679b52 100644 --- a/src/featureMatching/keypoints/getIntensityCentroid.ts +++ b/src/featureMatching/keypoints/getIntensityCentroid.ts @@ -1,7 +1,7 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; -import { getIntensityMoment } from './getIntensityMoment'; +import { getIntensityMoment } from './getIntensityMoment.js'; /** * Compute the intensity centroid of an image for each channel relatively to the center of the image. diff --git a/src/featureMatching/keypoints/getIntensityMoment.ts b/src/featureMatching/keypoints/getIntensityMoment.ts index 894467597..c13745027 100644 --- a/src/featureMatching/keypoints/getIntensityMoment.ts +++ b/src/featureMatching/keypoints/getIntensityMoment.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; export interface GetIntensityMomentOptions { /** diff --git a/src/featureMatching/keypoints/getOrientedFastKeypoints.ts b/src/featureMatching/keypoints/getOrientedFastKeypoints.ts index 46e78a2eb..f313de699 100644 --- a/src/featureMatching/keypoints/getOrientedFastKeypoints.ts +++ b/src/featureMatching/keypoints/getOrientedFastKeypoints.ts @@ -1,15 +1,15 @@ -import { Image } from '../../Image'; -import { getClockwiseAngle } from '../../maskAnalysis/utils/getAngle'; -import { toDegrees } from '../../utils/geometry/angles'; -import { getRadius } from '../../utils/getRadius'; -import { checkBorderDistance } from '../utils/checkBorderDistance'; +import type { Image } from '../../Image.js'; +import { getClockwiseAngle } from '../../maskAnalysis/utils/getAngle.js'; +import { toDegrees } from '../../utils/geometry/angles.js'; +import { getRadius } from '../../utils/getRadius.js'; +import { checkBorderDistance } from '../utils/checkBorderDistance.js'; -import { +import type { FastKeypoint, - getFastKeypoints, GetFastKeypointsOptions, -} from './getFastKeypoints'; -import { getPatchIntensityCentroid } from './getPatchIntensityCentroid'; +} from './getFastKeypoints.js'; +import { getFastKeypoints } from './getFastKeypoints.js'; +import { getPatchIntensityCentroid } from './getPatchIntensityCentroid.js'; export interface GetOrientedFastKeypointsOptions extends GetFastKeypointsOptions { diff --git a/src/featureMatching/keypoints/getPatchIntensityCentroid.ts b/src/featureMatching/keypoints/getPatchIntensityCentroid.ts index 6f66c8ca2..852db470e 100644 --- a/src/featureMatching/keypoints/getPatchIntensityCentroid.ts +++ b/src/featureMatching/keypoints/getPatchIntensityCentroid.ts @@ -1,10 +1,8 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; -import { - getPatchIntensityMoment, - GetPatchIntensityMomentOptions, -} from './getPatchIntensityMoment'; +import type { GetPatchIntensityMomentOptions } from './getPatchIntensityMoment.js'; +import { getPatchIntensityMoment } from './getPatchIntensityMoment.js'; /** * Compute the intensity centroid of the circular patch in an image for each channel relatively to the center of the image. diff --git a/src/featureMatching/keypoints/getPatchIntensityMoment.ts b/src/featureMatching/keypoints/getPatchIntensityMoment.ts index 112b2f580..e75bf632b 100644 --- a/src/featureMatching/keypoints/getPatchIntensityMoment.ts +++ b/src/featureMatching/keypoints/getPatchIntensityMoment.ts @@ -1,7 +1,7 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; -import { getFilledCirclePoints } from '../../utils/geometry/getCirclePoints'; -import { checkBorderDistance } from '../utils/checkBorderDistance'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; +import { getFilledCirclePoints } from '../../utils/geometry/getCirclePoints.js'; +import { checkBorderDistance } from '../utils/checkBorderDistance.js'; export interface GetPatchIntensityMomentOptions { /** diff --git a/src/featureMatching/keypoints/isFastKeypoint.ts b/src/featureMatching/keypoints/isFastKeypoint.ts index 6c35402af..87ae26e6e 100644 --- a/src/featureMatching/keypoints/isFastKeypoint.ts +++ b/src/featureMatching/keypoints/isFastKeypoint.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; export interface IsFastKeypointOptions { /** diff --git a/src/featureMatching/keypoints/utils/__tests__/getDistanceMatrix.test.ts b/src/featureMatching/keypoints/utils/__tests__/getDistanceMatrix.test.ts index c853d78d9..bc452e60b 100644 --- a/src/featureMatching/keypoints/utils/__tests__/getDistanceMatrix.test.ts +++ b/src/featureMatching/keypoints/utils/__tests__/getDistanceMatrix.test.ts @@ -1,5 +1,5 @@ -import { OrientedFastKeypoint } from '../../getOrientedFastKeypoints'; -import { getDistanceMatrix } from '../getDistanceMatrix'; +import type { OrientedFastKeypoint } from '../../getOrientedFastKeypoints.js'; +import { getDistanceMatrix } from '../getDistanceMatrix.js'; test('array of 3 keypoints', () => { const keypoints: OrientedFastKeypoint[] = [ diff --git a/src/featureMatching/keypoints/utils/__tests__/getKeypointsInRadius.test.ts b/src/featureMatching/keypoints/utils/__tests__/getKeypointsInRadius.test.ts index 792637e26..3d52c41d7 100644 --- a/src/featureMatching/keypoints/utils/__tests__/getKeypointsInRadius.test.ts +++ b/src/featureMatching/keypoints/utils/__tests__/getKeypointsInRadius.test.ts @@ -1,5 +1,5 @@ -import { OrientedFastKeypoint } from '../../getOrientedFastKeypoints'; -import { getKeypointsInRadius } from '../getKeypointsInRadius'; +import type { OrientedFastKeypoint } from '../../getOrientedFastKeypoints.js'; +import { getKeypointsInRadius } from '../getKeypointsInRadius.js'; test('array of 3 keypoints', () => { const keypoints: OrientedFastKeypoint[] = [ diff --git a/src/featureMatching/keypoints/utils/getDistanceMatrix.ts b/src/featureMatching/keypoints/utils/getDistanceMatrix.ts index abbb99cf7..c374139df 100644 --- a/src/featureMatching/keypoints/utils/getDistanceMatrix.ts +++ b/src/featureMatching/keypoints/utils/getDistanceMatrix.ts @@ -1,4 +1,4 @@ -import { OrientedFastKeypoint } from '../..'; +import type { OrientedFastKeypoint } from '../getOrientedFastKeypoints.js'; export type DistanceMatrix = Float64Array[]; diff --git a/src/featureMatching/keypoints/utils/getKeypointsInRadius.ts b/src/featureMatching/keypoints/utils/getKeypointsInRadius.ts index e076c395b..3787e53da 100644 --- a/src/featureMatching/keypoints/utils/getKeypointsInRadius.ts +++ b/src/featureMatching/keypoints/utils/getKeypointsInRadius.ts @@ -1,6 +1,6 @@ -import { OrientedFastKeypoint } from '../..'; +import type { OrientedFastKeypoint } from '../getOrientedFastKeypoints.js'; -import { getDistanceMatrix } from './getDistanceMatrix'; +import { getDistanceMatrix } from './getDistanceMatrix.js'; export type DistanceMatrix = Float64Array[]; diff --git a/src/featureMatching/matching/__tests__/bruteForceMatch.test.ts b/src/featureMatching/matching/__tests__/bruteForceMatch.test.ts index a4da1fdc9..a8f812709 100644 --- a/src/featureMatching/matching/__tests__/bruteForceMatch.test.ts +++ b/src/featureMatching/matching/__tests__/bruteForceMatch.test.ts @@ -1,9 +1,9 @@ -import { TestImagePath } from '../../../../test/TestImagePath'; -import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors'; -import { getBestKeypointsInRadius } from '../../keypoints/getBestKeypointsInRadius'; -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { Montage } from '../../visualize/Montage'; -import { bruteForceOneMatch } from '../bruteForceMatch'; +import type { TestImagePath } from '../../../../test/TestImagePath.js'; +import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors.js'; +import { getBestKeypointsInRadius } from '../../keypoints/getBestKeypointsInRadius.js'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { Montage } from '../../visualize/Montage.js'; +import { bruteForceOneMatch } from '../bruteForceMatch.js'; test.each([ { diff --git a/src/featureMatching/matching/__tests__/filterEuclideanDistance.test.ts b/src/featureMatching/matching/__tests__/filterEuclideanDistance.test.ts index bebfca132..158d69a7f 100644 --- a/src/featureMatching/matching/__tests__/filterEuclideanDistance.test.ts +++ b/src/featureMatching/matching/__tests__/filterEuclideanDistance.test.ts @@ -1,5 +1,5 @@ -import { Match } from '../bruteForceMatch'; -import { filterEuclideanDistance } from '../filterEuclideanDistance'; +import type { Match } from '../bruteForceMatch.js'; +import { filterEuclideanDistance } from '../filterEuclideanDistance.js'; test('3 matches', () => { const matches: Match[] = [ diff --git a/src/featureMatching/matching/__tests__/filterSmallestDistanceMatches.test.ts b/src/featureMatching/matching/__tests__/filterSmallestDistanceMatches.test.ts index dc89ec94a..192078755 100644 --- a/src/featureMatching/matching/__tests__/filterSmallestDistanceMatches.test.ts +++ b/src/featureMatching/matching/__tests__/filterSmallestDistanceMatches.test.ts @@ -1,5 +1,5 @@ -import { Match } from '../bruteForceMatch'; -import { filterSmallestDistanceMatches } from '../filterSmallestDistanceMatches'; +import type { Match } from '../bruteForceMatch.js'; +import { filterSmallestDistanceMatches } from '../filterSmallestDistanceMatches.js'; test('3 matches', () => { const matches: Match[] = [ diff --git a/src/featureMatching/matching/__tests__/getCrosscheckMatches.test.ts b/src/featureMatching/matching/__tests__/getCrosscheckMatches.test.ts index 8ddeed779..dda1da4de 100644 --- a/src/featureMatching/matching/__tests__/getCrosscheckMatches.test.ts +++ b/src/featureMatching/matching/__tests__/getCrosscheckMatches.test.ts @@ -1,10 +1,10 @@ -import { TestImagePath } from '../../../../test/TestImagePath'; -import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors'; -import { getBestKeypointsInRadius } from '../../keypoints/getBestKeypointsInRadius'; -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { Montage } from '../../visualize/Montage'; -import { Match } from '../bruteForceMatch'; -import { crosscheck, getCrosscheckMatches } from '../getCrosscheckMatches'; +import type { TestImagePath } from '../../../../test/TestImagePath.js'; +import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors.js'; +import { getBestKeypointsInRadius } from '../../keypoints/getBestKeypointsInRadius.js'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { Montage } from '../../visualize/Montage.js'; +import type { Match } from '../bruteForceMatch.js'; +import { crosscheck, getCrosscheckMatches } from '../getCrosscheckMatches.js'; describe('crosscheck', () => { it('all matches are common', () => { diff --git a/src/featureMatching/matching/__tests__/getHammingDistance.test.ts b/src/featureMatching/matching/__tests__/getHammingDistance.test.ts index 225ff4dd8..418e0dcb2 100644 --- a/src/featureMatching/matching/__tests__/getHammingDistance.test.ts +++ b/src/featureMatching/matching/__tests__/getHammingDistance.test.ts @@ -1,6 +1,6 @@ -import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors'; -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { getHammingDistance } from '../getHammingDistance'; +import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors.js'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { getHammingDistance } from '../getHammingDistance.js'; test('distance should be 0', () => { const a = new Uint8Array([0, 1, 0, 0, 0, 0, 0]); diff --git a/src/featureMatching/matching/bruteForceMatch.ts b/src/featureMatching/matching/bruteForceMatch.ts index 1730fd38b..7b64655a5 100644 --- a/src/featureMatching/matching/bruteForceMatch.ts +++ b/src/featureMatching/matching/bruteForceMatch.ts @@ -1,6 +1,6 @@ -import { BriefDescriptor } from '../descriptors/getBriefDescriptors'; +import type { BriefDescriptor } from '../descriptors/getBriefDescriptors.js'; -import { getHammingDistance } from './getHammingDistance'; +import { getHammingDistance } from './getHammingDistance.js'; // todo: implement bruteForceManyMatches -> N best matches for each source descriptor diff --git a/src/featureMatching/matching/filterEuclideanDistance.ts b/src/featureMatching/matching/filterEuclideanDistance.ts index e35e5cb1d..70274ceb2 100644 --- a/src/featureMatching/matching/filterEuclideanDistance.ts +++ b/src/featureMatching/matching/filterEuclideanDistance.ts @@ -1,5 +1,7 @@ -import { FastKeypoint, Match } from '..'; -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; +import type { FastKeypoint } from '../keypoints/getFastKeypoints.js'; + +import type { Match } from './bruteForceMatch.js'; export interface FilterEuclideanDistanceMatchesOptions { /** diff --git a/src/featureMatching/matching/filterSmallestDistanceMatches.ts b/src/featureMatching/matching/filterSmallestDistanceMatches.ts index 06cba4d33..24b5359a9 100644 --- a/src/featureMatching/matching/filterSmallestDistanceMatches.ts +++ b/src/featureMatching/matching/filterSmallestDistanceMatches.ts @@ -1,4 +1,4 @@ -import { Match } from '..'; +import type { Match } from './bruteForceMatch.js'; /** * Use this function to only keep the match from source to destination with diff --git a/src/featureMatching/matching/getCrosscheckMatches.ts b/src/featureMatching/matching/getCrosscheckMatches.ts index 7e6d70cd0..40ea3f1f9 100644 --- a/src/featureMatching/matching/getCrosscheckMatches.ts +++ b/src/featureMatching/matching/getCrosscheckMatches.ts @@ -1,7 +1,11 @@ -import { BriefDescriptor } from '../descriptors/getBriefDescriptors'; -import { sortByDestSource, sortBySourceDest } from '../utils/sortBySourceDest'; +import type { BriefDescriptor } from '../descriptors/getBriefDescriptors.js'; +import { + sortByDestSource, + sortBySourceDest, +} from '../utils/sortBySourceDest.js'; -import { bruteForceOneMatch, Match } from './bruteForceMatch'; +import type { Match } from './bruteForceMatch.js'; +import { bruteForceOneMatch } from './bruteForceMatch.js'; /** * Get the crosscheck matches from the source and destination descriptors. diff --git a/src/featureMatching/matching/getHammingDistance.ts b/src/featureMatching/matching/getHammingDistance.ts index f7946f5db..f2a3be8de 100644 --- a/src/featureMatching/matching/getHammingDistance.ts +++ b/src/featureMatching/matching/getHammingDistance.ts @@ -1,4 +1,4 @@ -import { BriefDescriptor } from '../descriptors/getBriefDescriptors'; +import type { BriefDescriptor } from '../descriptors/getBriefDescriptors.js'; /** * Compute the Hamming distance between two bit strings. diff --git a/src/featureMatching/utils/__tests__/checkBorderDistance.test.ts b/src/featureMatching/utils/__tests__/checkBorderDistance.test.ts index be0dc1279..636d9811b 100644 --- a/src/featureMatching/utils/__tests__/checkBorderDistance.test.ts +++ b/src/featureMatching/utils/__tests__/checkBorderDistance.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { Point } from '../../../geometry'; -import { checkBorderDistance } from '../checkBorderDistance'; +import { Image } from '../../../Image.js'; +import type { Point } from '../../../geometry/index.js'; +import { checkBorderDistance } from '../checkBorderDistance.js'; test('should be true', () => { const size = 7; diff --git a/src/featureMatching/utils/__tests__/compareIntensity.test.ts b/src/featureMatching/utils/__tests__/compareIntensity.test.ts index f57c46b1a..8f26593f2 100644 --- a/src/featureMatching/utils/__tests__/compareIntensity.test.ts +++ b/src/featureMatching/utils/__tests__/compareIntensity.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../../Image'; -import { compareIntensity } from '../compareIntensity'; +import { Image } from '../../../Image.js'; +import { compareIntensity } from '../compareIntensity.js'; test('verify descriptor is correct (descriptorLength = 10)', () => { const size = 5; diff --git a/src/featureMatching/utils/__tests__/extractSquareImage.test.ts b/src/featureMatching/utils/__tests__/extractSquareImage.test.ts index bcf9405a8..01296ef2d 100644 --- a/src/featureMatching/utils/__tests__/extractSquareImage.test.ts +++ b/src/featureMatching/utils/__tests__/extractSquareImage.test.ts @@ -1,4 +1,4 @@ -import { extractSquareImage } from '../extractSquareImage'; +import { extractSquareImage } from '../extractSquareImage.js'; test('7x7 image, first origin', () => { const image = testUtils.createGreyImage([ diff --git a/src/featureMatching/utils/__tests__/getColors.test.ts b/src/featureMatching/utils/__tests__/getColors.test.ts index 0e2d8e2b7..fd0ac6fc7 100644 --- a/src/featureMatching/utils/__tests__/getColors.test.ts +++ b/src/featureMatching/utils/__tests__/getColors.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../../Image'; -import { getColors } from '../getColors'; +import { Image } from '../../../Image.js'; +import { getColors } from '../getColors.js'; test('generate 10 blue shades', () => { const side = 100; diff --git a/src/featureMatching/utils/__tests__/getGaussianPoints.test.ts b/src/featureMatching/utils/__tests__/getGaussianPoints.test.ts index f429d2cb8..61bc09d0b 100644 --- a/src/featureMatching/utils/__tests__/getGaussianPoints.test.ts +++ b/src/featureMatching/utils/__tests__/getGaussianPoints.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { Point } from '../../../geometry'; -import { getGaussianPoints, getGaussianValues } from '../getGaussianPoints'; +import { Image } from '../../../Image.js'; +import type { Point } from '../../../geometry/index.js'; +import { getGaussianPoints, getGaussianValues } from '../getGaussianPoints.js'; function drawGaussianPoints(image: Image, points: Point[]): Image { const center = image.getCoordinates('center'); diff --git a/src/featureMatching/utils/__tests__/getKeypointColor.test.ts b/src/featureMatching/utils/__tests__/getKeypointColor.test.ts index 01ef5edc1..fe70e20b5 100644 --- a/src/featureMatching/utils/__tests__/getKeypointColor.test.ts +++ b/src/featureMatching/utils/__tests__/getKeypointColor.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { getColors } from '../getColors'; -import { getKeypointColor } from '../getKeypointColor'; +import { Image } from '../../../Image.js'; +import { getColors } from '../getColors.js'; +import { getKeypointColor } from '../getKeypointColor.js'; const origin = { column: 0, row: 0 }; diff --git a/src/featureMatching/utils/__tests__/getMatchColor.test.ts b/src/featureMatching/utils/__tests__/getMatchColor.test.ts index b159fff35..3c286a11b 100644 --- a/src/featureMatching/utils/__tests__/getMatchColor.test.ts +++ b/src/featureMatching/utils/__tests__/getMatchColor.test.ts @@ -1,7 +1,7 @@ -import { Image } from '../../../Image'; -import { Match } from '../../matching/bruteForceMatch'; -import { getColors } from '../getColors'; -import { getMatchColor } from '../getMatchColor'; +import { Image } from '../../../Image.js'; +import type { Match } from '../../matching/bruteForceMatch.js'; +import { getColors } from '../getColors.js'; +import { getMatchColor } from '../getMatchColor.js'; test('matches should all have a different color', () => { const image = new Image(5, 5); diff --git a/src/featureMatching/utils/__tests__/sortByDistance.test.ts b/src/featureMatching/utils/__tests__/sortByDistance.test.ts index cd697b66a..0111ff04a 100644 --- a/src/featureMatching/utils/__tests__/sortByDistance.test.ts +++ b/src/featureMatching/utils/__tests__/sortByDistance.test.ts @@ -1,5 +1,5 @@ -import { Match } from '../../matching/bruteForceMatch'; -import { sortByDistance } from '../sortByDistance'; +import type { Match } from '../../matching/bruteForceMatch.js'; +import { sortByDistance } from '../sortByDistance.js'; it('should sort by source then dest', () => { const matches: Match[] = [ diff --git a/src/featureMatching/utils/__tests__/sortBySourceDest.test.ts b/src/featureMatching/utils/__tests__/sortBySourceDest.test.ts index 6ff39d0b0..e82e7525a 100644 --- a/src/featureMatching/utils/__tests__/sortBySourceDest.test.ts +++ b/src/featureMatching/utils/__tests__/sortBySourceDest.test.ts @@ -1,5 +1,5 @@ -import { Match } from '../../matching/bruteForceMatch'; -import { sortByDestSource, sortBySourceDest } from '../sortBySourceDest'; +import type { Match } from '../../matching/bruteForceMatch.js'; +import { sortByDestSource, sortBySourceDest } from '../sortBySourceDest.js'; test('should sort by source then dest', () => { const matches: Match[] = [ diff --git a/src/featureMatching/utils/checkBorderDistance.ts b/src/featureMatching/utils/checkBorderDistance.ts index 1c8041aa2..0e314ecd8 100644 --- a/src/featureMatching/utils/checkBorderDistance.ts +++ b/src/featureMatching/utils/checkBorderDistance.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; /** * Check that a point is not too close to the border of the image. diff --git a/src/featureMatching/utils/compareIntensity.ts b/src/featureMatching/utils/compareIntensity.ts index 3da3de25f..1cd0e762b 100644 --- a/src/featureMatching/utils/compareIntensity.ts +++ b/src/featureMatching/utils/compareIntensity.ts @@ -1,6 +1,6 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; -import { sum } from '../../utils/geometry/points'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; +import { sum } from '../../utils/geometry/points.js'; export interface CompareIntensityOptions { /** diff --git a/src/featureMatching/utils/extractSquareImage.ts b/src/featureMatching/utils/extractSquareImage.ts index 6e227d033..91bae3b88 100644 --- a/src/featureMatching/utils/extractSquareImage.ts +++ b/src/featureMatching/utils/extractSquareImage.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; /** * Crop the source image to given dimensions around the origin. diff --git a/src/featureMatching/utils/getColors.ts b/src/featureMatching/utils/getColors.ts index 88e093ef6..e92e83637 100644 --- a/src/featureMatching/utils/getColors.ts +++ b/src/featureMatching/utils/getColors.ts @@ -1,6 +1,6 @@ -import { Image } from '../../Image'; -import { getClampFromTo } from '../../utils/clamp'; -import { GetColorsOptions } from '../featureMatching.types'; +import type { Image } from '../../Image.js'; +import { getClampFromTo } from '../../utils/clamp.js'; +import type { GetColorsOptions } from '../featureMatching.types.js'; /** * Generate an array of colors to draw the keypoints depending on their score or the matches depending on the distance. diff --git a/src/featureMatching/utils/getGaussianPoints.ts b/src/featureMatching/utils/getGaussianPoints.ts index 75ad077ba..b04969c6a 100644 --- a/src/featureMatching/utils/getGaussianPoints.ts +++ b/src/featureMatching/utils/getGaussianPoints.ts @@ -1,8 +1,8 @@ import { createRandomArray } from 'ml-spectra-processing'; -import { Point } from '../../geometry'; -import { getClampFromTo } from '../../utils/clamp'; -import { GetGaussianPointsOptions } from '../../utils/utils.types'; +import type { Point } from '../../geometry/index.js'; +import { getClampFromTo } from '../../utils/clamp.js'; +import type { GetGaussianPointsOptions } from '../../utils/utils.types.js'; /** * Get the coordinates of random points inside of the given dimensions, spread with a diff --git a/src/featureMatching/utils/getKeypointColor.ts b/src/featureMatching/utils/getKeypointColor.ts index 757543d58..c184e3340 100644 --- a/src/featureMatching/utils/getKeypointColor.ts +++ b/src/featureMatching/utils/getKeypointColor.ts @@ -1,4 +1,4 @@ -import { FastKeypoint } from '../keypoints/getFastKeypoints'; +import type { FastKeypoint } from '../keypoints/getFastKeypoints.js'; /** * Get the shade the keypoint with given index should have (the color is an indicator diff --git a/src/featureMatching/utils/getMatchColor.ts b/src/featureMatching/utils/getMatchColor.ts index b7b588a58..1113afb53 100644 --- a/src/featureMatching/utils/getMatchColor.ts +++ b/src/featureMatching/utils/getMatchColor.ts @@ -1,4 +1,4 @@ -import { Match } from '../matching/bruteForceMatch'; +import type { Match } from '../matching/bruteForceMatch.js'; /** * Get the shade of the match with given index (the color is an indicator diff --git a/src/featureMatching/utils/sortByDistance.ts b/src/featureMatching/utils/sortByDistance.ts index 10e8e3d0b..4f3a6369c 100644 --- a/src/featureMatching/utils/sortByDistance.ts +++ b/src/featureMatching/utils/sortByDistance.ts @@ -1,4 +1,4 @@ -import { Match } from '../matching/bruteForceMatch'; +import type { Match } from '../matching/bruteForceMatch.js'; /** * Source array of matches by ascending distance. diff --git a/src/featureMatching/utils/sortBySourceDest.ts b/src/featureMatching/utils/sortBySourceDest.ts index 26815de1a..1bd0c9c18 100644 --- a/src/featureMatching/utils/sortBySourceDest.ts +++ b/src/featureMatching/utils/sortBySourceDest.ts @@ -1,4 +1,4 @@ -import { Match } from '../matching/bruteForceMatch'; +import type { Match } from '../matching/bruteForceMatch.js'; /** * Sort array of matches by source index and then destination index. diff --git a/src/featureMatching/visualize/Montage.ts b/src/featureMatching/visualize/Montage.ts index bb7534859..a923290f7 100644 --- a/src/featureMatching/visualize/Montage.ts +++ b/src/featureMatching/visualize/Montage.ts @@ -1,11 +1,13 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; -import { FastKeypoint } from '../keypoints/getFastKeypoints'; -import { Match } from '../matching/bruteForceMatch'; - -import { drawKeypoints, DrawKeypointsOptions } from './drawKeypoints'; -import { drawMatches, DrawMatchesOptions } from './drawMatches'; -import { scaleKeypoints } from './scaleKeypoints'; +import { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; +import type { FastKeypoint } from '../keypoints/getFastKeypoints.js'; +import type { Match } from '../matching/bruteForceMatch.js'; + +import type { DrawKeypointsOptions } from './drawKeypoints.js'; +import { drawKeypoints } from './drawKeypoints.js'; +import type { DrawMatchesOptions } from './drawMatches.js'; +import { drawMatches } from './drawMatches.js'; +import { scaleKeypoints } from './scaleKeypoints.js'; export const MontageDisposition = { HORIZONTAL: 'horizontal', diff --git a/src/featureMatching/visualize/__tests__/Montage.test.ts b/src/featureMatching/visualize/__tests__/Montage.test.ts index 5a1a808a8..93809e8a5 100644 --- a/src/featureMatching/visualize/__tests__/Montage.test.ts +++ b/src/featureMatching/visualize/__tests__/Montage.test.ts @@ -1,7 +1,7 @@ -import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors'; -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { bruteForceOneMatch } from '../../matching/bruteForceMatch'; -import { Montage } from '../Montage'; +import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors.js'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { bruteForceOneMatch } from '../../matching/bruteForceMatch.js'; +import { Montage } from '../Montage.js'; const source = testUtils.load('featureMatching/alphabet.jpg'); const grey = source.convertColor('GREY'); diff --git a/src/featureMatching/visualize/__tests__/drawKeypoints.test.ts b/src/featureMatching/visualize/__tests__/drawKeypoints.test.ts index 1f2829b92..0266a9334 100644 --- a/src/featureMatching/visualize/__tests__/drawKeypoints.test.ts +++ b/src/featureMatching/visualize/__tests__/drawKeypoints.test.ts @@ -1,5 +1,5 @@ -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { drawKeypoints } from '../drawKeypoints'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { drawKeypoints } from '../drawKeypoints.js'; const image = testUtils.load('various/alphabet.jpg'); const grey = image.convertColor('GREY'); diff --git a/src/featureMatching/visualize/__tests__/drawMatches.test.ts b/src/featureMatching/visualize/__tests__/drawMatches.test.ts index ba2ba3801..857361815 100644 --- a/src/featureMatching/visualize/__tests__/drawMatches.test.ts +++ b/src/featureMatching/visualize/__tests__/drawMatches.test.ts @@ -1,9 +1,9 @@ -import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors'; -import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints'; -import { bruteForceOneMatch } from '../../matching/bruteForceMatch'; -import { Montage } from '../Montage'; -import { DrawKeypointsOptions } from '../drawKeypoints'; -import { drawMatches } from '../drawMatches'; +import { getBriefDescriptors } from '../../descriptors/getBriefDescriptors.js'; +import { getOrientedFastKeypoints } from '../../keypoints/getOrientedFastKeypoints.js'; +import { bruteForceOneMatch } from '../../matching/bruteForceMatch.js'; +import { Montage } from '../Montage.js'; +import type { DrawKeypointsOptions } from '../drawKeypoints.js'; +import { drawMatches } from '../drawMatches.js'; test('alphabet image as source and destination, nbKeypoint = 10', () => { const source = testUtils.load('various/alphabet.jpg'); diff --git a/src/featureMatching/visualize/__tests__/overlapImages.test.ts b/src/featureMatching/visualize/__tests__/overlapImages.test.ts index a2c52d19f..6cc3ea6a9 100644 --- a/src/featureMatching/visualize/__tests__/overlapImages.test.ts +++ b/src/featureMatching/visualize/__tests__/overlapImages.test.ts @@ -1,4 +1,4 @@ -import { overlapImages } from '../overlapImages'; +import { overlapImages } from '../overlapImages.js'; test('two triangles', () => { const source = testUtils.load('featureMatching/polygons/scaleneTriangle.png'); diff --git a/src/featureMatching/visualize/__tests__/scaleKeypoints.test.ts b/src/featureMatching/visualize/__tests__/scaleKeypoints.test.ts index 1b745e5b0..9a8840f62 100644 --- a/src/featureMatching/visualize/__tests__/scaleKeypoints.test.ts +++ b/src/featureMatching/visualize/__tests__/scaleKeypoints.test.ts @@ -1,5 +1,5 @@ -import { FastKeypoint } from '../../keypoints/getFastKeypoints'; -import { scaleKeypoints } from '../scaleKeypoints'; +import type { FastKeypoint } from '../../keypoints/getFastKeypoints.js'; +import { scaleKeypoints } from '../scaleKeypoints.js'; test('scale = 1', () => { const keypoints: FastKeypoint[] = [ diff --git a/src/featureMatching/visualize/drawKeypoints.ts b/src/featureMatching/visualize/drawKeypoints.ts index ba0133a1f..3df0439d2 100644 --- a/src/featureMatching/visualize/drawKeypoints.ts +++ b/src/featureMatching/visualize/drawKeypoints.ts @@ -1,12 +1,12 @@ -import { Image } from '../../Image'; -import { Point } from '../../geometry'; -import { sum } from '../../utils/geometry/points'; -import { getOutputImage } from '../../utils/getOutputImage'; -import { GetColorsOptions } from '../featureMatching.types'; -import { FastKeypoint } from '../keypoints/getFastKeypoints'; -import { OrientedFastKeypoint } from '../keypoints/getOrientedFastKeypoints'; -import { getColors } from '../utils/getColors'; -import { getKeypointColor } from '../utils/getKeypointColor'; +import type { Image } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; +import { sum } from '../../utils/geometry/points.js'; +import { getOutputImage } from '../../utils/getOutputImage.js'; +import type { GetColorsOptions } from '../featureMatching.types.js'; +import type { FastKeypoint } from '../keypoints/getFastKeypoints.js'; +import type { OrientedFastKeypoint } from '../keypoints/getOrientedFastKeypoints.js'; +import { getColors } from '../utils/getColors.js'; +import { getKeypointColor } from '../utils/getKeypointColor.js'; export interface DrawKeypointsOptions { /** diff --git a/src/featureMatching/visualize/drawMatches.ts b/src/featureMatching/visualize/drawMatches.ts index 64f7f87bc..554ecc301 100644 --- a/src/featureMatching/visualize/drawMatches.ts +++ b/src/featureMatching/visualize/drawMatches.ts @@ -1,13 +1,13 @@ -import { Image } from '../../Image'; -import { GetColorsOptions } from '../featureMatching.types'; -import { FastKeypoint } from '../keypoints/getFastKeypoints'; -import { Match } from '../matching/bruteForceMatch'; -import { getColors } from '../utils/getColors'; -import { getMatchColor } from '../utils/getMatchColor'; -import { sortByDistance } from '../utils/sortByDistance'; +import type { Image } from '../../Image.js'; +import type { GetColorsOptions } from '../featureMatching.types.js'; +import type { FastKeypoint } from '../keypoints/getFastKeypoints.js'; +import type { Match } from '../matching/bruteForceMatch.js'; +import { getColors } from '../utils/getColors.js'; +import { getMatchColor } from '../utils/getMatchColor.js'; +import { sortByDistance } from '../utils/sortByDistance.js'; -import { Montage } from './Montage'; -import { scaleKeypoints } from './scaleKeypoints'; +import type { Montage } from './Montage.js'; +import { scaleKeypoints } from './scaleKeypoints.js'; export interface DrawMatchesOptions { /** diff --git a/src/featureMatching/visualize/overlapImages.ts b/src/featureMatching/visualize/overlapImages.ts index 28b1fa616..9787a984e 100644 --- a/src/featureMatching/visualize/overlapImages.ts +++ b/src/featureMatching/visualize/overlapImages.ts @@ -1,4 +1,7 @@ -import { Image, ImageColorModel, ImageCoordinates, Point, merge } from '../..'; +import { Image, ImageCoordinates } from '../../Image.js'; +import type { Point } from '../../geometry/index.js'; +import { merge } from '../../operations/index.js'; +import { ImageColorModel } from '../../utils/constants/colorModels.js'; export interface OverlapImageOptions { /** diff --git a/src/featureMatching/visualize/scaleKeypoints.ts b/src/featureMatching/visualize/scaleKeypoints.ts index e97db0254..b664921e1 100644 --- a/src/featureMatching/visualize/scaleKeypoints.ts +++ b/src/featureMatching/visualize/scaleKeypoints.ts @@ -1,4 +1,4 @@ -import { FastKeypoint } from '../keypoints/getFastKeypoints'; +import type { FastKeypoint } from '../keypoints/getFastKeypoints.js'; /** * Scales the coordinates of the keypoints. diff --git a/src/filters/__tests__/convolution.test.ts b/src/filters/__tests__/convolution.test.ts index a3b455141..09b27bd23 100644 --- a/src/filters/__tests__/convolution.test.ts +++ b/src/filters/__tests__/convolution.test.ts @@ -1,9 +1,11 @@ import { Matrix } from 'ml-matrix'; -import { rawDirectConvolution } from '..'; -import { getClamp } from '../../utils/clamp'; -import { getBorderInterpolation } from '../../utils/interpolateBorder'; -import { computeConvolutionValue } from '../convolution'; +import { getClamp } from '../../utils/clamp.js'; +import { getBorderInterpolation } from '../../utils/interpolateBorder.js'; +import { + computeConvolutionValue, + rawDirectConvolution, +} from '../convolution.js'; describe('convolution functions', () => { it('separable convolution compared to opencv', () => { diff --git a/src/filters/__tests__/flip.test.ts b/src/filters/__tests__/flip.test.ts index 56191c527..db8a23b38 100644 --- a/src/filters/__tests__/flip.test.ts +++ b/src/filters/__tests__/flip.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; test('invert with out parameter', () => { const out = new Image(2, 2); diff --git a/src/filters/__tests__/flipX.test.ts b/src/filters/__tests__/flipX.test.ts index 6614f5240..ef253654d 100644 --- a/src/filters/__tests__/flipX.test.ts +++ b/src/filters/__tests__/flipX.test.ts @@ -1,4 +1,4 @@ -import flipX from '../flipX'; +import flipX from '../flipX.js'; test('should flip pixels horizontally of all RGBA components for a [2,1] image', () => { const image = testUtils.createRgbaImage([[1, 2, 3, 4, 5, 6, 7, 8]]); diff --git a/src/filters/__tests__/flipY.test.ts b/src/filters/__tests__/flipY.test.ts index 22a5e17a8..1b51819e8 100644 --- a/src/filters/__tests__/flipY.test.ts +++ b/src/filters/__tests__/flipY.test.ts @@ -1,4 +1,4 @@ -import flipY from '../flipY'; +import flipY from '../flipY.js'; test('should flip pixels vertically of all RGBA components for a [2,1] image', () => { const image = testUtils.createRgbaImage([[1, 2, 3, 4, 5, 6, 7, 8]]); diff --git a/src/filters/__tests__/gaussianBlur.test.ts b/src/filters/__tests__/gaussianBlur.test.ts index dfd9fa669..66d08bc4e 100644 --- a/src/filters/__tests__/gaussianBlur.test.ts +++ b/src/filters/__tests__/gaussianBlur.test.ts @@ -1,8 +1,8 @@ -import { +import type { GaussianBlurOptions, - gaussianBlur, GaussianBlurSigmaOptions, -} from '../gaussianBlur'; +} from '../gaussianBlur.js'; +import { gaussianBlur } from '../gaussianBlur.js'; test('symmetrical kernel, should return the kernel itself', () => { const image = testUtils.createGreyImage([ diff --git a/src/filters/__tests__/increaseContrast.test.ts b/src/filters/__tests__/increaseContrast.test.ts index 58797f698..f0180e60b 100644 --- a/src/filters/__tests__/increaseContrast.test.ts +++ b/src/filters/__tests__/increaseContrast.test.ts @@ -1,4 +1,4 @@ -import { increaseContrast } from '../increaseContrast'; +import { increaseContrast } from '../increaseContrast.js'; test('3x1 rgba image, custom output min and max', () => { const image = testUtils.createRgbaImage([ diff --git a/src/filters/__tests__/invert.test.ts b/src/filters/__tests__/invert.test.ts index cd59113b4..31fa3e8f3 100644 --- a/src/filters/__tests__/invert.test.ts +++ b/src/filters/__tests__/invert.test.ts @@ -1,5 +1,5 @@ -import { Mask } from '../..'; -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; +import { Mask } from '../../Mask.js'; describe('image is an Image', () => { it('invert an RGB image', () => { diff --git a/src/filters/__tests__/pixelate.test.ts b/src/filters/__tests__/pixelate.test.ts index 655ec6309..a0670df6a 100644 --- a/src/filters/__tests__/pixelate.test.ts +++ b/src/filters/__tests__/pixelate.test.ts @@ -1,4 +1,4 @@ -import { pixelate } from '../pixelate'; +import { pixelate } from '../pixelate.js'; describe('pixelization of images', () => { it('pixelate a simple grey image', () => { diff --git a/src/filters/and.ts b/src/filters/and.ts index 7e80e20a7..b6086ff83 100644 --- a/src/filters/and.ts +++ b/src/filters/and.ts @@ -1,5 +1,5 @@ -import { Mask } from '..'; -import { maskToOutputMask } from '../utils/getOutputImage'; +import type { Mask } from '../Mask.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; export interface AndOptions { /** diff --git a/src/filters/blur.ts b/src/filters/blur.ts index 177df45fc..468dbc7c9 100644 --- a/src/filters/blur.ts +++ b/src/filters/blur.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import { BorderType } from '../utils/interpolateBorder'; +import type { Image } from '../Image.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; -import { separableConvolution } from './convolution'; +import { separableConvolution } from './convolution.js'; export interface BlurOptions { /** diff --git a/src/filters/convolution.ts b/src/filters/convolution.ts index 1a19505e8..42ddad22b 100644 --- a/src/filters/convolution.ts +++ b/src/filters/convolution.ts @@ -3,17 +3,18 @@ import { DirectConvolution, } from 'ml-convolution'; -import { Image } from '../Image'; -import { extendBorders } from '../operations/extendBorders'; -import { getClamp } from '../utils/clamp'; -import { getIndex } from '../utils/getIndex'; -import { getOutputImage } from '../utils/getOutputImage'; -import { BorderType, getBorderInterpolation } from '../utils/interpolateBorder'; -import { round } from '../utils/round'; -import { +import { Image } from '../Image.js'; +import { extendBorders } from '../operations/extendBorders.js'; +import { getClamp } from '../utils/clamp.js'; +import { getIndex } from '../utils/getIndex.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; +import { getBorderInterpolation } from '../utils/interpolateBorder.js'; +import { round } from '../utils/round.js'; +import type { BorderInterpolationFunction, ClampFunction, -} from '../utils/utils.types'; +} from '../utils/utils.types.js'; export interface ConvolutionOptions { /** diff --git a/src/filters/derivativeFilter.ts b/src/filters/derivativeFilter.ts index 9d2a2bd59..c6bf38bd6 100644 --- a/src/filters/derivativeFilter.ts +++ b/src/filters/derivativeFilter.ts @@ -1,4 +1,6 @@ -import { BitDepth, Image } from '..'; +import { match } from 'ts-pattern'; + +import type { BitDepth, Image } from '../Image.js'; import { PREWITT_X, PREWITT_Y, @@ -6,8 +8,8 @@ import { SCHARR_Y, SOBEL_X, SOBEL_Y, -} from '../utils/constants/kernels'; -import type { BorderType } from '../utils/interpolateBorder'; +} from '../utils/constants/kernels.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; export const DerivativeFilter = { SOBEL: 'sobel', @@ -55,23 +57,15 @@ export function derivativeFilter( options: DerivativeFilterOptions = {}, ): Image { const { filter = 'sobel' } = options; - let kernelX = SOBEL_X; - let kernelY = SOBEL_Y; - switch (filter) { - case 'sobel': - break; - case 'scharr': - kernelX = SCHARR_X; - kernelY = SCHARR_Y; - break; - case 'prewitt': - kernelX = PREWITT_X; - kernelY = PREWITT_Y; - break; - default: - throw new RangeError(`invalid derivative filter: ${filter}`); - } + const kernels = match< + DerivativeFilter, + { kernelX: number[][]; kernelY: number[][] } + >(filter) + .with('sobel', () => ({ kernelX: SOBEL_X, kernelY: SOBEL_Y })) + .with('scharr', () => ({ kernelX: SCHARR_X, kernelY: SCHARR_Y })) + .with('prewitt', () => ({ kernelX: PREWITT_X, kernelY: PREWITT_Y })) + .exhaustive(); - return image.gradientFilter({ kernelX, kernelY, ...options }); + return image.gradientFilter({ ...kernels, ...options }); } diff --git a/src/filters/flip.ts b/src/filters/flip.ts index 83af7c427..562c44bc2 100644 --- a/src/filters/flip.ts +++ b/src/filters/flip.ts @@ -1,8 +1,8 @@ -import { Image } from '../Image'; -import { getOutputImage } from '../utils/getOutputImage'; +import type { Image } from '../Image.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; -import flipX from './flipX'; -import flipY from './flipY'; +import flipX from './flipX.js'; +import flipY from './flipY.js'; export interface FlipOptions { /** diff --git a/src/filters/flipX.ts b/src/filters/flipX.ts index 160ebaefd..2c4a3a230 100644 --- a/src/filters/flipX.ts +++ b/src/filters/flipX.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; /** * Apply a flipX filter to an image. diff --git a/src/filters/flipY.ts b/src/filters/flipY.ts index 1d60c927f..1a68ff393 100644 --- a/src/filters/flipY.ts +++ b/src/filters/flipY.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; /** * Apply a flipY filter to an image. diff --git a/src/filters/gaussianBlur.ts b/src/filters/gaussianBlur.ts index 9b4f7526b..b1dceef2e 100644 --- a/src/filters/gaussianBlur.ts +++ b/src/filters/gaussianBlur.ts @@ -1,8 +1,8 @@ -import { Image } from '../Image'; -import { getRadius } from '../utils/getRadius'; -import type { BorderType } from '../utils/interpolateBorder'; +import type { Image } from '../Image.js'; +import { getRadius } from '../utils/getRadius.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; -import { separableConvolution } from './convolution'; +import { separableConvolution } from './convolution.js'; interface GaussianBlurBaseOptions { /** diff --git a/src/filters/gradientFilter.ts b/src/filters/gradientFilter.ts index e08f2ec45..928058326 100644 --- a/src/filters/gradientFilter.ts +++ b/src/filters/gradientFilter.ts @@ -1,6 +1,7 @@ -import { BitDepth, Image } from '..'; -import type { BorderType } from '../utils/interpolateBorder'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { BitDepth } from '../Image.js'; +import { Image } from '../Image.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface GradientFilterBaseOptions { /** diff --git a/src/filters/hypotenuse.ts b/src/filters/hypotenuse.ts index e4b3b5c57..3f536795c 100644 --- a/src/filters/hypotenuse.ts +++ b/src/filters/hypotenuse.ts @@ -1,7 +1,7 @@ -import { Image } from '..'; -import { getOutputImage } from '../utils/getOutputImage'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateChannels } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateChannels } from '../utils/validators/validators.js'; export interface HypotenuseOptions { /** @@ -54,11 +54,7 @@ export function hypotenuse( otherImage.getValueByIndex(i, channel), ); - newImage.setValueByIndex( - i, - channel, - value > newImage.maxValue ? newImage.maxValue : value, - ); + newImage.setValueByIndex(i, channel, Math.min(value, newImage.maxValue)); } } diff --git a/src/filters/increaseContrast.ts b/src/filters/increaseContrast.ts index b40d8cf13..c184b6d73 100644 --- a/src/filters/increaseContrast.ts +++ b/src/filters/increaseContrast.ts @@ -1,6 +1,6 @@ -import { Image } from '../Image'; -import { ImageColorModel } from '../utils/constants/colorModels'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import { ImageColorModel } from '../utils/constants/colorModels.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface IncreaseContrastOptions { /** diff --git a/src/filters/index.ts b/src/filters/index.ts index 6edae3a1b..258d18e03 100644 --- a/src/filters/index.ts +++ b/src/filters/index.ts @@ -1,14 +1,14 @@ -export * from './and'; -export * from './blur'; -export * from './convolution'; -export * from './derivativeFilter'; -export * from './increaseContrast'; -export * from './gaussianBlur'; -export * from './gradientFilter'; -export * from './hypotenuse'; -export * from './invert'; -export * from './level'; -export * from './or'; -export * from './flip'; -export * from './medianFilter'; -export * from './pixelate'; +export * from './and.js'; +export * from './blur.js'; +export * from './convolution.js'; +export * from './derivativeFilter.js'; +export * from './increaseContrast.js'; +export * from './gaussianBlur.js'; +export * from './gradientFilter.js'; +export * from './hypotenuse.js'; +export * from './invert.js'; +export * from './level.js'; +export * from './or.js'; +export * from './flip.js'; +export * from './medianFilter.js'; +export * from './pixelate.js'; diff --git a/src/filters/invert.ts b/src/filters/invert.ts index c401cb37a..bd5e70843 100644 --- a/src/filters/invert.ts +++ b/src/filters/invert.ts @@ -1,6 +1,7 @@ -import { copyAlpha, Mask } from '..'; -import { Image } from '../Image'; -import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { copyAlpha } from '../operations/index.js'; +import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage.js'; export interface InvertOptions { /** diff --git a/src/filters/level.ts b/src/filters/level.ts index 09b099285..21e5562cb 100644 --- a/src/filters/level.ts +++ b/src/filters/level.ts @@ -1,8 +1,8 @@ -import { Image } from '../Image'; -import { getClamp } from '../utils/clamp'; -import { getOutputImage } from '../utils/getOutputImage'; -import checkProcessable from '../utils/validators/checkProcessable'; -import { validateChannels } from '../utils/validators/validators'; +import type { Image } from '../Image.js'; +import { getClamp } from '../utils/clamp.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; +import { validateChannels } from '../utils/validators/validators.js'; export interface LevelOptions { /** diff --git a/src/filters/medianFilter.ts b/src/filters/medianFilter.ts index a4998d1a5..8c7577d8f 100644 --- a/src/filters/medianFilter.ts +++ b/src/filters/medianFilter.ts @@ -1,8 +1,9 @@ import { xMedian } from 'ml-spectra-processing'; -import { Image } from '../Image'; -import { getBorderInterpolation, BorderType } from '../utils/interpolateBorder'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; +import { getBorderInterpolation } from '../utils/interpolateBorder.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface MedianFilterOptions { /** diff --git a/src/filters/or.ts b/src/filters/or.ts index 5f82cd655..8dfbdff31 100644 --- a/src/filters/or.ts +++ b/src/filters/or.ts @@ -1,5 +1,5 @@ -import { Mask } from '..'; -import { maskToOutputMask } from '../utils/getOutputImage'; +import type { Mask } from '../Mask.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; export interface OrOptions { /** diff --git a/src/filters/pixelate.ts b/src/filters/pixelate.ts index 6e0bf1b08..5265b038f 100644 --- a/src/filters/pixelate.ts +++ b/src/filters/pixelate.ts @@ -1,8 +1,9 @@ import { xMedian } from 'ml-spectra-processing'; -import { Image, Point } from '..'; -import { getOutputImage } from '../utils/getOutputImage'; -import { assertUnreachable } from '../utils/validators/assert'; +import type { Image } from '../Image.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { assertUnreachable } from '../utils/validators/assert.js'; export interface PixelateOptions { /** diff --git a/src/geometry/__tests__/resize.test.ts b/src/geometry/__tests__/resize.test.ts index 1ffede5fb..904700afd 100644 --- a/src/geometry/__tests__/resize.test.ts +++ b/src/geometry/__tests__/resize.test.ts @@ -1,7 +1,7 @@ import path from 'node:path'; -import { Image } from '../../Image'; -import { write } from '../../save'; +import type { Image } from '../../Image.js'; +import { write } from '../../save/index.js'; async function writeDebug(resized: Image, type: string) { // @ts-expect-error Dynamic string. diff --git a/src/geometry/__tests__/transformRotate.test.ts b/src/geometry/__tests__/transformRotate.test.ts index 997f788b0..b6ea407a0 100644 --- a/src/geometry/__tests__/transformRotate.test.ts +++ b/src/geometry/__tests__/transformRotate.test.ts @@ -1,5 +1,5 @@ -import { transformRotate } from '..'; -import { encodePng } from '../../save'; +import { encodePng } from '../../save/index.js'; +import { transformRotate } from '../transformRotate.js'; test('rotate + scale compared to opencv (nearest)', () => { const img = testUtils.load('opencv/test.png'); diff --git a/src/geometry/index.ts b/src/geometry/index.ts index a76a0b85e..0f33f8335 100644 --- a/src/geometry/index.ts +++ b/src/geometry/index.ts @@ -1,5 +1,5 @@ -export * from './resize'; -export * from './rotate'; -export * from './transform'; -export * from './transformRotate'; -export type { Point } from '../utils/geometry/points'; +export * from './resize.js'; +export * from './rotate.js'; +export * from './transform.js'; +export * from './transformRotate.js'; +export type { Point } from '../utils/geometry/points.js'; diff --git a/src/geometry/resize.ts b/src/geometry/resize.ts index 4ed700062..1309d959f 100644 --- a/src/geometry/resize.ts +++ b/src/geometry/resize.ts @@ -1,9 +1,9 @@ -import { Image } from '../Image'; -import { BorderType } from '../utils/interpolateBorder'; -import { InterpolationType } from '../utils/interpolatePixel'; -import { assert } from '../utils/validators/assert'; +import type { Image } from '../Image.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; +import type { InterpolationType } from '../utils/interpolatePixel.js'; +import { assert } from '../utils/validators/assert.js'; -import { transform } from './transform'; +import { transform } from './transform.js'; export interface ResizeOptions { /** diff --git a/src/geometry/rotate.ts b/src/geometry/rotate.ts index 6f7c86c00..de45d6cb0 100644 --- a/src/geometry/rotate.ts +++ b/src/geometry/rotate.ts @@ -1,4 +1,4 @@ -import { Image } from '../Image'; +import { Image } from '../Image.js'; export type RotateAngle = 90 | 180 | 270 | -90 | -180 | -270; diff --git a/src/geometry/transform.ts b/src/geometry/transform.ts index 67ef53846..ccd08d833 100644 --- a/src/geometry/transform.ts +++ b/src/geometry/transform.ts @@ -1,12 +1,11 @@ import { inverse, Matrix } from 'ml-matrix'; -import { Image } from '../Image'; -import { getClamp } from '../utils/clamp'; -import { BorderType, getBorderInterpolation } from '../utils/interpolateBorder'; -import { - getInterpolationFunction, - InterpolationType, -} from '../utils/interpolatePixel'; +import { Image } from '../Image.js'; +import { getClamp } from '../utils/clamp.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; +import { getBorderInterpolation } from '../utils/interpolateBorder.js'; +import type { InterpolationType } from '../utils/interpolatePixel.js'; +import { getInterpolationFunction } from '../utils/interpolatePixel.js'; export interface TransformOptions { /** diff --git a/src/geometry/transformRotate.ts b/src/geometry/transformRotate.ts index 9e9ed16fb..86875c080 100644 --- a/src/geometry/transformRotate.ts +++ b/src/geometry/transformRotate.ts @@ -1,7 +1,8 @@ -import { Image, ImageCoordinates } from '../Image'; -import { Point } from '../utils/geometry/points'; +import type { Image, ImageCoordinates } from '../Image.js'; +import type { Point } from '../utils/geometry/points.js'; -import { transform, TransformOptions } from './transform'; +import type { TransformOptions } from './transform.js'; +import { transform } from './transform.js'; export interface TransformRotateOptions extends TransformOptions { /** diff --git a/src/index.ts b/src/index.ts index 759884804..f142cbf3e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,24 +1,24 @@ -export * from './align'; -export * from './compare'; -export * from './compute'; -export * from './correctColor'; -export * from './draw'; -export * from './featureMatching'; -export * from './filters'; -export * from './geometry'; -export * from './utils/geometry'; -export * from './Image'; -export * from './load'; -export * from './Mask'; -export * from './maskAnalysis'; -export * from './morphology'; -export * from './operations'; -export * from './roi'; -export * from './save'; -export * from './Stack'; -export { decodeStack } from './stack/load/decodeStack'; -export * from './utils/utils.types'; -export * from './utils/constants/channelLabels'; -export * from './utils/constants/colorModels'; -export { BorderType } from './utils/interpolateBorder'; -export { InterpolationType } from './utils/interpolatePixel'; +export * from './align/index.js'; +export * from './compare/index.js'; +export * from './compute/index.js'; +export * from './correctColor/index.js'; +export * from './draw/index.js'; +export * from './featureMatching/index.js'; +export * from './filters/index.js'; +export * from './geometry/index.js'; +export * from './utils/geometry/index.js'; +export * from './Image.js'; +export * from './load/index.js'; +export * from './Mask.js'; +export * from './maskAnalysis/index.js'; +export * from './morphology/index.js'; +export * from './operations/index.js'; +export * from './roi/index.js'; +export * from './save/index.js'; +export * from './Stack.js'; +export { decodeStack } from './stack/load/decodeStack.js'; +export * from './utils/utils.types.js'; +export * from './utils/constants/channelLabels.js'; +export * from './utils/constants/colorModels.js'; +export { BorderType } from './utils/interpolateBorder.js'; +export { InterpolationType } from './utils/interpolatePixel.js'; diff --git a/src/load/__tests__/decode.test.ts b/src/load/__tests__/decode.test.ts index b25938614..0c0df2d54 100644 --- a/src/load/__tests__/decode.test.ts +++ b/src/load/__tests__/decode.test.ts @@ -1,4 +1,4 @@ -import { decode } from '..'; +import { decode } from '../decode.js'; test('auto decode png', () => { const buffer = testUtils.loadBuffer('formats/grey8.png'); diff --git a/src/load/__tests__/decodeJpeg.test.ts b/src/load/__tests__/decodeJpeg.test.ts index 0353df1fd..0f4034563 100644 --- a/src/load/__tests__/decodeJpeg.test.ts +++ b/src/load/__tests__/decodeJpeg.test.ts @@ -1,4 +1,4 @@ -import { decodeJpeg } from '..'; +import { decodeJpeg } from '../decodeJpeg.js'; const tests = [['grey6'], ['grey12'], ['rgb6'], ['rgb12']] as const; diff --git a/src/load/__tests__/decodePng.test.ts b/src/load/__tests__/decodePng.test.ts index 2203c0b3c..5d4c5857e 100644 --- a/src/load/__tests__/decodePng.test.ts +++ b/src/load/__tests__/decodePng.test.ts @@ -1,4 +1,4 @@ -import { decodePng } from '..'; +import { decodePng } from '../decodePng.js'; const tests = [ // ['name', components, alpha, bitDepth] diff --git a/src/load/__tests__/decodeTiff.test.ts b/src/load/__tests__/decodeTiff.test.ts index d80ccebdd..34a91e646 100644 --- a/src/load/__tests__/decodeTiff.test.ts +++ b/src/load/__tests__/decodeTiff.test.ts @@ -1,4 +1,4 @@ -import { decodeTiff } from '../decodeTiff'; +import { decodeTiff } from '../decodeTiff.js'; const tests = [ // ['name', components, alpha, bitDepth] diff --git a/src/load/__tests__/getMetadata.test.ts b/src/load/__tests__/getMetadata.test.ts index 7aaa15444..27b0bc856 100644 --- a/src/load/__tests__/getMetadata.test.ts +++ b/src/load/__tests__/getMetadata.test.ts @@ -1,5 +1,5 @@ -import { decodeJpeg } from '../decodeJpeg'; -import { decodeTiff } from '../decodeTiff'; +import { decodeJpeg } from '../decodeJpeg.js'; +import { decodeTiff } from '../decodeTiff.js'; test('without metadata', () => { const buffer = testUtils.loadBuffer(`various/without-metadata.jpg`); diff --git a/src/load/__tests__/read.test.ts b/src/load/__tests__/read.test.ts index 112b210bb..e50d5558e 100644 --- a/src/load/__tests__/read.test.ts +++ b/src/load/__tests__/read.test.ts @@ -1,5 +1,5 @@ -import { read } from '..'; -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; +import { read } from '../read.js'; test('read existing image', async () => { const img = await read(testUtils.getPath('formats/rgba32.png')); diff --git a/src/load/decode.ts b/src/load/decode.ts index 8ab84c212..21d652df8 100644 --- a/src/load/decode.ts +++ b/src/load/decode.ts @@ -1,10 +1,11 @@ import imageType from 'image-type'; +import { match } from 'ts-pattern'; -import { Image } from '../Image'; +import type { Image } from '../Image.js'; -import { decodeJpeg } from './decodeJpeg'; -import { decodePng } from './decodePng'; -import { decodeTiff } from './decodeTiff'; +import { decodeJpeg } from './decodeJpeg.js'; +import { decodePng } from './decodePng.js'; +import { decodeTiff } from './decodeTiff.js'; /** * Decode input data. Data format is automatically detected. @@ -19,14 +20,11 @@ export function decode(data: ArrayBufferView): Image { data.byteLength, ); const type = imageType(typedArray); - switch (type?.mime) { - case 'image/png': - return decodePng(typedArray); - case 'image/jpeg': - return decodeJpeg(typedArray); - case 'image/tiff': - return decodeTiff(typedArray); - default: + return match(type) + .with({ mime: 'image/png' }, () => decodePng(typedArray)) + .with({ mime: 'image/jpeg' }, () => decodeJpeg(typedArray)) + .with({ mime: 'image/tiff' }, () => decodeTiff(typedArray)) + .otherwise(() => { throw new RangeError(`invalid data format: ${type?.mime}`); - } + }); } diff --git a/src/load/decodeJpeg.ts b/src/load/decodeJpeg.ts index bf6785368..e94476512 100644 --- a/src/load/decodeJpeg.ts +++ b/src/load/decodeJpeg.ts @@ -1,9 +1,9 @@ import { decode as decodeExif } from 'fast-jpeg'; import { decode } from 'jpeg-js'; -import { Image } from '../Image'; +import { Image } from '../Image.js'; -import { getMetadata } from './getMetadata'; +import { getMetadata } from './getMetadata.js'; /** * Decode a jpeg. See the jpeg-js npm module. diff --git a/src/load/decodePng.ts b/src/load/decodePng.ts index 7103b4be7..1befaec2f 100644 --- a/src/load/decodePng.ts +++ b/src/load/decodePng.ts @@ -1,8 +1,10 @@ -import { decode, DecodedPng } from 'fast-png'; +import type { DecodedPng } from 'fast-png'; +import { decode } from 'fast-png'; -import { BitDepth, Image } from '../Image'; -import { ImageColorModel } from '../utils/constants/colorModels'; -import { assert } from '../utils/validators/assert'; +import type { BitDepth } from '../Image.js'; +import { Image } from '../Image.js'; +import type { ImageColorModel } from '../utils/constants/colorModels.js'; +import { assert } from '../utils/validators/assert.js'; /** * Decode a PNG. See the fast-png npm module. diff --git a/src/load/decodeTiff.ts b/src/load/decodeTiff.ts index 49d5c3c13..630135abc 100644 --- a/src/load/decodeTiff.ts +++ b/src/load/decodeTiff.ts @@ -1,8 +1,9 @@ import { decode } from 'tiff'; -import { BitDepth, Image } from '../Image'; +import type { BitDepth } from '../Image.js'; +import { Image } from '../Image.js'; -import { getMetadata } from './getMetadata'; +import { getMetadata } from './getMetadata.js'; type TiffIfd = ReturnType[number]; diff --git a/src/load/getMetadata.ts b/src/load/getMetadata.ts index 19613a2fa..1fe935783 100644 --- a/src/load/getMetadata.ts +++ b/src/load/getMetadata.ts @@ -1,4 +1,4 @@ -import { decode } from 'tiff'; +import type { decode } from 'tiff'; type TiffIfd = ReturnType[number]; diff --git a/src/load/index.ts b/src/load/index.ts index a1a7dbe51..f00ca9c0f 100644 --- a/src/load/index.ts +++ b/src/load/index.ts @@ -1,8 +1,8 @@ -export * from './decode'; -export * from './decodeJpeg'; -export * from './decodePng'; -export * from './decodeTiff'; -export * from './load.types'; -export * from './read'; -export * from './readCanvas'; -export * from './readImg'; +export * from './decode.js'; +export * from './decodeJpeg.js'; +export * from './decodePng.js'; +export * from './decodeTiff.js'; +export * from './load.types.js'; +export * from './read.js'; +export * from './readCanvas.js'; +export * from './readImg.js'; diff --git a/src/load/read.ts b/src/load/read.ts index 20e07b8f6..eee2f3f0c 100644 --- a/src/load/read.ts +++ b/src/load/read.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; -import { Image } from '../Image'; +import type { Image } from '../Image.js'; -import { decode } from './decode'; +import { decode } from './decode.js'; /** * Read an image from the disk. diff --git a/src/load/readCanvas.ts b/src/load/readCanvas.ts index 5a4be0d9e..61a9b8fdc 100644 --- a/src/load/readCanvas.ts +++ b/src/load/readCanvas.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import { assert } from '../utils/validators/assert'; +import { Image } from '../Image.js'; +import { assert } from '../utils/validators/assert.js'; /** * Read an image from an HTML canvas element. diff --git a/src/load/readImg.ts b/src/load/readImg.ts index 9eaacea9b..d1e266b63 100644 --- a/src/load/readImg.ts +++ b/src/load/readImg.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import { assert } from '../utils/validators/assert'; +import type { Image } from '../Image.js'; +import { assert } from '../utils/validators/assert.js'; -import { readCanvas } from './readCanvas'; +import { readCanvas } from './readCanvas.js'; // TODO: Create nodejs version that throws an error /** diff --git a/src/maskAnalysis/__tests__/getBorderPoints.test.ts b/src/maskAnalysis/__tests__/getBorderPoints.test.ts index 813c5e92c..a8607851d 100644 --- a/src/maskAnalysis/__tests__/getBorderPoints.test.ts +++ b/src/maskAnalysis/__tests__/getBorderPoints.test.ts @@ -1,4 +1,4 @@ -import { Mask } from '../../Mask'; +import { Mask } from '../../Mask.js'; test('3x3 mask', () => { const mask = testUtils.createMask([ diff --git a/src/maskAnalysis/__tests__/getConvexHull.test.ts b/src/maskAnalysis/__tests__/getConvexHull.test.ts index d9844ebd2..dae1e72a9 100644 --- a/src/maskAnalysis/__tests__/getConvexHull.test.ts +++ b/src/maskAnalysis/__tests__/getConvexHull.test.ts @@ -1,4 +1,4 @@ -import { getConvexHull } from '../getConvexHull'; +import { getConvexHull } from '../getConvexHull.js'; test('cross', () => { const mask = testUtils.createMask([ diff --git a/src/maskAnalysis/__tests__/getMbr.test.ts b/src/maskAnalysis/__tests__/getMbr.test.ts index cceb616a1..4e7e4334a 100644 --- a/src/maskAnalysis/__tests__/getMbr.test.ts +++ b/src/maskAnalysis/__tests__/getMbr.test.ts @@ -1,6 +1,6 @@ -import { fromMask } from '../../roi'; -import { angle } from '../../utils/geometry/angles'; -import { getMbr } from '../getMbr'; +import { fromMask } from '../../roi/index.js'; +import { angle } from '../../utils/geometry/angles.js'; +import { getMbr } from '../getMbr.js'; test('verify that angle is correct', () => { const mask = testUtils.createMask(` diff --git a/src/maskAnalysis/getBorderPoints.ts b/src/maskAnalysis/getBorderPoints.ts index 5d5d658f3..349bb4601 100644 --- a/src/maskAnalysis/getBorderPoints.ts +++ b/src/maskAnalysis/getBorderPoints.ts @@ -1,7 +1,7 @@ -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; -import { GetBorderPointsOptions } from './maskAnalysis.types'; +import type { GetBorderPointsOptions } from './maskAnalysis.types.js'; // TODO: This function could be optimised by following the contour instead of scanning all pixels. /** diff --git a/src/maskAnalysis/getConvexHull.ts b/src/maskAnalysis/getConvexHull.ts index 70d85cb72..6a08cabf7 100644 --- a/src/maskAnalysis/getConvexHull.ts +++ b/src/maskAnalysis/getConvexHull.ts @@ -1,12 +1,12 @@ -import { Mask } from '../Mask'; +import type { Mask } from '../Mask.js'; import { getPolygonArea, getPolygonPerimeter, -} from '../utils/geometry/polygons'; +} from '../utils/geometry/polygons.js'; -import { ConvexHull } from './maskAnalysis.types'; -import { getExtendedBorderPoints } from './utils/getExtendedBorderPoints'; -import { monotoneChainConvexHull as mcch } from './utils/monotoneChainConvexHull'; +import type { ConvexHull } from './maskAnalysis.types.js'; +import { getExtendedBorderPoints } from './utils/getExtendedBorderPoints.js'; +import { monotoneChainConvexHull as mcch } from './utils/monotoneChainConvexHull.js'; /** * Get the vertices of the convex Hull polygon of a mask. diff --git a/src/maskAnalysis/getFeret.ts b/src/maskAnalysis/getFeret.ts index 9c7dbd6ec..0dbf21981 100644 --- a/src/maskAnalysis/getFeret.ts +++ b/src/maskAnalysis/getFeret.ts @@ -1,10 +1,10 @@ -import { Mask } from '../Mask'; -import { Point } from '../geometry'; -import { toDegrees } from '../utils/geometry/angles'; -import { rotate } from '../utils/geometry/points'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../geometry/index.js'; +import { toDegrees } from '../utils/geometry/angles.js'; +import { rotate } from '../utils/geometry/points.js'; -import { Feret, FeretDiameter } from './maskAnalysis.types'; -import { getAngle } from './utils/getAngle'; +import type { Feret, FeretDiameter } from './maskAnalysis.types.js'; +import { getAngle } from './utils/getAngle.js'; /** * Computes the Feret diameters. diff --git a/src/maskAnalysis/getMbr.ts b/src/maskAnalysis/getMbr.ts index 9545f5067..37516f4b9 100644 --- a/src/maskAnalysis/getMbr.ts +++ b/src/maskAnalysis/getMbr.ts @@ -1,9 +1,9 @@ -import { Mask } from '../Mask'; +import type { Mask } from '../Mask.js'; -import { Mbr } from './maskAnalysis.types'; -import { getExtendedBorderPoints } from './utils/getExtendedBorderPoints'; -import { getMbrFromPoints } from './utils/getMbrFromPoints'; -import { monotoneChainConvexHull } from './utils/monotoneChainConvexHull'; +import type { Mbr } from './maskAnalysis.types.js'; +import { getExtendedBorderPoints } from './utils/getExtendedBorderPoints.js'; +import { getMbrFromPoints } from './utils/getMbrFromPoints.js'; +import { monotoneChainConvexHull } from './utils/monotoneChainConvexHull.js'; /** * Get the four corners of the minimum bounding rectangle of an ROI. diff --git a/src/maskAnalysis/index.ts b/src/maskAnalysis/index.ts index 6e9a4c82a..791ed3d28 100644 --- a/src/maskAnalysis/index.ts +++ b/src/maskAnalysis/index.ts @@ -1 +1 @@ -export * from './maskAnalysis.types'; +export * from './maskAnalysis.types.js'; diff --git a/src/maskAnalysis/maskAnalysis.types.ts b/src/maskAnalysis/maskAnalysis.types.ts index 07194a88d..7941715c5 100644 --- a/src/maskAnalysis/maskAnalysis.types.ts +++ b/src/maskAnalysis/maskAnalysis.types.ts @@ -1,4 +1,4 @@ -import { Point } from '../utils/geometry/points'; +import type { Point } from '../utils/geometry/points.js'; export interface FeretDiameter { /** diff --git a/src/maskAnalysis/utils/__tests__/getAngle.test.ts b/src/maskAnalysis/utils/__tests__/getAngle.test.ts index f9335020f..8539d2f5b 100644 --- a/src/maskAnalysis/utils/__tests__/getAngle.test.ts +++ b/src/maskAnalysis/utils/__tests__/getAngle.test.ts @@ -1,8 +1,4 @@ -import { toBeDeepCloseTo } from 'jest-matcher-deep-close-to'; - -import { getAngle, getClockwiseAngle } from '../getAngle'; - -expect.extend({ toBeDeepCloseTo }); +import { getAngle, getClockwiseAngle } from '../getAngle.js'; test.each([ [ diff --git a/src/maskAnalysis/utils/__tests__/getExtendedBorderPoints.test.ts b/src/maskAnalysis/utils/__tests__/getExtendedBorderPoints.test.ts index e6a635f38..f7c972b3e 100644 --- a/src/maskAnalysis/utils/__tests__/getExtendedBorderPoints.test.ts +++ b/src/maskAnalysis/utils/__tests__/getExtendedBorderPoints.test.ts @@ -1,5 +1,5 @@ -import { Mask } from '../../../Mask'; -import { getExtendedBorderPoints } from '../getExtendedBorderPoints'; +import { Mask } from '../../../Mask.js'; +import { getExtendedBorderPoints } from '../getExtendedBorderPoints.js'; test('one pixel', () => { const mask = testUtils.createMask([[1]]); diff --git a/src/maskAnalysis/utils/__tests__/getMbrAngle.test.ts b/src/maskAnalysis/utils/__tests__/getMbrAngle.test.ts index ba01d7482..14c299a03 100644 --- a/src/maskAnalysis/utils/__tests__/getMbrAngle.test.ts +++ b/src/maskAnalysis/utils/__tests__/getMbrAngle.test.ts @@ -1,4 +1,4 @@ -import { getMbrAngle } from '../getMbrAngle'; +import { getMbrAngle } from '../getMbrAngle.js'; test.each([ [ diff --git a/src/maskAnalysis/utils/__tests__/getMbrFromPoints.test.ts b/src/maskAnalysis/utils/__tests__/getMbrFromPoints.test.ts index b3ac070e3..99edeb703 100644 --- a/src/maskAnalysis/utils/__tests__/getMbrFromPoints.test.ts +++ b/src/maskAnalysis/utils/__tests__/getMbrFromPoints.test.ts @@ -1,4 +1,4 @@ -import { getMbrFromPoints } from '../getMbrFromPoints'; +import { getMbrFromPoints } from '../getMbrFromPoints.js'; test.each([ [ diff --git a/src/maskAnalysis/utils/__tests__/monotoneChainConvexHull.test.ts b/src/maskAnalysis/utils/__tests__/monotoneChainConvexHull.test.ts index f3c460ef8..129a8725a 100644 --- a/src/maskAnalysis/utils/__tests__/monotoneChainConvexHull.test.ts +++ b/src/maskAnalysis/utils/__tests__/monotoneChainConvexHull.test.ts @@ -1,4 +1,4 @@ -import { monotoneChainConvexHull as mcch } from '../monotoneChainConvexHull'; +import { monotoneChainConvexHull as mcch } from '../monotoneChainConvexHull.js'; test('basic square', () => { const result = mcch([ diff --git a/src/maskAnalysis/utils/getAngle.ts b/src/maskAnalysis/utils/getAngle.ts index 89787a729..9ec8b0350 100644 --- a/src/maskAnalysis/utils/getAngle.ts +++ b/src/maskAnalysis/utils/getAngle.ts @@ -1,4 +1,5 @@ -import { difference, normalize, Point } from '../../utils/geometry/points'; +import type { Point } from '../../utils/geometry/points.js'; +import { difference, normalize } from '../../utils/geometry/points.js'; /** * The angle in radians of a vector relatively to the x axis. diff --git a/src/maskAnalysis/utils/getExtendedBorderPoints.ts b/src/maskAnalysis/utils/getExtendedBorderPoints.ts index 790633027..43f20742e 100644 --- a/src/maskAnalysis/utils/getExtendedBorderPoints.ts +++ b/src/maskAnalysis/utils/getExtendedBorderPoints.ts @@ -1,5 +1,5 @@ -import { Mask } from '../../Mask'; -import { Point } from '../../utils/geometry/points'; +import type { Mask } from '../../Mask.js'; +import type { Point } from '../../utils/geometry/points.js'; /** * Get the pixels that surround an ROI. The pixels include the top and left borders, diff --git a/src/maskAnalysis/utils/getMbrAngle.ts b/src/maskAnalysis/utils/getMbrAngle.ts index b23662ad2..a95319a7b 100644 --- a/src/maskAnalysis/utils/getMbrAngle.ts +++ b/src/maskAnalysis/utils/getMbrAngle.ts @@ -1,7 +1,7 @@ -import { Point } from '../../geometry'; -import { toDegrees } from '../../utils/geometry/angles'; +import type { Point } from '../../geometry/index.js'; +import { toDegrees } from '../../utils/geometry/angles.js'; -import { getAngle } from './getAngle'; +import { getAngle } from './getAngle.js'; const leftFirst = (mbrPoint1: Point, mbrPoint2: Point) => mbrPoint1.column <= mbrPoint2.column ? -1 : 1; diff --git a/src/maskAnalysis/utils/getMbrFromPoints.ts b/src/maskAnalysis/utils/getMbrFromPoints.ts index 7edb61351..5dca796b7 100644 --- a/src/maskAnalysis/utils/getMbrFromPoints.ts +++ b/src/maskAnalysis/utils/getMbrFromPoints.ts @@ -1,8 +1,9 @@ -import { Point, rotate } from '../../utils/geometry/points'; -import { Mbr } from '../maskAnalysis.types'; +import type { Point } from '../../utils/geometry/points.js'; +import { rotate } from '../../utils/geometry/points.js'; +import type { Mbr } from '../maskAnalysis.types.js'; -import { getAngle } from './getAngle'; -import { getMbrAngle } from './getMbrAngle'; +import { getAngle } from './getAngle.js'; +import { getMbrAngle } from './getMbrAngle.js'; /** * Get the four corners of the minimum bounding rectangle from a set of points defining a simple convex polygon. diff --git a/src/maskAnalysis/utils/monotoneChainConvexHull.ts b/src/maskAnalysis/utils/monotoneChainConvexHull.ts index 618a2ca2c..e6338c0d2 100644 --- a/src/maskAnalysis/utils/monotoneChainConvexHull.ts +++ b/src/maskAnalysis/utils/monotoneChainConvexHull.ts @@ -1,4 +1,4 @@ -import { Point } from '../../utils/geometry/points'; +import type { Point } from '../../utils/geometry/points.js'; interface McchOptions { /** diff --git a/src/morphology/__tests__/cannyEdgeDetector.test.ts b/src/morphology/__tests__/cannyEdgeDetector.test.ts index e3cbe0d91..03b332aed 100644 --- a/src/morphology/__tests__/cannyEdgeDetector.test.ts +++ b/src/morphology/__tests__/cannyEdgeDetector.test.ts @@ -1,4 +1,4 @@ -import { getDirection } from '..'; +import { getDirection } from '../cannyEdgeDetector.js'; describe('cannyEdgeDetector', () => { it('5x5 grey image with dot', () => { diff --git a/src/morphology/__tests__/clearBorder.test.ts b/src/morphology/__tests__/clearBorder.test.ts index 54faf9600..9a3fbbf1a 100644 --- a/src/morphology/__tests__/clearBorder.test.ts +++ b/src/morphology/__tests__/clearBorder.test.ts @@ -1,4 +1,4 @@ -import { Mask } from '../..'; +import { Mask } from '../../Mask.js'; test('5x5 mask, without corners', () => { const image = testUtils.createMask([ diff --git a/src/morphology/__tests__/floodFill.test.ts b/src/morphology/__tests__/floodFill.test.ts index 9338a18f8..85602b1f5 100644 --- a/src/morphology/__tests__/floodFill.test.ts +++ b/src/morphology/__tests__/floodFill.test.ts @@ -1,4 +1,4 @@ -import { Mask } from '../..'; +import { Mask } from '../../Mask.js'; test('mask 5x5, default options', () => { const image = testUtils.createMask([ diff --git a/src/morphology/__tests__/solidFill.test.ts b/src/morphology/__tests__/solidFill.test.ts index 9c49d0a3d..095f24abb 100644 --- a/src/morphology/__tests__/solidFill.test.ts +++ b/src/morphology/__tests__/solidFill.test.ts @@ -1,4 +1,5 @@ -import { encodePng, Mask } from '../..'; +import { Mask } from '../../Mask.js'; +import { encodePng } from '../../save/index.js'; test('mask 5x5, default options', () => { const image = testUtils.createMask([ diff --git a/src/morphology/bottomHat.ts b/src/morphology/bottomHat.ts index 6b6c97e47..0f3367823 100644 --- a/src/morphology/bottomHat.ts +++ b/src/morphology/bottomHat.ts @@ -1,7 +1,8 @@ -import { Image, Mask } from '..'; -import { subtract } from '../compare'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { subtract } from '../compare/index.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface BottomHatOptions { /** diff --git a/src/morphology/cannyEdgeDetector.ts b/src/morphology/cannyEdgeDetector.ts index bd86aab73..86acf1459 100644 --- a/src/morphology/cannyEdgeDetector.ts +++ b/src/morphology/cannyEdgeDetector.ts @@ -1,8 +1,9 @@ -import { Image, Mask } from '..'; -import { GaussianBlurOptions } from '../filters'; -import { getIndex } from '../utils/getIndex'; -import { imageToOutputMask } from '../utils/getOutputImage'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { GaussianBlurOptions } from '../filters/index.js'; +import { getIndex } from '../utils/getIndex.js'; +import { imageToOutputMask } from '../utils/getOutputImage.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface CannyEdgeOptions { /** diff --git a/src/morphology/clearBorder.ts b/src/morphology/clearBorder.ts index 9e949ac21..942871c69 100644 --- a/src/morphology/clearBorder.ts +++ b/src/morphology/clearBorder.ts @@ -1,7 +1,7 @@ -import { Mask } from '..'; -import { borderIterator } from '../utils/borderIterator'; +import type { Mask } from '../Mask.js'; +import { borderIterator } from '../utils/borderIterator.js'; -import { multipleFloodFill } from './multipleFloodFill'; +import { multipleFloodFill } from './multipleFloodFill.js'; export interface ClearBorderOptions { /** diff --git a/src/morphology/close.ts b/src/morphology/close.ts index 9290c8589..7a293e2ac 100644 --- a/src/morphology/close.ts +++ b/src/morphology/close.ts @@ -1,6 +1,7 @@ -import { Image, Mask } from '..'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface CloseOptions { /** diff --git a/src/morphology/dilate.ts b/src/morphology/dilate.ts index a9e187595..5e7690456 100644 --- a/src/morphology/dilate.ts +++ b/src/morphology/dilate.ts @@ -1,7 +1,7 @@ -import { Mask } from '..'; -import { Image } from '../Image'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface DilateOptions { /** diff --git a/src/morphology/erode.ts b/src/morphology/erode.ts index 72c9b1b79..528356370 100644 --- a/src/morphology/erode.ts +++ b/src/morphology/erode.ts @@ -1,7 +1,7 @@ -import { Mask } from '..'; -import { Image } from '../Image'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface ErodeOptions { /** diff --git a/src/morphology/floodFill.ts b/src/morphology/floodFill.ts index 4618ca8e5..835d651e6 100644 --- a/src/morphology/floodFill.ts +++ b/src/morphology/floodFill.ts @@ -1,7 +1,8 @@ -import { Mask, Point } from '..'; -import { getIndex } from '../utils/getIndex'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../geometry/index.js'; +import { getIndex } from '../utils/getIndex.js'; -import { multipleFloodFill } from './multipleFloodFill'; +import { multipleFloodFill } from './multipleFloodFill.js'; export interface FloodFillOptions { /** diff --git a/src/morphology/index.ts b/src/morphology/index.ts index 29b4fbca3..3b345b0c5 100644 --- a/src/morphology/index.ts +++ b/src/morphology/index.ts @@ -1,11 +1,11 @@ -export * from './erode'; -export * from './dilate'; -export * from './open'; -export * from './close'; -export * from './topHat'; -export * from './bottomHat'; -export * from './morphologicalGradient'; -export * from './clearBorder'; -export * from './cannyEdgeDetector'; -export * from './floodFill'; -export * from './solidFill'; +export * from './erode.js'; +export * from './dilate.js'; +export * from './open.js'; +export * from './close.js'; +export * from './topHat.js'; +export * from './bottomHat.js'; +export * from './morphologicalGradient.js'; +export * from './clearBorder.js'; +export * from './cannyEdgeDetector.js'; +export * from './floodFill.js'; +export * from './solidFill.js'; diff --git a/src/morphology/morphologicalGradient.ts b/src/morphology/morphologicalGradient.ts index d5b5261ec..40e5c86bc 100644 --- a/src/morphology/morphologicalGradient.ts +++ b/src/morphology/morphologicalGradient.ts @@ -1,7 +1,8 @@ -import { Image, Mask } from '..'; -import { subtract } from '../compare'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { subtract } from '../compare/index.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface MorphologicalGradientOptions { /** diff --git a/src/morphology/multipleFloodFill.ts b/src/morphology/multipleFloodFill.ts index 1dedb8c57..36f549508 100644 --- a/src/morphology/multipleFloodFill.ts +++ b/src/morphology/multipleFloodFill.ts @@ -1,7 +1,7 @@ -import { Mask } from '..'; -import { BitValue } from '../Mask'; -import { maskToOutputMask } from '../utils/getOutputImage'; -import { assert } from '../utils/validators/assert'; +import type { BitValue } from '../Mask.js'; +import { Mask } from '../Mask.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; +import { assert } from '../utils/validators/assert.js'; export interface MultipleFloodFillOptions { /** diff --git a/src/morphology/open.ts b/src/morphology/open.ts index ca0c77859..6d2c32be9 100644 --- a/src/morphology/open.ts +++ b/src/morphology/open.ts @@ -1,6 +1,7 @@ -import { Image, Mask } from '..'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface OpenOptions { /** diff --git a/src/morphology/solidFill.ts b/src/morphology/solidFill.ts index c23e1075a..2b091360d 100644 --- a/src/morphology/solidFill.ts +++ b/src/morphology/solidFill.ts @@ -1,5 +1,5 @@ -import { Mask } from '..'; -import { maskToOutputMask } from '../utils/getOutputImage'; +import type { Mask } from '../Mask.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; export interface SolidFillOptions { /** diff --git a/src/morphology/topHat.ts b/src/morphology/topHat.ts index ad5fae5f0..017571f1a 100644 --- a/src/morphology/topHat.ts +++ b/src/morphology/topHat.ts @@ -1,7 +1,8 @@ -import { Image, Mask } from '..'; -import { subtract } from '../compare'; -import { checkKernel } from '../utils/validators/checkKernel'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { subtract } from '../compare/index.js'; +import { checkKernel } from '../utils/validators/checkKernel.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface TopHatOptions { /** diff --git a/src/operations/__tests__/copyAlpha.test.ts b/src/operations/__tests__/copyAlpha.test.ts index 813c92485..1076a2bf3 100644 --- a/src/operations/__tests__/copyAlpha.test.ts +++ b/src/operations/__tests__/copyAlpha.test.ts @@ -1,4 +1,4 @@ -import { copyAlpha } from '../convertColor'; +import { copyAlpha } from '../convertColor.js'; test('source and dest different sizes', () => { const source = testUtils.createRgbaImage([[10, 20, 30, 40, 60, 70, 80, 90]]); diff --git a/src/operations/__tests__/copyTo.test.ts b/src/operations/__tests__/copyTo.test.ts index 3e83ea7a2..d13f6d748 100644 --- a/src/operations/__tests__/copyTo.test.ts +++ b/src/operations/__tests__/copyTo.test.ts @@ -1,5 +1,5 @@ -import { Mask } from '../../Mask'; -import { copyTo } from '../copyTo'; +import { Mask } from '../../Mask.js'; +import { copyTo } from '../copyTo.js'; test('default options', () => { const source = testUtils.createGreyImage([[100, 0]]); diff --git a/src/operations/__tests__/correctBackground.test.ts b/src/operations/__tests__/correctBackground.test.ts index c63c2068b..972e3b382 100644 --- a/src/operations/__tests__/correctBackground.test.ts +++ b/src/operations/__tests__/correctBackground.test.ts @@ -1,7 +1,7 @@ -import { Point } from '../../geometry'; -import { sampleBackgroundPoints } from '../../utils/sampleBackgroundPoints'; -import { correctBackground } from '../correctBackground'; -import { getMaskFromCannyEdge } from '../getMaskFromCannyEdge'; +import type { Point } from '../../geometry/index.js'; +import { sampleBackgroundPoints } from '../../utils/sampleBackgroundPoints.js'; +import { correctBackground } from '../correctBackground.js'; +import { getMaskFromCannyEdge } from '../getMaskFromCannyEdge.js'; test('basic test', () => { const image = testUtils.createGreyImage([ diff --git a/src/operations/__tests__/crop.test.ts b/src/operations/__tests__/crop.test.ts index 791841d6e..54332cfe8 100644 --- a/src/operations/__tests__/crop.test.ts +++ b/src/operations/__tests__/crop.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; test('GREY image, default options', () => { const image = testUtils.createGreyImage([ diff --git a/src/operations/__tests__/cropAlpha.test.ts b/src/operations/__tests__/cropAlpha.test.ts index a0ba27471..30d36b379 100644 --- a/src/operations/__tests__/cropAlpha.test.ts +++ b/src/operations/__tests__/cropAlpha.test.ts @@ -1,4 +1,4 @@ -import { cropAlpha } from '../cropAlpha'; +import { cropAlpha } from '../cropAlpha.js'; test('GREYA, no crop', () => { const image = testUtils.createGreyaImage([ diff --git a/src/operations/__tests__/cropRectangle.test.ts b/src/operations/__tests__/cropRectangle.test.ts index ad95866b6..7f43b5b8e 100644 --- a/src/operations/__tests__/cropRectangle.test.ts +++ b/src/operations/__tests__/cropRectangle.test.ts @@ -1,7 +1,7 @@ -import { Image } from '../../Image'; -import { rotatePoint } from '../../point/operations'; -import { Point } from '../../utils/geometry/points'; -import { assert } from '../../utils/validators/assert'; +import type { Image } from '../../Image.js'; +import { rotatePoint } from '../../point/operations.js'; +import type { Point } from '../../utils/geometry/points.js'; +import { assert } from '../../utils/validators/assert.js'; test('straight rectangle top left', () => { const image = testUtils.createGreyImage([ diff --git a/src/operations/__tests__/extendBorders.test.ts b/src/operations/__tests__/extendBorders.test.ts index 7b378b868..7c6963d1e 100644 --- a/src/operations/__tests__/extendBorders.test.ts +++ b/src/operations/__tests__/extendBorders.test.ts @@ -1,4 +1,4 @@ -import { extendBorders } from '../extendBorders'; +import { extendBorders } from '../extendBorders.js'; test('grey image with basic value', () => { const image = testUtils.createGreyImage(` diff --git a/src/operations/__tests__/getMaskFromCannyEdge.test.ts b/src/operations/__tests__/getMaskFromCannyEdge.test.ts index 5b0389cb2..9a54204ed 100644 --- a/src/operations/__tests__/getMaskFromCannyEdge.test.ts +++ b/src/operations/__tests__/getMaskFromCannyEdge.test.ts @@ -1,4 +1,4 @@ -import { getMaskFromCannyEdge } from '../getMaskFromCannyEdge'; +import { getMaskFromCannyEdge } from '../getMaskFromCannyEdge.js'; test('basic test', () => { const image = testUtils.createGreyImage([ diff --git a/src/operations/__tests__/greyAlgorithms.test.ts b/src/operations/__tests__/greyAlgorithms.test.ts index fc67ca569..3576ff2e6 100644 --- a/src/operations/__tests__/greyAlgorithms.test.ts +++ b/src/operations/__tests__/greyAlgorithms.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { hue } from '../greyAlgorithms'; +import { Image } from '../../Image.js'; +import { hue } from '../greyAlgorithms.js'; test('hue is zero', () => { const image = new Image(1, 1, { colorModel: 'RGBA' }); diff --git a/src/operations/__tests__/merge.test.ts b/src/operations/__tests__/merge.test.ts index 751ca801a..f02abbacf 100644 --- a/src/operations/__tests__/merge.test.ts +++ b/src/operations/__tests__/merge.test.ts @@ -1,4 +1,4 @@ -import { merge } from '../merge'; +import { merge } from '../merge.js'; test('merge into RGB', () => { const img = testUtils.createRgbImage([[0, 1, 2, 253, 254, 255]]); diff --git a/src/operations/__tests__/threshold.test.ts b/src/operations/__tests__/threshold.test.ts index b82541141..4be673c2e 100644 --- a/src/operations/__tests__/threshold.test.ts +++ b/src/operations/__tests__/threshold.test.ts @@ -1,5 +1,6 @@ -import { ImageColorModel, Image } from '../..'; -import { computeThreshold, threshold } from '../threshold'; +import { Image } from '../../Image.js'; +import { ImageColorModel } from '../../utils/constants/colorModels.js'; +import { computeThreshold, threshold } from '../threshold.js'; test('threshold with a fixed value of 100', () => { const testImage = testUtils.load('opencv/test.png'); diff --git a/src/operations/convertBitDepth.ts b/src/operations/convertBitDepth.ts index 5f8d21f14..bdbf67ddc 100644 --- a/src/operations/convertBitDepth.ts +++ b/src/operations/convertBitDepth.ts @@ -1,4 +1,5 @@ -import { Image, BitDepth } from '../Image'; +import type { BitDepth } from '../Image.js'; +import { Image } from '../Image.js'; /** * Convert the bit depth of an image. diff --git a/src/operations/convertColor.ts b/src/operations/convertColor.ts index 78a4c986f..86d32b7bb 100644 --- a/src/operations/convertColor.ts +++ b/src/operations/convertColor.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { ImageColorModel } from '../utils/constants/colorModels'; -import { getOutputImage, maskToOutputImage } from '../utils/getOutputImage'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { ImageColorModel } from '../utils/constants/colorModels.js'; +import { getOutputImage, maskToOutputImage } from '../utils/getOutputImage.js'; export interface ConvertColorOptions { /** diff --git a/src/operations/copyTo.ts b/src/operations/copyTo.ts index d072b6747..d36511733 100644 --- a/src/operations/copyTo.ts +++ b/src/operations/copyTo.ts @@ -1,7 +1,9 @@ -import { Image, Mask, Point } from '..'; -import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage'; -import { setBlendedPixel } from '../utils/setBlendedPixel'; -import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../geometry/index.js'; +import { getOutputImage, maskToOutputMask } from '../utils/getOutputImage.js'; +import { setBlendedPixel } from '../utils/setBlendedPixel.js'; +import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger.js'; export interface CopyToOptions { /** diff --git a/src/operations/correctBackground.ts b/src/operations/correctBackground.ts index c30a1546b..91f34d8f4 100644 --- a/src/operations/correctBackground.ts +++ b/src/operations/correctBackground.ts @@ -1,8 +1,8 @@ import { PolynomialRegression2D } from 'ml-regression-polynomial-2d'; -import { Image } from '../Image'; -import { Point } from '../geometry'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import type { Point } from '../geometry/index.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface CorrectBackgroundOptions { /** diff --git a/src/operations/crop.ts b/src/operations/crop.ts index d55dc141d..db6a06c3e 100644 --- a/src/operations/crop.ts +++ b/src/operations/crop.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import { Point } from '../utils/geometry/points'; -import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger'; -import checkProcessable from '../utils/validators/checkProcessable'; +import { Image } from '../Image.js'; +import type { Point } from '../utils/geometry/points.js'; +import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; export interface CropOptions { /** diff --git a/src/operations/cropAlpha.ts b/src/operations/cropAlpha.ts index 33f14f366..8cd978c59 100644 --- a/src/operations/cropAlpha.ts +++ b/src/operations/cropAlpha.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; -import { CropAlphaOptions } from './operations.types'; +import type { CropAlphaOptions } from './operations.types.js'; /** * Crops the image based on the alpha channel diff --git a/src/operations/cropRectangle.ts b/src/operations/cropRectangle.ts index 4e0050ff7..5dc0797ea 100644 --- a/src/operations/cropRectangle.ts +++ b/src/operations/cropRectangle.ts @@ -1,8 +1,9 @@ -import { Image } from '../Image'; -import { transform, TransformOptions } from '../geometry'; -import { getAngle } from '../maskAnalysis/utils/getAngle'; -import { rotatePoint } from '../point/operations'; -import { Point } from '../utils/geometry/points'; +import type { Image } from '../Image.js'; +import type { TransformOptions } from '../geometry/index.js'; +import { transform } from '../geometry/index.js'; +import { getAngle } from '../maskAnalysis/utils/getAngle.js'; +import { rotatePoint } from '../point/operations.js'; +import type { Point } from '../utils/geometry/points.js'; export type CropRectangleOptions = Omit< TransformOptions, diff --git a/src/operations/extendBorders.ts b/src/operations/extendBorders.ts index 92b4ab347..bdfd2fbbf 100644 --- a/src/operations/extendBorders.ts +++ b/src/operations/extendBorders.ts @@ -1,5 +1,6 @@ -import { Image } from '../Image'; -import { BorderType, getBorderInterpolation } from '../utils/interpolateBorder'; +import { Image } from '../Image.js'; +import type { BorderType } from '../utils/interpolateBorder.js'; +import { getBorderInterpolation } from '../utils/interpolateBorder.js'; export interface ExtendBordersOptions { /** diff --git a/src/operations/extract.ts b/src/operations/extract.ts index 0fc8d50b0..a0233f399 100644 --- a/src/operations/extract.ts +++ b/src/operations/extract.ts @@ -1,8 +1,8 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { assert } from '../utils/validators/assert'; -import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { assert } from '../utils/validators/assert.js'; +import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger.js'; export interface ExtractOptions { /** diff --git a/src/operations/getMaskFromCannyEdge.ts b/src/operations/getMaskFromCannyEdge.ts index 9d00f5774..01ebdd8ea 100644 --- a/src/operations/getMaskFromCannyEdge.ts +++ b/src/operations/getMaskFromCannyEdge.ts @@ -1,6 +1,6 @@ -import { Image } from '../Image'; -import { DilateOptions } from '../morphology'; -import { fromMask } from '../roi'; +import type { Image } from '../Image.js'; +import type { DilateOptions } from '../morphology/index.js'; +import { fromMask } from '../roi/index.js'; /** * Creates a mask with ROI shapes with CannyEdge filter. Then these shapes diff --git a/src/operations/grey.ts b/src/operations/grey.ts index a183338ea..827e51eb2 100644 --- a/src/operations/grey.ts +++ b/src/operations/grey.ts @@ -1,10 +1,11 @@ -import { Image, ImageColorModel } from '..'; -import { getClamp } from '../utils/clamp'; -import { getOutputImage } from '../utils/getOutputImage'; -import { assert } from '../utils/validators/assert'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import { getClamp } from '../utils/clamp.js'; +import type { ImageColorModel } from '../utils/constants/colorModels.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { assert } from '../utils/validators/assert.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; -import * as greyAlgorithms from './greyAlgorithms'; +import * as greyAlgorithms from './greyAlgorithms.js'; export const GreyAlgorithm = { LUMA_709: 'luma709', @@ -109,7 +110,6 @@ export function grey(image: Image, options: GreyOptions = {}): Image { if (typeof algorithm === 'function') { method = algorithm; } else { - // eslint-disable-next-line import/namespace method = greyAlgorithms[algorithm]; } diff --git a/src/operations/greyAlgorithms.ts b/src/operations/greyAlgorithms.ts index 34e426644..4262da68a 100644 --- a/src/operations/greyAlgorithms.ts +++ b/src/operations/greyAlgorithms.ts @@ -1,5 +1,5 @@ -import { Image } from '..'; -import { assert } from '../utils/validators/assert'; +import type { Image } from '../Image.js'; +import { assert } from '../utils/validators/assert.js'; /** * Converts R, G and B values to a single value using Luma 709 standard({@link https://en.wikipedia.org/wiki/Luma_(video)}). diff --git a/src/operations/index.ts b/src/operations/index.ts index 6ee0a491e..ee09b8239 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -1,16 +1,16 @@ -export * from './convertColor'; -export * from './convertBitDepth'; -export * from './extract'; -export * from './merge'; -export * from './split'; -export * from './threshold'; -export * from './grey'; -export * from './copyTo'; -export * from './crop'; -export * from './cropAlpha'; -export * from './cropRectangle'; -export * from './operations.types'; -export * from './paintMaskOnImage'; -export * from './paintMaskOnMask'; -export * from './correctBackground'; -export * from './extendBorders'; +export * from './convertColor.js'; +export * from './convertBitDepth.js'; +export * from './extract.js'; +export * from './merge.js'; +export * from './split.js'; +export * from './threshold.js'; +export * from './grey.js'; +export * from './copyTo.js'; +export * from './crop.js'; +export * from './cropAlpha.js'; +export * from './cropRectangle.js'; +export * from './operations.types.js'; +export * from './paintMaskOnImage.js'; +export * from './paintMaskOnMask.js'; +export * from './correctBackground.js'; +export * from './extendBorders.js'; diff --git a/src/operations/merge.ts b/src/operations/merge.ts index 40c54926d..1bc7c3a3f 100644 --- a/src/operations/merge.ts +++ b/src/operations/merge.ts @@ -1,5 +1,5 @@ -import { Image } from '../Image'; -import { ImageColorModel } from '../utils/constants/colorModels'; +import { Image } from '../Image.js'; +import type { ImageColorModel } from '../utils/constants/colorModels.js'; /** * Inverse of split. Merges multiple single-channel images into one. diff --git a/src/operations/paintMaskOnImage.ts b/src/operations/paintMaskOnImage.ts index 8d8a41295..0efe6046c 100644 --- a/src/operations/paintMaskOnImage.ts +++ b/src/operations/paintMaskOnImage.ts @@ -1,10 +1,10 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { getDefaultColor } from '../utils/getDefaultColor'; -import { getOutputImage } from '../utils/getOutputImage'; -import { setBlendedPixel } from '../utils/setBlendedPixel'; -import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { getDefaultColor } from '../utils/getDefaultColor.js'; +import { getOutputImage } from '../utils/getOutputImage.js'; +import { setBlendedPixel } from '../utils/setBlendedPixel.js'; +import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger.js'; export interface PaintMaskOnImageOptions { /** diff --git a/src/operations/paintMaskOnMask.ts b/src/operations/paintMaskOnMask.ts index 9958d5fb5..b2dd0c9e2 100644 --- a/src/operations/paintMaskOnMask.ts +++ b/src/operations/paintMaskOnMask.ts @@ -1,7 +1,7 @@ -import { BitValue, Mask } from '../Mask'; -import { Point } from '../utils/geometry/points'; -import { maskToOutputMask } from '../utils/getOutputImage'; -import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger'; +import type { BitValue, Mask } from '../Mask.js'; +import type { Point } from '../utils/geometry/points.js'; +import { maskToOutputMask } from '../utils/getOutputImage.js'; +import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger.js'; export interface PaintMaskOnMaskOptions { /** diff --git a/src/operations/split.ts b/src/operations/split.ts index 61c1f10a6..a5e06d5f2 100644 --- a/src/operations/split.ts +++ b/src/operations/split.ts @@ -1,4 +1,4 @@ -import { Image } from '../Image'; +import { Image } from '../Image.js'; /** * Create an array of single-channel images based on a multi-channel image. diff --git a/src/operations/threshold.ts b/src/operations/threshold.ts index fe4acf96a..e53c5b29f 100644 --- a/src/operations/threshold.ts +++ b/src/operations/threshold.ts @@ -1,22 +1,24 @@ -import { Mask } from '..'; -import { Image } from '../Image'; -import { imageToOutputMask } from '../utils/getOutputImage'; +import { match } from 'ts-pattern'; -import huang from './thresholds/huang'; -import intermodes from './thresholds/intermodes'; -import isodata from './thresholds/isodata'; -import li from './thresholds/li'; -import maxEntropy from './thresholds/maxEntropy'; -import mean from './thresholds/mean'; -import minError from './thresholds/minError'; -import minimum from './thresholds/minimum'; -import moments from './thresholds/moments'; -import { otsu } from './thresholds/otsu'; -import percentile from './thresholds/percentile'; -import renyiEntropy from './thresholds/renyiEntropy'; -import shanbhag from './thresholds/shanbhag'; -import { triangle } from './thresholds/triangle'; -import yen from './thresholds/yen'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { imageToOutputMask } from '../utils/getOutputImage.js'; + +import huang from './thresholds/huang.js'; +import intermodes from './thresholds/intermodes.js'; +import isodata from './thresholds/isodata.js'; +import li from './thresholds/li.js'; +import maxEntropy from './thresholds/maxEntropy.js'; +import mean from './thresholds/mean.js'; +import minError from './thresholds/minError.js'; +import minimum from './thresholds/minimum.js'; +import moments from './thresholds/moments.js'; +import { otsu } from './thresholds/otsu.js'; +import percentile from './thresholds/percentile.js'; +import renyiEntropy from './thresholds/renyiEntropy.js'; +import shanbhag from './thresholds/shanbhag.js'; +import { triangle } from './thresholds/triangle.js'; +import yen from './thresholds/yen.js'; export const ThresholdAlgorithm = { HUANG: 'huang', @@ -89,40 +91,23 @@ export function computeThreshold( const histogram = image.histogram({ slots }); const scale = slots ? 2 ** image.bitDepth / slots : 1; - switch (algorithm) { - case 'huang': - return huang(histogram) * scale; - case 'intermodes': - return intermodes(histogram) * scale; - case 'isodata': - return isodata(histogram) * scale; - case 'li': - return li(histogram, image.size) * scale; - case 'maxEntropy': - return maxEntropy(histogram, image.size) * scale; - case 'mean': - return mean(histogram, image.size) * scale; - case 'minimum': - return minimum(histogram) * scale; - case 'minError': - return minError(histogram, image.size) * scale; - case 'moments': - return moments(histogram, image.size) * scale; - case 'otsu': - return otsu(histogram, image.size) * scale; - case 'percentile': - return percentile(histogram) * scale; - case 'renyiEntropy': - return renyiEntropy(histogram, image.size) * scale; - case 'shanbhag': - return shanbhag(histogram, image.size) * scale; - case 'triangle': - return triangle(histogram) * scale; - case 'yen': - return yen(histogram, image.size) * scale; - default: - throw new RangeError(`invalid threshold algorithm: ${algorithm}`); - } + return match(algorithm) + .with('huang', () => huang(histogram) * scale) + .with('intermodes', () => intermodes(histogram) * scale) + .with('isodata', () => isodata(histogram) * scale) + .with('li', () => li(histogram, image.size) * scale) + .with('maxEntropy', () => maxEntropy(histogram, image.size) * scale) + .with('mean', () => mean(histogram, image.size) * scale) + .with('minimum', () => minimum(histogram) * scale) + .with('minError', () => minError(histogram, image.size) * scale) + .with('moments', () => moments(histogram, image.size) * scale) + .with('otsu', () => otsu(histogram, image.size) * scale) + .with('percentile', () => percentile(histogram) * scale) + .with('renyiEntropy', () => renyiEntropy(histogram, image.size) * scale) + .with('shanbhag', () => shanbhag(histogram, image.size) * scale) + .with('triangle', () => triangle(histogram) * scale) + .with('yen', () => yen(histogram, image.size) * scale) + .exhaustive(); } // See: https://docs.opencv.org/4.0.1/d7/d1b/group__imgproc__misc.html#gaa9e58d2860d4afa658ef70a9b1115576 diff --git a/src/operations/thresholds/__tests__/thresholdAlgorithms.test.ts b/src/operations/thresholds/__tests__/thresholdAlgorithms.test.ts index d14f9b195..9d1b9a37b 100644 --- a/src/operations/thresholds/__tests__/thresholdAlgorithms.test.ts +++ b/src/operations/thresholds/__tests__/thresholdAlgorithms.test.ts @@ -1,4 +1,4 @@ -import { computeThreshold } from '../../threshold'; +import { computeThreshold } from '../../threshold.js'; test('Huang should work similarily to ImageJ', () => { const img = testUtils.load('various/grayscale_by_zimmyrose.png'); diff --git a/src/operations/thresholds/intermodes.ts b/src/operations/thresholds/intermodes.ts index 9aaa22632..023584458 100644 --- a/src/operations/thresholds/intermodes.ts +++ b/src/operations/thresholds/intermodes.ts @@ -6,7 +6,7 @@ * */ -import { assert } from '../../utils/validators/assert'; +import { assert } from '../../utils/validators/assert.js'; /** * Return a threshold for a histogram using Intermodes algorithm. diff --git a/src/operations/thresholds/isodata.ts b/src/operations/thresholds/isodata.ts index ee5daebe7..a12807864 100644 --- a/src/operations/thresholds/isodata.ts +++ b/src/operations/thresholds/isodata.ts @@ -5,7 +5,7 @@ * */ -import { assert } from '../../utils/validators/assert'; +import { assert } from '../../utils/validators/assert.js'; /** * Return a threshold for a histogram using Isodata algorithm. diff --git a/src/point/operations.ts b/src/point/operations.ts index 35b862ba1..8f6e87fa4 100644 --- a/src/point/operations.ts +++ b/src/point/operations.ts @@ -1,4 +1,4 @@ -import { Point } from '../utils/geometry/points'; +import type { Point } from '../utils/geometry/points.js'; /** * Rotate a point around a center by a given angle. diff --git a/src/roi/Roi.ts b/src/roi/Roi.ts index 861411392..e7471b115 100644 --- a/src/roi/Roi.ts +++ b/src/roi/Roi.ts @@ -1,15 +1,20 @@ -import { Mask } from '../Mask'; -import { Feret, GetBorderPointsOptions, Mbr } from '../maskAnalysis'; -import { getConvexHull } from '../maskAnalysis/getConvexHull'; -import { getFeret } from '../maskAnalysis/getFeret'; -import { getMbr } from '../maskAnalysis/getMbr'; -import { Point } from '../utils/geometry/points'; - -import { RoiMap } from './RoiMapManager'; -import { getBorderPoints } from './getBorderPoints'; -import { getMask, GetMaskOptions } from './getMask'; -import { getEllipse } from './properties/getEllipse'; -import { Border, Ellipse } from './roi.types'; +import type { Mask } from '../Mask.js'; +import { getConvexHull } from '../maskAnalysis/getConvexHull.js'; +import { getFeret } from '../maskAnalysis/getFeret.js'; +import { getMbr } from '../maskAnalysis/getMbr.js'; +import type { + Feret, + GetBorderPointsOptions, + Mbr, +} from '../maskAnalysis/index.js'; +import type { Point } from '../utils/geometry/points.js'; + +import type { RoiMap } from './RoiMapManager.js'; +import { getBorderPoints } from './getBorderPoints.js'; +import type { GetMaskOptions } from './getMask.js'; +import { getMask } from './getMask.js'; +import { getEllipse } from './properties/getEllipse.js'; +import type { Border, Ellipse } from './roi.types.js'; interface Computed { perimeter: number; diff --git a/src/roi/RoiMapManager.ts b/src/roi/RoiMapManager.ts index 196c7d898..924ab66e7 100644 --- a/src/roi/RoiMapManager.ts +++ b/src/roi/RoiMapManager.ts @@ -1,10 +1,12 @@ import { Matrix } from 'ml-matrix'; -import { Mask } from '../Mask'; +import type { Mask } from '../Mask.js'; -import { Roi } from './Roi'; -import { FromMaskOptions, fromMask } from './fromMask'; -import { getRois, GetRoisOptions } from './getRois'; +import type { Roi } from './Roi.js'; +import type { FromMaskOptions } from './fromMask.js'; +import { fromMask } from './fromMask.js'; +import type { GetRoisOptions } from './getRois.js'; +import { getRois } from './getRois.js'; export interface RoiManager { getRois(options: GetRoisOptions): Roi[]; diff --git a/src/roi/__tests__/Roi.test.ts b/src/roi/__tests__/Roi.test.ts index 6ad521903..6cbd31d68 100644 --- a/src/roi/__tests__/Roi.test.ts +++ b/src/roi/__tests__/Roi.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '../fromMask'; +import { fromMask } from '../fromMask.js'; test('getRatio', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/RoiMapManager.test.ts b/src/roi/__tests__/RoiMapManager.test.ts index 2615d0acd..b2f19ea32 100644 --- a/src/roi/__tests__/RoiMapManager.test.ts +++ b/src/roi/__tests__/RoiMapManager.test.ts @@ -1,5 +1,5 @@ -import { RoiMapManager } from '../RoiMapManager'; -import { fromMask } from '../fromMask'; +import { RoiMapManager } from '../RoiMapManager.js'; +import { fromMask } from '../fromMask.js'; test('should work with crop', () => { const image = testUtils.createGreyImage([ diff --git a/src/roi/__tests__/__snapshots__/computeRois.test.ts.snap b/src/roi/__tests__/__snapshots__/computeRois.test.ts.snap index e56e1a336..c0a086d9c 100644 --- a/src/roi/__tests__/__snapshots__/computeRois.test.ts.snap +++ b/src/roi/__tests__/__snapshots__/computeRois.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`3x3 mask 1`] = ` [ diff --git a/src/roi/__tests__/borderLengths.test.ts b/src/roi/__tests__/borderLengths.test.ts index 44b97cc21..08294215b 100644 --- a/src/roi/__tests__/borderLengths.test.ts +++ b/src/roi/__tests__/borderLengths.test.ts @@ -1,4 +1,7 @@ -import { fromMask, RoiKind } from '../..'; +import { test } from 'vitest'; + +import { fromMask } from '../fromMask.js'; +import { RoiKind } from '../getRois.js'; test('border lengths property 5x5', () => { const mask = testUtils.createMask([ @@ -17,7 +20,7 @@ test('border lengths property 5x5', () => { ]); }); -test.skip.failing('border lengths property 4x4', () => { +test.fails.skip('border lengths property 4x4', () => { const mask = testUtils.createMask([ [0, 1, 1, 1], [0, 1, 0, 1], diff --git a/src/roi/__tests__/centroid.test.ts b/src/roi/__tests__/centroid.test.ts index b5e52701c..63976208a 100644 --- a/src/roi/__tests__/centroid.test.ts +++ b/src/roi/__tests__/centroid.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '../..'; +import { fromMask } from '../fromMask.js'; test('centroid property 4x4', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/colorRois.test.ts b/src/roi/__tests__/colorRois.test.ts index 092edf7d7..57e864589 100644 --- a/src/roi/__tests__/colorRois.test.ts +++ b/src/roi/__tests__/colorRois.test.ts @@ -1,5 +1,5 @@ -import { fromMask } from '..'; -import { colorRois } from '../colorRois'; +import { colorRois } from '../colorRois.js'; +import { fromMask } from '../fromMask.js'; test('1x2 mask', () => { const mask = testUtils.createMask([[0, 1]]); diff --git a/src/roi/__tests__/computeRois.test.ts b/src/roi/__tests__/computeRois.test.ts index 264281316..66f3f3f7d 100644 --- a/src/roi/__tests__/computeRois.test.ts +++ b/src/roi/__tests__/computeRois.test.ts @@ -1,6 +1,7 @@ -import { RoiMapManager, fromMask, waterShed } from '..'; -import { createGreyImage, getInt32Array } from '../../../test/testUtils'; -import { computeRois } from '../computeRois'; +import { RoiMapManager } from '../RoiMapManager.js'; +import { computeRois } from '../computeRois.js'; +import { fromMask } from '../fromMask.js'; +import { waterShed } from '../waterShed.js'; test('3x3 mask', () => { const mask = testUtils.createMask([ @@ -18,7 +19,7 @@ test('3x3 mask', () => { }); test('test 2, waterShed for a grey image', () => { - const image = createGreyImage([ + const image = testUtils.createGreyImage([ [3, 3, 3, 3, 3, 3, 3, 3, 4, 4], [3, 3, 2, 2, 2, 3, 3, 3, 4, 4], [4, 3, 2, 1, 2, 2, 3, 3, 4, 4], @@ -34,7 +35,7 @@ test('test 2, waterShed for a grey image', () => { const roiMapManager = waterShed(image, { threshold: 2 / 255 }); const result = new RoiMapManager({ - data: getInt32Array(` + data: testUtils.getInt32Array(` 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, diff --git a/src/roi/__tests__/ellipse.test.ts b/src/roi/__tests__/ellipse.test.ts index 6a10f2786..0080e00d4 100644 --- a/src/roi/__tests__/ellipse.test.ts +++ b/src/roi/__tests__/ellipse.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; test('ellipse on a small figure 3x3', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/eqpc.test.ts b/src/roi/__tests__/eqpc.test.ts index d25ad80cc..33a94949e 100644 --- a/src/roi/__tests__/eqpc.test.ts +++ b/src/roi/__tests__/eqpc.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; test('calculates eqpc to Roi', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/fillRatio.test.ts b/src/roi/__tests__/fillRatio.test.ts index efb69ea36..1d47f14ae 100644 --- a/src/roi/__tests__/fillRatio.test.ts +++ b/src/roi/__tests__/fillRatio.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; test('fillRatio 4x4', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/fromMask.test.ts b/src/roi/__tests__/fromMask.test.ts index a85b26fd3..ba7467228 100644 --- a/src/roi/__tests__/fromMask.test.ts +++ b/src/roi/__tests__/fromMask.test.ts @@ -1,5 +1,5 @@ -import { fromMask } from '..'; -import { Mask } from '../..'; +import { Mask } from '../../Mask.js'; +import { fromMask } from '../fromMask.js'; test('3x3 mask, black', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/getBorderPoints.test.ts b/src/roi/__tests__/getBorderPoints.test.ts index 3e7099f4a..445f79041 100644 --- a/src/roi/__tests__/getBorderPoints.test.ts +++ b/src/roi/__tests__/getBorderPoints.test.ts @@ -1,4 +1,4 @@ -import { Mask } from '../../Mask'; +import { Mask } from '../../Mask.js'; test('6x5 mask with hole, no inner borders', () => { const roi = testUtils.createRoi([ diff --git a/src/roi/__tests__/getMask.test.ts b/src/roi/__tests__/getMask.test.ts index 9b4e56ae3..9c2b038ca 100644 --- a/src/roi/__tests__/getMask.test.ts +++ b/src/roi/__tests__/getMask.test.ts @@ -1,5 +1,5 @@ -import { fromMask } from '../fromMask'; -import { getMask } from '../getMask'; +import { fromMask } from '../fromMask.js'; +import { getMask } from '../getMask.js'; test('cross', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/getRoiById.test.ts b/src/roi/__tests__/getRoiById.test.ts index 0a4aa9560..4422bfc49 100644 --- a/src/roi/__tests__/getRoiById.test.ts +++ b/src/roi/__tests__/getRoiById.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '../fromMask'; +import { fromMask } from '../fromMask.js'; test('should throw error', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/getRois.test.ts b/src/roi/__tests__/getRois.test.ts index e42529682..4e09d9cf5 100644 --- a/src/roi/__tests__/getRois.test.ts +++ b/src/roi/__tests__/getRois.test.ts @@ -1,5 +1,5 @@ -import { fromMask } from '..'; -import { getRois } from '../getRois'; +import { fromMask } from '../fromMask.js'; +import { getRois } from '../getRois.js'; test('3x3 mask, kind BLACK', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/holesInfo.test.ts b/src/roi/__tests__/holesInfo.test.ts index 020ce2fe0..57f8a489f 100644 --- a/src/roi/__tests__/holesInfo.test.ts +++ b/src/roi/__tests__/holesInfo.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; test('holes surface and number of holes 4x4', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/ped.test.ts b/src/roi/__tests__/ped.test.ts index 7d5563b5a..65c526f3d 100644 --- a/src/roi/__tests__/ped.test.ts +++ b/src/roi/__tests__/ped.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '../fromMask'; +import { fromMask } from '../fromMask.js'; test('calculates ped from roi', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/perimeter.test.ts b/src/roi/__tests__/perimeter.test.ts index 9999bf21b..9b192c7b5 100644 --- a/src/roi/__tests__/perimeter.test.ts +++ b/src/roi/__tests__/perimeter.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; describe('ROI perimeter', () => { test('perimeter', () => { diff --git a/src/roi/__tests__/points.test.ts b/src/roi/__tests__/points.test.ts index 26ef2cdb4..fd20ef70f 100644 --- a/src/roi/__tests__/points.test.ts +++ b/src/roi/__tests__/points.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; test('points 1st test', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/roundness.test.ts b/src/roi/__tests__/roundness.test.ts index 5f312bb30..a328b103d 100644 --- a/src/roi/__tests__/roundness.test.ts +++ b/src/roi/__tests__/roundness.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; test('roundness 1 ', () => { const mask = testUtils.createMask([ diff --git a/src/roi/__tests__/solidity.test.ts b/src/roi/__tests__/solidity.test.ts index c9e4f8c51..f567aed12 100644 --- a/src/roi/__tests__/solidity.test.ts +++ b/src/roi/__tests__/solidity.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; describe('ROI solidity', () => { it('solidity 1', () => { diff --git a/src/roi/__tests__/sphericity.test.ts b/src/roi/__tests__/sphericity.test.ts index fb041a772..1e11d355e 100644 --- a/src/roi/__tests__/sphericity.test.ts +++ b/src/roi/__tests__/sphericity.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; describe('ROI sphericity', () => { test('sphericity 1', () => { diff --git a/src/roi/__tests__/surface.test.ts b/src/roi/__tests__/surface.test.ts index 29279ff6e..2510bd18a 100644 --- a/src/roi/__tests__/surface.test.ts +++ b/src/roi/__tests__/surface.test.ts @@ -1,4 +1,4 @@ -import { fromMask } from '..'; +import { fromMask } from '../fromMask.js'; describe('ROI surface', () => { it('surface of a figure with a hole', () => { diff --git a/src/roi/__tests__/waterShed.test.ts b/src/roi/__tests__/waterShed.test.ts index 9fb2ea9c2..2feeb0cb0 100644 --- a/src/roi/__tests__/waterShed.test.ts +++ b/src/roi/__tests__/waterShed.test.ts @@ -1,10 +1,9 @@ -import { computeThreshold } from '../..'; -import { createGreyImage, getInt32Array } from '../../../test/testUtils'; -import { waterShed } from '../waterShed'; +import { computeThreshold } from '../../operations/index.js'; +import { waterShed } from '../waterShed.js'; describe('Test WaterShed Roi generation', () => { it('test 1,basic test without parameters/options', () => { - const image = createGreyImage([ + const image = testUtils.createGreyImage([ [3, 3, 3, 3, 3], [3, 2, 2, 2, 3], [3, 2, 1, 2, 3], @@ -32,7 +31,7 @@ describe('Test WaterShed Roi generation', () => { }); it('test 2, waterShed for a grey image', () => { - const image = createGreyImage([ + const image = testUtils.createGreyImage([ [3, 3, 3, 3, 3, 3, 3, 3, 4, 4], [3, 3, 2, 2, 2, 3, 3, 3, 4, 4], [4, 3, 2, 1, 2, 2, 3, 3, 4, 4], @@ -46,7 +45,7 @@ describe('Test WaterShed Roi generation', () => { ]); const roiMapManager = waterShed(image, { threshold: 2 / 255 }); - const resultArray = getInt32Array(` + const resultArray = testUtils.getInt32Array(` 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, @@ -71,7 +70,7 @@ describe('Test WaterShed Roi generation', () => { }); it('test 3, with threshold option', () => { - const image = createGreyImage([ + const image = testUtils.createGreyImage([ [1, 1, 1, 1, 1], [1, 2, 2, 2, 1], [1, 2, 3, 2, 1], @@ -82,7 +81,7 @@ describe('Test WaterShed Roi generation', () => { const roiMapManager = waterShed(invertedImage, { threshold: 253 / image.maxValue, }); - const resultArray = getInt32Array(` + const resultArray = testUtils.getInt32Array(` 0, 0, 0, 0, 0, 0,-1,-1,-1, 0, 0,-1,-1,-1, 0, @@ -102,7 +101,7 @@ describe('Test WaterShed Roi generation', () => { }); }); it('test 4, waterShed through threshold value', () => { - const image = createGreyImage([ + const image = testUtils.createGreyImage([ [3, 3, 3, 3, 3, 3, 3, 3, 4, 4], [3, 3, 2, 2, 2, 3, 3, 3, 4, 4], [4, 3, 2, 1, 2, 2, 3, 3, 4, 4], @@ -119,7 +118,7 @@ describe('Test WaterShed Roi generation', () => { const roiMapManager = waterShed(image, { threshold: threshold / image.maxValue, }); - const resultArray = getInt32Array(` + const resultArray = testUtils.getInt32Array(` 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, @@ -144,7 +143,7 @@ describe('Test WaterShed Roi generation', () => { }); }); it('test 5, waterShed through threshold mask and with inverted image', () => { - const image = createGreyImage([ + const image = testUtils.createGreyImage([ [3, 3, 3, 3, 3, 3, 3, 3, 4, 4], [3, 3, 2, 2, 2, 3, 3, 8, 4, 4], [4, 3, 2, 1, 2, 2, 3, 3, 4, 4], @@ -159,7 +158,7 @@ describe('Test WaterShed Roi generation', () => { const mask = image.threshold({ algorithm: 'otsu' }); const roiMapManager = waterShed(image, { mask }); - const resultArray = getInt32Array(` + const resultArray = testUtils.getInt32Array(` -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, diff --git a/src/roi/colorRois.ts b/src/roi/colorRois.ts index e2e7cf454..d897dc4f0 100644 --- a/src/roi/colorRois.ts +++ b/src/roi/colorRois.ts @@ -1,9 +1,8 @@ -import { Image } from '..'; +import { Image } from '../Image.js'; -import { RoiKind } from './getRois'; -import { getColorMap } from './utils/getColorMap'; - -import { RoiMapManager } from '.'; +import type { RoiMapManager } from './RoiMapManager.js'; +import type { RoiKind } from './getRois.js'; +import { getColorMap } from './utils/getColorMap.js'; export const RoisColorMode = { /** diff --git a/src/roi/computeRois.ts b/src/roi/computeRois.ts index e128e375d..17897a0fb 100644 --- a/src/roi/computeRois.ts +++ b/src/roi/computeRois.ts @@ -1,5 +1,5 @@ -import { Roi } from './Roi'; -import { RoiMapManager } from './RoiMapManager'; +import { Roi } from './Roi.js'; +import type { RoiMapManager } from './RoiMapManager.js'; /** * Generate an array of ROIs based on an ROI map manager. diff --git a/src/roi/fromMask.ts b/src/roi/fromMask.ts index 7c9489a6c..9472286be 100644 --- a/src/roi/fromMask.ts +++ b/src/roi/fromMask.ts @@ -1,7 +1,7 @@ -import { Mask } from '..'; -import { assert } from '../utils/validators/assert'; +import type { Mask } from '../Mask.js'; +import { assert } from '../utils/validators/assert.js'; -import { RoiMapManager } from './RoiMapManager'; +import { RoiMapManager } from './RoiMapManager.js'; export interface FromMaskOptions { /** diff --git a/src/roi/getBorderPoints.ts b/src/roi/getBorderPoints.ts index f603b273c..97c5ad4ef 100644 --- a/src/roi/getBorderPoints.ts +++ b/src/roi/getBorderPoints.ts @@ -1,7 +1,7 @@ -import { GetBorderPointsOptions } from '../maskAnalysis'; -import { Point } from '../utils/geometry/points'; +import type { GetBorderPointsOptions } from '../maskAnalysis/index.js'; +import type { Point } from '../utils/geometry/points.js'; -import { Roi } from './Roi'; +import type { Roi } from './Roi.js'; /** * Return an array with the coordinates of the pixels that are on the border of the ROI. diff --git a/src/roi/getMask.ts b/src/roi/getMask.ts index 437fede5e..d7caabe2e 100644 --- a/src/roi/getMask.ts +++ b/src/roi/getMask.ts @@ -1,6 +1,6 @@ -import { Mask } from '../Mask'; +import { Mask } from '../Mask.js'; -import { Roi } from './Roi'; +import type { Roi } from './Roi.js'; export interface GetMaskOptions { /** diff --git a/src/roi/getRois.ts b/src/roi/getRois.ts index 94c13e72f..a7844a63e 100644 --- a/src/roi/getRois.ts +++ b/src/roi/getRois.ts @@ -1,6 +1,8 @@ -import { Roi } from './Roi'; -import { RoiMapManager } from './RoiMapManager'; -import { computeRois } from './computeRois'; +import { match } from 'ts-pattern'; + +import type { Roi } from './Roi.js'; +import type { RoiMapManager } from './RoiMapManager.js'; +import { computeRois } from './computeRois.js'; export const RoiKind = { BLACK: 'black', @@ -50,24 +52,12 @@ export function getRois( ) { computeRois(roiMapManager); } - let rois; - switch (kind) { - case 'black': { - rois = roiMapManager.blackRois; - break; - } - case 'white': { - rois = roiMapManager.whiteRois; - break; - } - case 'bw': { - rois = [...roiMapManager.whiteRois, ...roiMapManager.blackRois]; - break; - } - default: { - throw new RangeError(`invalid ROI kind: ${kind}`); - } - } + + const rois = match(kind) + .with('black', () => roiMapManager.blackRois) + .with('white', () => roiMapManager.whiteRois) + .with('bw', () => [...roiMapManager.whiteRois, ...roiMapManager.blackRois]) + .exhaustive(); return rois.filter( (roi) => roi.surface >= minSurface && roi.surface <= maxSurface, diff --git a/src/roi/index.ts b/src/roi/index.ts index 10a914fbc..3ae2309ef 100644 --- a/src/roi/index.ts +++ b/src/roi/index.ts @@ -1,10 +1,10 @@ -export * from './colorRois'; -export * from './computeRois'; -export * from './fromMask'; -export * from './getBorderPoints'; -export * from './getMask'; -export * from './getRois'; -export * from './Roi'; -export * from './RoiMapManager'; -export * from './waterShed'; -export * from './roi.types'; +export * from './colorRois.js'; +export * from './computeRois.js'; +export * from './fromMask.js'; +export * from './getBorderPoints.js'; +export * from './getMask.js'; +export * from './getRois.js'; +export * from './Roi.js'; +export * from './RoiMapManager.js'; +export * from './waterShed.js'; +export * from './roi.types.js'; diff --git a/src/roi/properties/getEllipse.ts b/src/roi/properties/getEllipse.ts index cf30b3d8a..a2047773e 100644 --- a/src/roi/properties/getEllipse.ts +++ b/src/roi/properties/getEllipse.ts @@ -1,12 +1,12 @@ import { EigenvalueDecomposition } from 'ml-matrix'; import { xVariance, xyCovariance } from 'ml-spectra-processing'; -import { Point } from '../../geometry'; -import { getAngle } from '../../maskAnalysis/utils/getAngle'; -import { toDegrees } from '../../utils/geometry/angles'; -import { assert } from '../../utils/validators/assert'; -import { Roi } from '../Roi'; -import { Ellipse } from '../roi.types'; +import type { Point } from '../../geometry/index.js'; +import { getAngle } from '../../maskAnalysis/utils/getAngle.js'; +import { toDegrees } from '../../utils/geometry/angles.js'; +import { assert } from '../../utils/validators/assert.js'; +import type { Roi } from '../Roi.js'; +import type { Ellipse } from '../roi.types.js'; /** * Calculates ellipse on around ROI. * @param roi - Region of interest. diff --git a/src/roi/roi.types.ts b/src/roi/roi.types.ts index 7fbd362af..0a789754e 100644 --- a/src/roi/roi.types.ts +++ b/src/roi/roi.types.ts @@ -1,4 +1,4 @@ -import { Point } from '../utils/geometry/points'; +import type { Point } from '../utils/geometry/points.js'; export interface Ellipse { center: { diff --git a/src/roi/utils/__tests__/getColorMap.test.ts b/src/roi/utils/__tests__/getColorMap.test.ts index ebf073429..3c31a60ea 100644 --- a/src/roi/utils/__tests__/getColorMap.test.ts +++ b/src/roi/utils/__tests__/getColorMap.test.ts @@ -1,5 +1,5 @@ -import { getBinaryMap } from '../colorMaps/getBinaryMap'; -import { getColorMap } from '../getColorMap'; +import { getBinaryMap } from '../colorMaps/getBinaryMap.js'; +import { getColorMap } from '../getColorMap.js'; test('default options', () => { const colorMap = getBinaryMap({ nbNegative: 1, nbPositive: 1 }); diff --git a/src/roi/utils/__tests__/hsvToRgb.test.ts b/src/roi/utils/__tests__/hsvToRgb.test.ts index f4de215ea..ffeef0ba1 100644 --- a/src/roi/utils/__tests__/hsvToRgb.test.ts +++ b/src/roi/utils/__tests__/hsvToRgb.test.ts @@ -1,4 +1,4 @@ -import { hsvToRgb } from '../hsvToRgb'; +import { hsvToRgb } from '../hsvToRgb.js'; test('black', () => { const rgb = new Uint8Array([0, 0, 0]); diff --git a/src/roi/utils/__tests__/rgbToNumber.test.ts b/src/roi/utils/__tests__/rgbToNumber.test.ts index f63b80cba..5e75cd0d8 100644 --- a/src/roi/utils/__tests__/rgbToNumber.test.ts +++ b/src/roi/utils/__tests__/rgbToNumber.test.ts @@ -1,4 +1,4 @@ -import { rgbToNumber } from '../rgbToNumber'; +import { rgbToNumber } from '../rgbToNumber.js'; test('white', () => { const rgb = new Uint8Array([255, 255, 255]); diff --git a/src/roi/utils/colorMaps/getBinaryMap.ts b/src/roi/utils/colorMaps/getBinaryMap.ts index 1456103db..9edc52941 100644 --- a/src/roi/utils/colorMaps/getBinaryMap.ts +++ b/src/roi/utils/colorMaps/getBinaryMap.ts @@ -1,6 +1,6 @@ -import { RoiKind } from '../../getRois'; -import { hsvToRgb } from '../hsvToRgb'; -import { rgbToNumber } from '../rgbToNumber'; +import type { RoiKind } from '../../getRois.js'; +import { hsvToRgb } from '../hsvToRgb.js'; +import { rgbToNumber } from '../rgbToNumber.js'; // warning: the values in a uint32 array are flipped!! e.g. [0,0,0,1] becomes 0x01000000 // the bits values are therefore in the following order: ABGR diff --git a/src/roi/utils/colorMaps/getRainbowMap.ts b/src/roi/utils/colorMaps/getRainbowMap.ts index 9c5bad9cb..e947f10be 100644 --- a/src/roi/utils/colorMaps/getRainbowMap.ts +++ b/src/roi/utils/colorMaps/getRainbowMap.ts @@ -1,6 +1,8 @@ -import { RoiKind } from '../../getRois'; -import { hsvToRgb } from '../hsvToRgb'; -import { rgbToNumber } from '../rgbToNumber'; +import { match } from 'ts-pattern'; + +import type { RoiKind } from '../../getRois.js'; +import { hsvToRgb } from '../hsvToRgb.js'; +import { rgbToNumber } from '../rgbToNumber.js'; export interface GetRainbowMapOptions { /** @@ -30,24 +32,11 @@ export function getRainbowMap(options: GetRainbowMapOptions): Uint32Array { const hueRange = 360; - let step: number; - switch (roiKind) { - case 'bw': { - step = hueRange / (nbNegative + nbPositive); - break; - } - case 'black': { - step = hueRange / nbNegative; - break; - } - case 'white': { - step = hueRange / nbPositive; - break; - } - default: { - throw new RangeError(`invalid ROI kind: ${roiKind}`); - } - } + const step = match(roiKind) + .with('bw', () => hueRange / (nbNegative + nbPositive)) + .with('black', () => hueRange / nbNegative) + .with('white', () => hueRange / nbPositive) + .exhaustive(); // negative values let hue = 0; diff --git a/src/roi/utils/colorMaps/getSaturationMap.ts b/src/roi/utils/colorMaps/getSaturationMap.ts index 455ad98a1..66e4cb898 100644 --- a/src/roi/utils/colorMaps/getSaturationMap.ts +++ b/src/roi/utils/colorMaps/getSaturationMap.ts @@ -1,6 +1,6 @@ -import { RoiKind } from '../../getRois'; -import { hsvToRgb } from '../hsvToRgb'; -import { rgbToNumber } from '../rgbToNumber'; +import type { RoiKind } from '../../getRois.js'; +import { hsvToRgb } from '../hsvToRgb.js'; +import { rgbToNumber } from '../rgbToNumber.js'; export interface GetSaturationMapOptions { /** diff --git a/src/roi/utils/getColorMap.ts b/src/roi/utils/getColorMap.ts index 85b4b2bba..2d22dcbad 100644 --- a/src/roi/utils/getColorMap.ts +++ b/src/roi/utils/getColorMap.ts @@ -1,9 +1,11 @@ -import { RoisColorMode } from '../colorRois'; -import { RoiKind } from '../getRois'; +import { match } from 'ts-pattern'; -import { getBinaryMap } from './colorMaps/getBinaryMap'; -import { getRainbowMap } from './colorMaps/getRainbowMap'; -import { getSaturationMap } from './colorMaps/getSaturationMap'; +import type { RoisColorMode } from '../colorRois.js'; +import type { RoiKind } from '../getRois.js'; + +import { getBinaryMap } from './colorMaps/getBinaryMap.js'; +import { getRainbowMap } from './colorMaps/getRainbowMap.js'; +import { getSaturationMap } from './colorMaps/getSaturationMap.js'; export interface GetColorMapOptions { /** @@ -36,14 +38,9 @@ export function getColorMap(options: GetColorMapOptions): Uint32Array { const { mode = 'binary' } = options; options = { roiKind: 'bw', ...options }; - switch (mode) { - case 'binary': - return getBinaryMap(options); - case 'saturation': - return getSaturationMap(options); - case 'rainbow': - return getRainbowMap(options); - default: - throw new RangeError(`invalid color mode: ${mode}`); - } + return match(mode) + .with('binary', () => getBinaryMap(options)) + .with('saturation', () => getSaturationMap(options)) + .with('rainbow', () => getRainbowMap(options)) + .exhaustive(); } diff --git a/src/roi/waterShed.ts b/src/roi/waterShed.ts index 36fcb2562..001bc0d39 100644 --- a/src/roi/waterShed.ts +++ b/src/roi/waterShed.ts @@ -1,11 +1,12 @@ import PriorityQueue from 'js-priority-queue'; -import { RoiMapManager } from '..'; -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { getExtrema } from '../compute/getExtrema'; -import { Point } from '../geometry'; -import checkProcessable from '../utils/validators/checkProcessable'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { getExtrema } from '../compute/index.js'; +import type { Point } from '../geometry/index.js'; +import checkProcessable from '../utils/validators/checkProcessable.js'; + +import { RoiMapManager } from './RoiMapManager.js'; /** * Point interface that is used in the queue data structure. diff --git a/src/save/__tests__/encodeBmp.test.ts b/src/save/__tests__/encodeBmp.test.ts index 5db528c64..09669e2b4 100644 --- a/src/save/__tests__/encodeBmp.test.ts +++ b/src/save/__tests__/encodeBmp.test.ts @@ -1,4 +1,4 @@ -import { encodeBmp } from '../encodeBmp'; +import { encodeBmp } from '../encodeBmp.js'; test('encode 5x5 mask', () => { const image = testUtils.createGreyImage([ diff --git a/src/save/__tests__/encodeJpeg.test.ts b/src/save/__tests__/encodeJpeg.test.ts index 6210a88c5..069013d64 100644 --- a/src/save/__tests__/encodeJpeg.test.ts +++ b/src/save/__tests__/encodeJpeg.test.ts @@ -1,5 +1,5 @@ -import { encodeJpeg } from '..'; -import { decode } from '../../load/decode'; +import { decode } from '../../load/decode.js'; +import { encodeJpeg } from '../encodeJpeg.js'; test('encode an 8-bit rgba image', () => { const image = testUtils.createRgbaImage([ diff --git a/src/save/__tests__/encodePng.test.ts b/src/save/__tests__/encodePng.test.ts index 7a37aa198..78c858745 100644 --- a/src/save/__tests__/encodePng.test.ts +++ b/src/save/__tests__/encodePng.test.ts @@ -1,5 +1,5 @@ -import { encodePng } from '..'; -import { decode } from '../../load/decode'; +import { decode } from '../../load/decode.js'; +import { encodePng } from '../encodePng.js'; test('should encode what it decoded', () => { const buffer = testUtils.loadBuffer('formats/grey8.png'); diff --git a/src/save/__tests__/write.test.ts b/src/save/__tests__/write.test.ts index 2f46ac094..af0e0d45b 100644 --- a/src/save/__tests__/write.test.ts +++ b/src/save/__tests__/write.test.ts @@ -2,8 +2,8 @@ import { existsSync } from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { write, writeSync } from '..'; -import { read, readSync } from '../..'; +import { read, readSync } from '../../load/index.js'; +import { write, writeSync } from '../write.js'; let tmpDir: string; beforeEach(() => { @@ -126,7 +126,7 @@ test('unknown format error', () => { expect(() => { // @ts-expect-error test invalid format writeSync(destination, img, { format: 'foo' }); - }).toThrow(/invalid format: foo/); + }).toThrow(/foo/); }); test('image extension error', async () => { diff --git a/src/save/encode.ts b/src/save/encode.ts index 8a95d9cb5..3f99f3b6c 100644 --- a/src/save/encode.ts +++ b/src/save/encode.ts @@ -1,9 +1,13 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import { match, P } from 'ts-pattern'; -import { encodeBmp } from './encodeBmp'; -import { encodeJpeg, EncodeJpegOptions } from './encodeJpeg'; -import { encodePng, EncodePngOptions } from './encodePng'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; + +import { encodeBmp } from './encodeBmp.js'; +import type { EncodeJpegOptions } from './encodeJpeg.js'; +import { encodeJpeg } from './encodeJpeg.js'; +import type { EncodePngOptions } from './encodePng.js'; +import { encodePng } from './encodePng.js'; export const ImageFormat = { PNG: 'png', @@ -37,13 +41,13 @@ export function encode( image: Image | Mask, options: EncodeOptionsBmp | EncodeOptionsPng | EncodeOptionsJpeg = defaultPng, ): Uint8Array { - if (options.format === 'png') { - return encodePng(image, options.encoderOptions); - } else if (options.format === 'jpg' || options.format === 'jpeg') { - return encodeJpeg(image, options.encoderOptions); - } else if (options.format === 'bmp') { - return encodeBmp(image); - } else { - throw new RangeError(`invalid format: ${options.format}`); - } + return match(options) + .with({ format: 'png' }, (options) => + encodePng(image, options.encoderOptions), + ) + .with({ format: P.union('jpg', 'jpeg') }, (options) => + encodeJpeg(image, options.encoderOptions), + ) + .with({ format: 'bmp' }, () => encodeBmp(image)) + .exhaustive(); } diff --git a/src/save/encodeBmp.ts b/src/save/encodeBmp.ts index 122ebade1..ffadc7f8a 100644 --- a/src/save/encodeBmp.ts +++ b/src/save/encodeBmp.ts @@ -1,8 +1,8 @@ //@ts-expect-error ts package not ready yet import * as bmp from 'fast-bmp'; -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import type { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; /** * Creates a BMP buffer from a mask. diff --git a/src/save/encodeJpeg.ts b/src/save/encodeJpeg.ts index 9a34d1ffd..79891f1bb 100644 --- a/src/save/encodeJpeg.ts +++ b/src/save/encodeJpeg.ts @@ -1,7 +1,7 @@ import { encode } from 'jpeg-js'; -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import type { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; export interface EncodeJpegOptions { /** diff --git a/src/save/encodePng.ts b/src/save/encodePng.ts index 94ca9a0e5..56f872d61 100644 --- a/src/save/encodePng.ts +++ b/src/save/encodePng.ts @@ -1,7 +1,8 @@ -import { encode, PngEncoderOptions } from 'fast-png'; +import type { PngEncoderOptions } from 'fast-png'; +import { encode } from 'fast-png'; -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import type { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; export type EncodePngOptions = PngEncoderOptions; diff --git a/src/save/index.ts b/src/save/index.ts index e28dc7463..b2a09f6fe 100644 --- a/src/save/index.ts +++ b/src/save/index.ts @@ -1,5 +1,5 @@ -export * from './encode'; -export * from './encodePng'; -export * from './encodeJpeg'; -export * from './write'; -export * from './writeCanvas'; +export * from './encode.js'; +export * from './encodePng.js'; +export * from './encodeJpeg.js'; +export * from './write.js'; +export * from './writeCanvas.js'; diff --git a/src/save/write.ts b/src/save/write.ts index bc7267dfe..4adf143ad 100644 --- a/src/save/write.ts +++ b/src/save/write.ts @@ -2,14 +2,15 @@ import fs from 'node:fs'; import nodePath from 'node:path'; import url from 'node:url'; -import { Image, Mask } from '..'; +import type { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; -import { - encode, +import type { EncodeOptionsBmp, EncodeOptionsJpeg, EncodeOptionsPng, -} from './encode'; +} from './encode.js'; +import { encode } from './encode.js'; export interface WriteOptions { /** diff --git a/src/save/writeCanvas.ts b/src/save/writeCanvas.ts index e5ad46aaa..bedd8e222 100644 --- a/src/save/writeCanvas.ts +++ b/src/save/writeCanvas.ts @@ -1,6 +1,6 @@ -import { Mask } from '..'; -import { Image } from '../Image'; -import { assert } from '../utils/validators/assert'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import { assert } from '../utils/validators/assert.js'; export interface WriteCanvasOptions { /** diff --git a/src/stack/compute/__tests__/histogram.test.ts b/src/stack/compute/__tests__/histogram.test.ts index b3e74d1b4..b5b7a6698 100644 --- a/src/stack/compute/__tests__/histogram.test.ts +++ b/src/stack/compute/__tests__/histogram.test.ts @@ -1,4 +1,4 @@ -import { Stack } from '../../../Stack'; +import { Stack } from '../../../Stack.js'; test('two grey images, bitsDepth = 8', () => { const image = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/compute/__tests__/maxImage.test.ts b/src/stack/compute/__tests__/maxImage.test.ts index a16e56705..2ff135001 100644 --- a/src/stack/compute/__tests__/maxImage.test.ts +++ b/src/stack/compute/__tests__/maxImage.test.ts @@ -1,8 +1,8 @@ import { join } from 'node:path'; -import { Image } from '../../../Image'; -import { Stack } from '../../../Stack'; -import { getStackFromFolder } from '../../utils/getStackFromFolder'; +import { Image } from '../../../Image.js'; +import { Stack } from '../../../Stack.js'; +import { getStackFromFolder } from '../../utils/getStackFromFolder.js'; test('2 grey images', () => { const image1 = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/compute/__tests__/meanImage.test.ts b/src/stack/compute/__tests__/meanImage.test.ts index 43e67fef1..fb1e47937 100644 --- a/src/stack/compute/__tests__/meanImage.test.ts +++ b/src/stack/compute/__tests__/meanImage.test.ts @@ -1,8 +1,8 @@ import { join } from 'node:path'; -import { Image } from '../../../Image'; -import { Stack } from '../../../Stack'; -import { getStackFromFolder } from '../../utils/getStackFromFolder'; +import { Image } from '../../../Image.js'; +import { Stack } from '../../../Stack.js'; +import { getStackFromFolder } from '../../utils/getStackFromFolder.js'; test('2 grey images', () => { const image1 = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/compute/__tests__/medianImage.test.ts b/src/stack/compute/__tests__/medianImage.test.ts index bd35c37d6..815065e1d 100644 --- a/src/stack/compute/__tests__/medianImage.test.ts +++ b/src/stack/compute/__tests__/medianImage.test.ts @@ -1,8 +1,8 @@ import { join } from 'node:path'; -import { Image } from '../../../Image'; -import { Stack } from '../../../Stack'; -import { getStackFromFolder } from '../../utils/getStackFromFolder'; +import { Image } from '../../../Image.js'; +import { Stack } from '../../../Stack.js'; +import { getStackFromFolder } from '../../utils/getStackFromFolder.js'; test('3 grey images', () => { const image1 = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/compute/__tests__/minImage.test.ts b/src/stack/compute/__tests__/minImage.test.ts index 92381f5f8..4a79082ef 100644 --- a/src/stack/compute/__tests__/minImage.test.ts +++ b/src/stack/compute/__tests__/minImage.test.ts @@ -1,8 +1,8 @@ import { join } from 'node:path'; -import { Image } from '../../../Image'; -import { Stack } from '../../../Stack'; -import { getStackFromFolder } from '../../utils/getStackFromFolder'; +import { Image } from '../../../Image.js'; +import { Stack } from '../../../Stack.js'; +import { getStackFromFolder } from '../../utils/getStackFromFolder.js'; test('simple images', () => { const image1 = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/compute/__tests__/sum.test.ts b/src/stack/compute/__tests__/sum.test.ts index 6c540140f..e25587181 100644 --- a/src/stack/compute/__tests__/sum.test.ts +++ b/src/stack/compute/__tests__/sum.test.ts @@ -1,8 +1,8 @@ import { join } from 'node:path'; -import { Image } from '../../../Image'; -import { Stack } from '../../../Stack'; -import { getStackFromFolder } from '../../utils/getStackFromFolder'; +import { Image } from '../../../Image.js'; +import { Stack } from '../../../Stack.js'; +import { getStackFromFolder } from '../../utils/getStackFromFolder.js'; test('2 grey images', () => { const image1 = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/compute/histogram.ts b/src/stack/compute/histogram.ts index a34ccff06..1a7cb4174 100644 --- a/src/stack/compute/histogram.ts +++ b/src/stack/compute/histogram.ts @@ -1,6 +1,6 @@ -import { Stack } from '../../Stack'; -import { HistogramOptions } from '../../compute'; -import { checkProcessable } from '../utils/checkProcessable'; +import type { Stack } from '../../Stack.js'; +import type { HistogramOptions } from '../../compute/index.js'; +import { checkProcessable } from '../utils/checkProcessable.js'; /** * Get the sum of all the histograms of the stack's images. If no channel is specified in the options, the images must be GREY. diff --git a/src/stack/compute/maxImage.ts b/src/stack/compute/maxImage.ts index e95476c93..9959769c5 100644 --- a/src/stack/compute/maxImage.ts +++ b/src/stack/compute/maxImage.ts @@ -1,6 +1,6 @@ -import { Image } from '../../Image'; -import { Stack } from '../../Stack'; -import { checkProcessable } from '../utils/checkProcessable'; +import { Image } from '../../Image.js'; +import type { Stack } from '../../Stack.js'; +import { checkProcessable } from '../utils/checkProcessable.js'; /** * Returns a new image with the maximum values of each pixel from the stack. diff --git a/src/stack/compute/meanImage.ts b/src/stack/compute/meanImage.ts index 444e472ea..7123bc9ef 100644 --- a/src/stack/compute/meanImage.ts +++ b/src/stack/compute/meanImage.ts @@ -1,6 +1,6 @@ -import { Image } from '../../Image'; -import { Stack } from '../../Stack'; -import { checkProcessable } from '../utils/checkProcessable'; +import { Image } from '../../Image.js'; +import type { Stack } from '../../Stack.js'; +import { checkProcessable } from '../utils/checkProcessable.js'; /** * Returns a new image with the average values of each pixel of the images of the stack. diff --git a/src/stack/compute/medianImage.ts b/src/stack/compute/medianImage.ts index cf7411cc4..f18a64e79 100644 --- a/src/stack/compute/medianImage.ts +++ b/src/stack/compute/medianImage.ts @@ -1,9 +1,9 @@ // @ts-expect-error: median-quisckselect has no types import quickMedian from 'median-quickselect'; -import { Image } from '../../Image'; -import { Stack } from '../../Stack'; -import { checkProcessable } from '../utils/checkProcessable'; +import { Image } from '../../Image.js'; +import type { Stack } from '../../Stack.js'; +import { checkProcessable } from '../utils/checkProcessable.js'; /** * Returns a new image with the median values of each pixel of the images of the stack. diff --git a/src/stack/compute/minImage.ts b/src/stack/compute/minImage.ts index 85496dfb7..b5eb63086 100644 --- a/src/stack/compute/minImage.ts +++ b/src/stack/compute/minImage.ts @@ -1,6 +1,6 @@ -import { Image } from '../../Image'; -import { Stack } from '../../Stack'; -import { checkProcessable } from '../utils/checkProcessable'; +import { Image } from '../../Image.js'; +import type { Stack } from '../../Stack.js'; +import { checkProcessable } from '../utils/checkProcessable.js'; /** * Returns a new image with the minimum values of each pixel from the stack. diff --git a/src/stack/compute/sum.ts b/src/stack/compute/sum.ts index 1aa99cec7..52c757441 100644 --- a/src/stack/compute/sum.ts +++ b/src/stack/compute/sum.ts @@ -1,6 +1,6 @@ -import { Image } from '../../Image'; -import { Stack } from '../../Stack'; -import { checkProcessable } from '../utils/checkProcessable'; +import { Image } from '../../Image.js'; +import type { Stack } from '../../Stack.js'; +import { checkProcessable } from '../utils/checkProcessable.js'; /** * Returns a new 16 bits depth image with the sum of each pixel of the images of the stack. diff --git a/src/stack/index.ts b/src/stack/index.ts index 1288e638d..30bbff950 100644 --- a/src/stack/index.ts +++ b/src/stack/index.ts @@ -1,7 +1,7 @@ -export * from './compute/histogram'; -export * from './compute/maxImage'; -export * from './compute/meanImage'; -export * from './compute/medianImage'; -export * from './load/decodeStack'; -export * from './compute/minImage'; -export * from './compute/sum'; +export * from './compute/histogram.js'; +export * from './compute/maxImage.js'; +export * from './compute/meanImage.js'; +export * from './compute/medianImage.js'; +export * from './load/decodeStack.js'; +export * from './compute/minImage.js'; +export * from './compute/sum.js'; diff --git a/src/stack/load/__tests__/decodeStack.test.ts b/src/stack/load/__tests__/decodeStack.test.ts index df3f92e1b..b34a90e0f 100644 --- a/src/stack/load/__tests__/decodeStack.test.ts +++ b/src/stack/load/__tests__/decodeStack.test.ts @@ -1,5 +1,5 @@ -import { TestImagePath } from '../../../../test/TestImagePath'; -import { decodeStack } from '../decodeStack'; +import type { TestImagePath } from '../../../../test/TestImagePath.js'; +import { decodeStack } from '../decodeStack.js'; test.each([ { diff --git a/src/stack/load/decodeStack.ts b/src/stack/load/decodeStack.ts index ed4f23345..24f84d3f9 100644 --- a/src/stack/load/decodeStack.ts +++ b/src/stack/load/decodeStack.ts @@ -1,8 +1,9 @@ import imageType from 'image-type'; +import { match } from 'ts-pattern'; -import { Stack } from '../../Stack'; +import type { Stack } from '../../Stack.js'; -import { decodeStackFromTiff } from './decodeTiff'; +import { decodeStackFromTiff } from './decodeTiff.js'; /** * Decode input data and create stack. Data format is automatically detected. @@ -17,10 +18,9 @@ export function decodeStack(data: ArrayBufferView): Stack { data.byteLength, ); const type = imageType(typedArray); - switch (type?.mime) { - case 'image/tiff': - return decodeStackFromTiff(typedArray); - default: + return match(type) + .with({ mime: 'image/tiff' }, () => decodeStackFromTiff(typedArray)) + .otherwise(() => { throw new RangeError(`invalid data format: ${type?.mime}`); - } + }); } diff --git a/src/stack/load/decodeTiff.ts b/src/stack/load/decodeTiff.ts index 72d932e5f..503078310 100644 --- a/src/stack/load/decodeTiff.ts +++ b/src/stack/load/decodeTiff.ts @@ -1,7 +1,7 @@ import { decode } from 'tiff'; -import { Stack } from '../../Stack'; -import { getImageFromIFD } from '../../load/decodeTiff'; +import { Stack } from '../../Stack.js'; +import { getImageFromIFD } from '../../load/decodeTiff.js'; /** * Decode a TIFF and create a stack of images. diff --git a/src/stack/utils/__tests__/checkProcessable.test.ts b/src/stack/utils/__tests__/checkProcessable.test.ts index cb81119bf..0a1748497 100644 --- a/src/stack/utils/__tests__/checkProcessable.test.ts +++ b/src/stack/utils/__tests__/checkProcessable.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { Stack } from '../../../Stack'; -import { checkProcessable } from '../checkProcessable'; +import { Image } from '../../../Image.js'; +import { Stack } from '../../../Stack.js'; +import { checkProcessable } from '../checkProcessable.js'; test('should throw if images have different sizes', () => { const image1 = testUtils.createGreyImage([[1, 2, 3, 4]]); diff --git a/src/stack/utils/checkImagesValid.ts b/src/stack/utils/checkImagesValid.ts index d77fe47ab..b7188b590 100644 --- a/src/stack/utils/checkImagesValid.ts +++ b/src/stack/utils/checkImagesValid.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import type { Image } from '../../Image.js'; /** * Verify all images of array have the same bit depth and color model. diff --git a/src/stack/utils/checkProcessable.ts b/src/stack/utils/checkProcessable.ts index 9640331ba..c6ab05756 100644 --- a/src/stack/utils/checkProcessable.ts +++ b/src/stack/utils/checkProcessable.ts @@ -1,5 +1,5 @@ -import { Stack } from '../../Stack'; -import { format } from '../../utils/validators/checkProcessable'; +import type { Stack } from '../../Stack.js'; +import { format } from '../../utils/validators/checkProcessable.js'; interface CheckStackOptions { /** diff --git a/src/stack/utils/getStackFromFolder.ts b/src/stack/utils/getStackFromFolder.ts index 4924c7813..9dad68e4f 100644 --- a/src/stack/utils/getStackFromFolder.ts +++ b/src/stack/utils/getStackFromFolder.ts @@ -1,8 +1,8 @@ import { readdirSync } from 'node:fs'; import { join } from 'node:path'; -import { Stack } from '../../Stack'; -import { readSync } from '../../load'; +import { Stack } from '../../Stack.js'; +import { readSync } from '../../load/index.js'; /** * Create a stack with all images at a given path. diff --git a/src/utils/__tests__/assert.test.ts b/src/utils/__tests__/assert.test.ts index 167f970a0..3b04f11a4 100644 --- a/src/utils/__tests__/assert.test.ts +++ b/src/utils/__tests__/assert.test.ts @@ -1,4 +1,4 @@ -import { assert } from '../validators/assert'; +import { assert } from '../validators/assert.js'; test('should restrict type', () => { const variable: number | undefined = 3; diff --git a/src/utils/__tests__/boolToNumber.test.ts b/src/utils/__tests__/boolToNumber.test.ts index b43cc883e..c385213a3 100644 --- a/src/utils/__tests__/boolToNumber.test.ts +++ b/src/utils/__tests__/boolToNumber.test.ts @@ -1,4 +1,4 @@ -import { boolToNumber } from '../boolToNumber'; +import { boolToNumber } from '../boolToNumber.js'; test('convert number to number', () => { expect(boolToNumber(1)).toBe(1); diff --git a/src/utils/__tests__/borderIterator.test.ts b/src/utils/__tests__/borderIterator.test.ts index 833d6186b..880d97447 100644 --- a/src/utils/__tests__/borderIterator.test.ts +++ b/src/utils/__tests__/borderIterator.test.ts @@ -1,5 +1,6 @@ -import { Image, Mask } from '../..'; -import { borderIterator } from '../borderIterator'; +import { Image } from '../../Image.js'; +import type { Mask } from '../../Mask.js'; +import { borderIterator } from '../borderIterator.js'; test('3x4 image', () => { const image = new Image(4, 3); diff --git a/src/utils/__tests__/checkKernel.test.ts b/src/utils/__tests__/checkKernel.test.ts index c6e10aa31..c47d3f6fe 100644 --- a/src/utils/__tests__/checkKernel.test.ts +++ b/src/utils/__tests__/checkKernel.test.ts @@ -1,4 +1,4 @@ -import { checkKernel } from '../validators/checkKernel'; +import { checkKernel } from '../validators/checkKernel.js'; test('should throw', () => { const kernel = [ diff --git a/src/utils/__tests__/checkProcessable.test.ts b/src/utils/__tests__/checkProcessable.test.ts index 941c352eb..96d59bb47 100644 --- a/src/utils/__tests__/checkProcessable.test.ts +++ b/src/utils/__tests__/checkProcessable.test.ts @@ -1,4 +1,4 @@ -import checkProcessable from '../validators/checkProcessable'; +import checkProcessable from '../validators/checkProcessable.js'; test('wrong bit depth', () => { const img = testUtils.createGreyImage([ diff --git a/src/utils/__tests__/clamp.test.ts b/src/utils/__tests__/clamp.test.ts index 35cce3813..11698f14b 100644 --- a/src/utils/__tests__/clamp.test.ts +++ b/src/utils/__tests__/clamp.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { getClamp } from '../clamp'; +import { Image } from '../../Image.js'; +import { getClamp } from '../clamp.js'; test("clamp 65'536", () => { const image = new Image(2, 1, { diff --git a/src/utils/__tests__/copyData.test.ts b/src/utils/__tests__/copyData.test.ts index 133a139ec..de3722746 100644 --- a/src/utils/__tests__/copyData.test.ts +++ b/src/utils/__tests__/copyData.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../..'; -import { copyData } from '../copyData'; +import { Image } from '../../Image.js'; +import { copyData } from '../copyData.js'; test('2x3 GREY image', () => { const source = testUtils.createGreyImage([ diff --git a/src/utils/__tests__/getDefaultColor.test.ts b/src/utils/__tests__/getDefaultColor.test.ts index 0abb193ba..a1c302d51 100644 --- a/src/utils/__tests__/getDefaultColor.test.ts +++ b/src/utils/__tests__/getDefaultColor.test.ts @@ -1,4 +1,4 @@ -import { getDefaultColor } from '../getDefaultColor'; +import { getDefaultColor } from '../getDefaultColor.js'; test('GREY', () => { const image = testUtils.createGreyImage([ diff --git a/src/utils/__tests__/getIndex.test.ts b/src/utils/__tests__/getIndex.test.ts index f72d667a0..52068181d 100644 --- a/src/utils/__tests__/getIndex.test.ts +++ b/src/utils/__tests__/getIndex.test.ts @@ -1,5 +1,6 @@ -import { Image, Mask } from '../..'; -import { getIndex } from '../getIndex'; +import { Image } from '../../Image.js'; +import { Mask } from '../../Mask.js'; +import { getIndex } from '../getIndex.js'; test('mask, index should increment regularly', () => { const mask = new Mask(3, 4); diff --git a/src/utils/__tests__/getMinMax.test.ts b/src/utils/__tests__/getMinMax.test.ts index 183574f22..a89c0a3d6 100644 --- a/src/utils/__tests__/getMinMax.test.ts +++ b/src/utils/__tests__/getMinMax.test.ts @@ -1,4 +1,4 @@ -import { getMinMax } from '../getMinMax'; +import { getMinMax } from '../getMinMax.js'; test('grey image', () => { const image = testUtils.createGreyImage([[1, 2, 3, 4, 5, 7, 4, 9, 6]]); diff --git a/src/utils/__tests__/getOutputImage.test.ts b/src/utils/__tests__/getOutputImage.test.ts index 1f98fb5f0..27386577b 100644 --- a/src/utils/__tests__/getOutputImage.test.ts +++ b/src/utils/__tests__/getOutputImage.test.ts @@ -1,12 +1,12 @@ -import { Mask } from '../..'; -import { Image } from '../../Image'; -import { ImageColorModel } from '../constants/colorModels'; +import { Image } from '../../Image.js'; +import { Mask } from '../../Mask.js'; +import { ImageColorModel } from '../constants/colorModels.js'; import { getOutputImage, imageToOutputMask, maskToOutputImage, maskToOutputMask, -} from '../getOutputImage'; +} from '../getOutputImage.js'; describe('getOutputImage', () => { it('should default to creating an empty image', () => { diff --git a/src/utils/__tests__/interpolateBorder.test.ts b/src/utils/__tests__/interpolateBorder.test.ts index e4ad243e2..3ffac2555 100644 --- a/src/utils/__tests__/interpolateBorder.test.ts +++ b/src/utils/__tests__/interpolateBorder.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../Image'; +import { Image } from '../../Image.js'; import { getBorderInterpolation, interpolateConstantPoint, @@ -6,7 +6,7 @@ import { interpolateReplicatePoint, interpolateWrapPoint, interpolateReflect101Point, -} from '../interpolateBorder'; +} from '../interpolateBorder.js'; test('in range', () => { expect(interpolateReflectPoint(0, 10)).toBe(0); @@ -91,7 +91,5 @@ test('REFLECT_101 - positive', () => { test('unknown type', () => { // @ts-expect-error: testing JS problem - expect(() => getBorderInterpolation('unknown', 5)).toThrow( - 'invalid border type: unknown', - ); + expect(() => getBorderInterpolation('unknown', 5)).toThrow(/unknown/); }); diff --git a/src/utils/__tests__/sampleBackgroundPoints.test.ts b/src/utils/__tests__/sampleBackgroundPoints.test.ts index 0c85a68c7..86263c7be 100644 --- a/src/utils/__tests__/sampleBackgroundPoints.test.ts +++ b/src/utils/__tests__/sampleBackgroundPoints.test.ts @@ -1,5 +1,5 @@ -import { getMaskFromCannyEdge } from '../../operations/getMaskFromCannyEdge'; -import { sampleBackgroundPoints } from '../sampleBackgroundPoints'; +import { getMaskFromCannyEdge } from '../../operations/getMaskFromCannyEdge.js'; +import { sampleBackgroundPoints } from '../sampleBackgroundPoints.js'; test('basic test', () => { const image = testUtils.createGreyImage([ diff --git a/src/utils/__tests__/setBlendedPixel.test.ts b/src/utils/__tests__/setBlendedPixel.test.ts index 15db5777a..381596152 100644 --- a/src/utils/__tests__/setBlendedPixel.test.ts +++ b/src/utils/__tests__/setBlendedPixel.test.ts @@ -1,4 +1,4 @@ -import { setBlendedPixel } from '../setBlendedPixel'; +import { setBlendedPixel } from '../setBlendedPixel.js'; test('GREYA image, default options', () => { const image = testUtils.createGreyaImage([ diff --git a/src/utils/__tests__/setBlendedVisiblePixel.test.ts b/src/utils/__tests__/setBlendedVisiblePixel.test.ts index 471e933e1..de39733bf 100644 --- a/src/utils/__tests__/setBlendedVisiblePixel.test.ts +++ b/src/utils/__tests__/setBlendedVisiblePixel.test.ts @@ -1,4 +1,4 @@ -import { setBlendedVisiblePixel } from '../setBlendedVisiblePixel'; +import { setBlendedVisiblePixel } from '../setBlendedVisiblePixel.js'; test('GREYA image, default options', () => { const image = testUtils.createGreyaImage([ diff --git a/src/utils/arrayPointsToObjects.ts b/src/utils/arrayPointsToObjects.ts index 4d14a8b1b..8cbf69207 100644 --- a/src/utils/arrayPointsToObjects.ts +++ b/src/utils/arrayPointsToObjects.ts @@ -1,4 +1,4 @@ -import { ArrayPoint, Point } from './geometry/points'; +import type { ArrayPoint, Point } from './geometry/points.js'; /** * Convert object points into array points. diff --git a/src/utils/boolToNumber.ts b/src/utils/boolToNumber.ts index 431c124cc..dbf0b08da 100644 --- a/src/utils/boolToNumber.ts +++ b/src/utils/boolToNumber.ts @@ -1,4 +1,4 @@ -import { BitValue } from '../Mask'; +import type { BitValue } from '../Mask.js'; /** * Converts a bit value to the corresponding number. diff --git a/src/utils/borderIterator.ts b/src/utils/borderIterator.ts index 534ca56ca..187d64c79 100644 --- a/src/utils/borderIterator.ts +++ b/src/utils/borderIterator.ts @@ -1,4 +1,5 @@ -import { Mask, Image } from '..'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; /** * Create function that allows to iterate on the pixels of the border of an image. diff --git a/src/utils/clamp.ts b/src/utils/clamp.ts index c9f9b473b..6596ddefc 100644 --- a/src/utils/clamp.ts +++ b/src/utils/clamp.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; +import type { Image } from '../Image.js'; -import { ClampFunction } from './utils.types'; -import { assert } from './validators/assert'; +import type { ClampFunction } from './utils.types.js'; +import { assert } from './validators/assert.js'; /** * Get the clamp function for an image (depends on the image bit depth). diff --git a/src/utils/constants/__tests__/channelLabels.test.ts b/src/utils/constants/__tests__/channelLabels.test.ts index 2a4ffb0a4..1cfee45af 100644 --- a/src/utils/constants/__tests__/channelLabels.test.ts +++ b/src/utils/constants/__tests__/channelLabels.test.ts @@ -1,6 +1,6 @@ -import { Image } from '../../../Image'; -import { channelLabels } from '../channelLabels'; -import { ImageColorModel } from '../colorModels'; +import { Image } from '../../../Image.js'; +import { channelLabels } from '../channelLabels.js'; +import { ImageColorModel } from '../colorModels.js'; test.each([ { diff --git a/src/utils/constants/channelLabels.ts b/src/utils/constants/channelLabels.ts index a05bb4f3b..ad49db278 100644 --- a/src/utils/constants/channelLabels.ts +++ b/src/utils/constants/channelLabels.ts @@ -1,4 +1,4 @@ -import { ImageColorModel } from './colorModels'; +import type { ImageColorModel } from './colorModels.js'; export const channelLabels = { GREY: ['Grey'], diff --git a/src/utils/copyData.ts b/src/utils/copyData.ts index d0cc0a927..4e3171702 100644 --- a/src/utils/copyData.ts +++ b/src/utils/copyData.ts @@ -1,4 +1,5 @@ -import { Image, Mask } from '..'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; export function copyData(source: Image, target: Image): void; export function copyData(source: Mask, target: Mask): void; diff --git a/src/utils/geometry/__tests__/angles.test.ts b/src/utils/geometry/__tests__/angles.test.ts index bbfc0ffdf..bcbe74692 100644 --- a/src/utils/geometry/__tests__/angles.test.ts +++ b/src/utils/geometry/__tests__/angles.test.ts @@ -1,5 +1,5 @@ -import { toDegrees } from '../angles'; -import { rotate } from '../points'; +import { toDegrees } from '../angles.js'; +import { rotate } from '../points.js'; test('toDegrees', () => { expect(toDegrees(Math.PI / 2)).toBe(90); diff --git a/src/utils/geometry/__tests__/getCirclePoints.test.ts b/src/utils/geometry/__tests__/getCirclePoints.test.ts index 18b7b62e8..609922646 100644 --- a/src/utils/geometry/__tests__/getCirclePoints.test.ts +++ b/src/utils/geometry/__tests__/getCirclePoints.test.ts @@ -1,10 +1,10 @@ -import { Image } from '../../../Image'; +import { Image } from '../../../Image.js'; import { getCirclePoints, getCompassPoints, getFilledCirclePoints, getLinePoints, -} from '../getCirclePoints'; +} from '../getCirclePoints.js'; test('circle with radius 1', () => { expect(getCirclePoints(1)).toStrictEqual([ diff --git a/src/utils/geometry/__tests__/lines.test.ts b/src/utils/geometry/__tests__/lines.test.ts index d11449922..0348e320c 100644 --- a/src/utils/geometry/__tests__/lines.test.ts +++ b/src/utils/geometry/__tests__/lines.test.ts @@ -1,4 +1,4 @@ -import { getLineLength } from '../lines'; +import { getLineLength } from '../lines.js'; describe('getLineLength', () => { it('length zero', () => { diff --git a/src/utils/geometry/__tests__/points.test.ts b/src/utils/geometry/__tests__/points.test.ts index 60a58adbe..0280733d3 100644 --- a/src/utils/geometry/__tests__/points.test.ts +++ b/src/utils/geometry/__tests__/points.test.ts @@ -1,4 +1,4 @@ -import { normalize, sortByColumnRow } from '../points'; +import { normalize, sortByColumnRow } from '../points.js'; describe('normalize', () => { it('simple numbers', () => { diff --git a/src/utils/geometry/__tests__/polygons.test.ts b/src/utils/geometry/__tests__/polygons.test.ts index ba25b848a..9cdc86f64 100644 --- a/src/utils/geometry/__tests__/polygons.test.ts +++ b/src/utils/geometry/__tests__/polygons.test.ts @@ -1,4 +1,4 @@ -import { getPolygonArea, getPolygonPerimeter } from '../polygons'; +import { getPolygonArea, getPolygonPerimeter } from '../polygons.js'; describe('getPolygonPerimeter', () => { it('perimeter zero', () => { diff --git a/src/utils/geometry/__tests__/removeClosePoints.test.ts b/src/utils/geometry/__tests__/removeClosePoints.test.ts index 10d167458..6b927c4c0 100644 --- a/src/utils/geometry/__tests__/removeClosePoints.test.ts +++ b/src/utils/geometry/__tests__/removeClosePoints.test.ts @@ -1,5 +1,5 @@ -import { getExtrema } from '../../../compute/getExtrema'; -import { removeClosePoints } from '../removeClosePoints'; +import { getExtrema } from '../../../compute/getExtrema.js'; +import { removeClosePoints } from '../removeClosePoints.js'; test('combine minimum points on 5x5 image', () => { const image = testUtils.createGreyImage([ diff --git a/src/utils/geometry/angles.ts b/src/utils/geometry/angles.ts index a82f9baf7..b772f0113 100644 --- a/src/utils/geometry/angles.ts +++ b/src/utils/geometry/angles.ts @@ -1,4 +1,5 @@ -import { difference, dot, normalize, Point } from './points'; +import type { Point } from './points.js'; +import { difference, dot, normalize } from './points.js'; /** * Convert radians to degrees. diff --git a/src/utils/geometry/getCirclePoints.ts b/src/utils/geometry/getCirclePoints.ts index 758a14af2..c328c83ba 100644 --- a/src/utils/geometry/getCirclePoints.ts +++ b/src/utils/geometry/getCirclePoints.ts @@ -1,9 +1,9 @@ import { circle, line } from 'bresenham-zingl'; -import { deleteDuplicates } from '../../draw/utils/deleteDuplicates'; -import { Point } from '../../geometry'; +import { deleteDuplicates } from '../../draw/utils/deleteDuplicates.js'; +import type { Point } from '../../geometry/index.js'; -import { sortByColumnRow } from './points'; +import { sortByColumnRow } from './points.js'; /** * Get the coordinates of the points on a circle. The reference is the center of the circle. diff --git a/src/utils/geometry/index.ts b/src/utils/geometry/index.ts index a67c56cd3..23adfb194 100644 --- a/src/utils/geometry/index.ts +++ b/src/utils/geometry/index.ts @@ -1 +1 @@ -export * from './removeClosePoints'; +export * from './removeClosePoints.js'; diff --git a/src/utils/geometry/lines.ts b/src/utils/geometry/lines.ts index 2f929e4df..48053ce0e 100644 --- a/src/utils/geometry/lines.ts +++ b/src/utils/geometry/lines.ts @@ -1,4 +1,4 @@ -import { Point } from './points'; +import type { Point } from './points.js'; export interface Line { /** diff --git a/src/utils/geometry/polygons.ts b/src/utils/geometry/polygons.ts index 6e411bf68..dff60c398 100644 --- a/src/utils/geometry/polygons.ts +++ b/src/utils/geometry/polygons.ts @@ -1,5 +1,5 @@ -import { getLineLength } from './lines'; -import { Point } from './points'; +import { getLineLength } from './lines.js'; +import type { Point } from './points.js'; /** * Compute the perimeter of a polygon. diff --git a/src/utils/geometry/removeClosePoints.ts b/src/utils/geometry/removeClosePoints.ts index bf7cfd7d7..5bcf7066a 100644 --- a/src/utils/geometry/removeClosePoints.ts +++ b/src/utils/geometry/removeClosePoints.ts @@ -1,6 +1,6 @@ -import { Image } from '../..'; +import type { Image } from '../../Image.js'; -import { Point } from './points'; +import type { Point } from './points.js'; export interface RemoveClosePointsOptions { /** diff --git a/src/utils/getDefaultColor.ts b/src/utils/getDefaultColor.ts index 12f59bdfa..789823e52 100644 --- a/src/utils/getDefaultColor.ts +++ b/src/utils/getDefaultColor.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import { match } from 'ts-pattern'; -import { assert } from './validators/assert'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; /** * Get the default color for a given color model. @@ -10,18 +10,11 @@ import { assert } from './validators/assert'; * @returns Default color. */ export function getDefaultColor(image: Image | Mask): number[] { - switch (image.colorModel) { - case 'GREY': - return [0]; - case 'GREYA': - return [0, image.maxValue]; - case 'RGB': - return [0, 0, 0]; - case 'RGBA': - return [0, 0, 0, image.maxValue]; - case 'BINARY': - return [1]; - default: - assert(false, `invalid image color model: ${image.colorModel}`); - } + return match(image.colorModel) + .with('GREY', () => [0]) + .with('GREYA', () => [0, image.maxValue]) + .with('RGB', () => [0, 0, 0]) + .with('RGBA', () => [0, 0, 0, image.maxValue]) + .with('BINARY', () => [1]) + .exhaustive(); } diff --git a/src/utils/getIndex.ts b/src/utils/getIndex.ts index 72a08da3f..8b9632237 100644 --- a/src/utils/getIndex.ts +++ b/src/utils/getIndex.ts @@ -1,4 +1,5 @@ -import { Image, Mask } from '..'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; export function getIndex( column: number, diff --git a/src/utils/getMinMax.ts b/src/utils/getMinMax.ts index bf2b7cd64..e98895753 100644 --- a/src/utils/getMinMax.ts +++ b/src/utils/getMinMax.ts @@ -1,4 +1,4 @@ -import { Image } from '..'; +import type { Image } from '../Image.js'; /** * Find the min and max values of each channel of the image. diff --git a/src/utils/getOutputImage.ts b/src/utils/getOutputImage.ts index 0bce4b111..8cbb50c8c 100644 --- a/src/utils/getOutputImage.ts +++ b/src/utils/getOutputImage.ts @@ -1,7 +1,8 @@ -import { CreateFromOptions, Image } from '../Image'; -import { Mask } from '../Mask'; +import type { CreateFromOptions } from '../Image.js'; +import { Image } from '../Image.js'; +import { Mask } from '../Mask.js'; -import { copyData } from './copyData'; +import { copyData } from './copyData.js'; export interface OutOptions { /** @@ -123,9 +124,9 @@ export function imageToOutputMask( } } -function checkRequirements( +function checkRequirements( requirements: ReqType, - out: OutType, + out: ReqType, ): void { type Keys = keyof ReqType; for (const property in requirements) { diff --git a/src/utils/interpolateBorder.ts b/src/utils/interpolateBorder.ts index fd9d02d93..963f49fdf 100644 --- a/src/utils/interpolateBorder.ts +++ b/src/utils/interpolateBorder.ts @@ -1,6 +1,8 @@ -import { Image } from '../Image'; +import { match } from 'ts-pattern'; -import { BorderInterpolationFunction } from './utils.types'; +import type { Image } from '../Image.js'; + +import type { BorderInterpolationFunction } from './utils.types.js'; export const BorderType = { CONSTANT: 'constant', @@ -24,20 +26,13 @@ export function getBorderInterpolation( type: BorderType, value: number, ): BorderInterpolationFunction { - switch (type) { - case 'constant': - return getInterpolateConstant(value); - case 'replicate': - return interpolateReplicate; - case 'reflect': - return interpolateReflect; - case 'reflect101': - return interpolateReflect101; - case 'wrap': - return interpolateWrap; - default: - throw new RangeError(`invalid border type: ${type}`); - } + return match(type) + .with('constant', () => getInterpolateConstant(value)) + .with('replicate', () => interpolateReplicate) + .with('reflect', () => interpolateReflect) + .with('reflect101', () => interpolateReflect101) + .with('wrap', () => interpolateWrap) + .exhaustive(); } function checkRange(point: number, length: number): void { diff --git a/src/utils/interpolatePixel.ts b/src/utils/interpolatePixel.ts index de9203391..3f583ebe6 100644 --- a/src/utils/interpolatePixel.ts +++ b/src/utils/interpolatePixel.ts @@ -1,7 +1,12 @@ -import { Image } from '../Image'; +import { match } from 'ts-pattern'; -import { round } from './round'; -import { BorderInterpolationFunction, ClampFunction } from './utils.types'; +import type { Image } from '../Image.js'; + +import { round } from './round.js'; +import type { + BorderInterpolationFunction, + ClampFunction, +} from './utils.types.js'; export const InterpolationType = { NEAREST: 'nearest', @@ -29,20 +34,11 @@ type InterpolationFunction = ( export function getInterpolationFunction( interpolationType: InterpolationType, ): InterpolationFunction { - switch (interpolationType) { - case 'nearest': { - return interpolateNearest; - } - case 'bilinear': { - return interpolateBilinear; - } - case 'bicubic': { - return interpolateBicubic; - } - default: { - throw new RangeError(`invalid interpolationType: ${interpolationType}`); - } - } + return match(interpolationType) + .with('nearest', () => interpolateNearest) + .with('bilinear', () => interpolateBilinear) + .with('bicubic', () => interpolateBicubic) + .exhaustive(); } /** diff --git a/src/utils/sampleBackgroundPoints.ts b/src/utils/sampleBackgroundPoints.ts index 7e0d518a5..2e8ad05a1 100644 --- a/src/utils/sampleBackgroundPoints.ts +++ b/src/utils/sampleBackgroundPoints.ts @@ -1,6 +1,6 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; -import { Point } from '../geometry'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; +import type { Point } from '../geometry/index.js'; interface SampleBackgroundPointsOptions { /** diff --git a/src/utils/setBlendedPixel.ts b/src/utils/setBlendedPixel.ts index 324dfcaa0..0a039938b 100644 --- a/src/utils/setBlendedPixel.ts +++ b/src/utils/setBlendedPixel.ts @@ -1,8 +1,8 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; -import { getDefaultColor } from './getDefaultColor'; -import { assert } from './validators/assert'; +import { getDefaultColor } from './getDefaultColor.js'; +import { assert } from './validators/assert.js'; /** * Blend the given pixel with the pixel at the specified location in the image. diff --git a/src/utils/setBlendedVisiblePixel.ts b/src/utils/setBlendedVisiblePixel.ts index d78ae865e..dad822667 100644 --- a/src/utils/setBlendedVisiblePixel.ts +++ b/src/utils/setBlendedVisiblePixel.ts @@ -1,7 +1,7 @@ -import { Image } from '../Image'; -import { Mask } from '../Mask'; +import type { Image } from '../Image.js'; +import type { Mask } from '../Mask.js'; -import { setBlendedPixel } from './setBlendedPixel'; +import { setBlendedPixel } from './setBlendedPixel.js'; /** * Blend the given pixel with the pixel at the specified location in the image if the pixel is in image's bounds. diff --git a/src/utils/utils.types.ts b/src/utils/utils.types.ts index 5ce3c032e..b7483adfb 100644 --- a/src/utils/utils.types.ts +++ b/src/utils/utils.types.ts @@ -1,4 +1,4 @@ -import { Image } from '../Image'; +import type { Image } from '../Image.js'; export type ClampFunction = (value: number) => number; diff --git a/src/utils/validators/checkPointIsInteger.ts b/src/utils/validators/checkPointIsInteger.ts index 42b130fb8..fddd2934c 100644 --- a/src/utils/validators/checkPointIsInteger.ts +++ b/src/utils/validators/checkPointIsInteger.ts @@ -1,4 +1,4 @@ -import { Point } from '../..'; +import type { Point } from '../../geometry/index.js'; /** * Check that the coordinates of a point are integers. diff --git a/src/utils/validators/checkProcessable.ts b/src/utils/validators/checkProcessable.ts index e8ddf60a9..99117f1f3 100644 --- a/src/utils/validators/checkProcessable.ts +++ b/src/utils/validators/checkProcessable.ts @@ -1,6 +1,7 @@ -import { BitDepth, Image, ImageColorModel, Mask } from '../..'; +import type { BitDepth, Image } from '../../Image.js'; +import type { Mask } from '../../Mask.js'; +import type { ImageColorModel } from '../constants/colorModels.js'; -// @ts-expect-error Intl types don't exist yet const formatter = new Intl.ListFormat('en', { type: 'disjunction' }); interface CheckOptions { diff --git a/src/utils/validators/validators.ts b/src/utils/validators/validators.ts index 756465c70..80ca1d1f3 100644 --- a/src/utils/validators/validators.ts +++ b/src/utils/validators/validators.ts @@ -1,5 +1,5 @@ -import { Image } from '../../Image'; -import { Mask } from '../../Mask'; +import type { Image } from '../../Image.js'; +import type { Mask } from '../../Mask.js'; /** * Validate an array of channels. diff --git a/tailwind.config.js b/tailwind.config.js index 196957bbf..a9f64e821 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,4 +1,4 @@ -module.exports = { +export default { content: ['./index.html', './demo/**/*.{vue,js,ts,jsx,tsx}'], plugins: [require('@tailwindcss/forms')], }; diff --git a/test/__tests__/jestMatchers.test.ts b/test/__tests__/jestMatchers.test.ts index 3007d9fda..94508e481 100644 --- a/test/__tests__/jestMatchers.test.ts +++ b/test/__tests__/jestMatchers.test.ts @@ -1,5 +1,5 @@ -import { Image } from '../../src'; -import { Mask } from '../../src/Mask'; +import { Mask } from '../../src/Mask.js'; +import { Image } from '../../src/index.js'; describe('toMatchImage', () => { it('should load and match', () => { diff --git a/test/__tests__/testUtils.test.ts b/test/__tests__/testUtils.test.ts index 9fcbbb18b..0cbcaf81b 100644 --- a/test/__tests__/testUtils.test.ts +++ b/test/__tests__/testUtils.test.ts @@ -1,4 +1,4 @@ -import { Image } from '../../src'; +import { Image } from '../../src/index.js'; describe('load', () => { it('should load the image synchronously', () => { diff --git a/test/createImageFromData.ts b/test/createImageFromData.ts index e13e7d8c5..66fd32d87 100644 --- a/test/createImageFromData.ts +++ b/test/createImageFromData.ts @@ -1,17 +1,15 @@ -import { +import type { BitDepth, - Image, ImageColorModel, ImageDataArray, ImageOptions, -} from '../src'; -import { colorModels } from '../src/utils/constants/colorModels'; +} from '../src/index.js'; +import { Image, colorModels } from '../src/index.js'; export type CreateImageOptions = Pick; /** * Create a new Image object from image data. - * * @param data - Image data. * @param colorModel - Image color model. * @param options - Additional options to create the image. @@ -32,7 +30,6 @@ export function createImageFromData( /** * Create a new Image object from a 2D matrix. - * * @param data - Image data. * @param colorModel - Image color model. * @param bitDepth - Bit depth. @@ -77,7 +74,6 @@ function createImageFrom2DArray( /** * Create a new Image object from data encoded in a string. - * * @param data - Image data. * @param colorModel - Image color model. * @param bitDepth - Bit depth. @@ -96,7 +92,7 @@ function createImageFromString( const imageData = createDataArray(height * width * channels, bitDepth); for (let row = 0; row < height; row++) { const line = lines[row].trim(); - const values = line.split(/[^0-9]+/).map((v) => parseInt(v, 10)); + const values = line.split(/[^0-9]+/).map((v) => Number.parseInt(v, 10)); if (values.length % channels !== 0) { throw new RangeError( `length of row ${row} (${values.length}) is not a multiple of channels (${channels})`, @@ -126,7 +122,6 @@ function createImageFromString( /** * Create a new data typed array for an image. - * * @param size - Total size of the data array. * @param bitDepth - Bit depth. * @returns The created array. diff --git a/test/createMask.ts b/test/createMask.ts index 3f58e81ea..3ce249864 100644 --- a/test/createMask.ts +++ b/test/createMask.ts @@ -1,8 +1,7 @@ -import { Mask } from '../src'; +import { Mask } from '../src/Mask.js'; /** * Create a new Mask object from mask data. - * * @param data - Mask data. * @returns The new mask. */ @@ -16,7 +15,6 @@ export function createMask(data: number[][] | string): Mask { /** * Create a new Mask object from a 2D matrix. - * * @param data - Mask data. * @returns The new mask. */ @@ -42,7 +40,6 @@ function createMaskFrom2DArray(data: number[][]): Mask { /** * Create a new Mask object from data encoded in a string. - * * @param data - Mask data. * @returns The new mask. */ @@ -54,7 +51,7 @@ function createMaskFromString(data: string): Mask { const imageData = new Uint8Array(height * width); for (let row = 0; row < height; row++) { const line = lines[row].trim(); - const values = line.split(/[^0-9]+/).map((v) => parseInt(v, 10)); + const values = line.split(/[^0-9]+/).map((v) => Number.parseInt(v, 10)); if (values.length !== width) { throw new RangeError( diff --git a/test/jest.d.ts b/test/jest.d.ts index 614ff00d2..b4d398a87 100644 --- a/test/jest.d.ts +++ b/test/jest.d.ts @@ -1,24 +1,22 @@ -import { MatchImageSnapshotOptions } from 'jest-image-snapshot'; +import type { MatchImageSnapshotOptions } from 'jest-image-snapshot'; -import { Image } from '../src'; -import { Mask } from '../src/Mask'; +import type { Mask } from '../src/Mask.js'; +import type { Image } from '../src/index.js'; -import { TestImagePath } from './TestImagePath'; -import { JestMatcherOptions } from './jestMatchers'; +import type { TestImagePath } from './TestImagePath.js'; +import type { JestMatcherOptions } from './jestMatchers.js'; declare global { namespace jest { interface Matchers { /** * Match an existing image object. - * * @param expectedImage - The expected image. */ toMatchImage(expectedImage: Image, options?: JestMatcherOptions): R; /** * Match an image from the test/img directory. - * * @param expectedImagePath - The path to the expected image. */ toMatchImage( @@ -28,7 +26,6 @@ declare global { /** * Match an image by providing the expected data matrix. - * * @param expectedImageData - The expected image data matrix. */ toMatchImageData( @@ -38,7 +35,6 @@ declare global { /** * Match an image by providing the expected data. - * * @param expectedImageData - The expected image data. */ @@ -49,21 +45,18 @@ declare global { /** * Match an existing image object. - * * @param expectedMask - The expected image. */ toMatchMask(expectedMask: Mask): R; /** * Match an image by providing the expected data matrix. - * * @param expectedImageData - The expected image data matrix. */ toMatchMaskData(expectedImageData: number[][]): R; /** * Match an image by providing the expected data. - * * @param expectedImageData - The expected image data. */ @@ -72,7 +65,6 @@ declare global { /** * Match an image snapshot. Can be used on Image and Mask objects as well * as PNG-encoded data. - * * @param options - Options of the jest-image-snapshot library. * @see {@link https://github.com/americanexpress/jest-image-snapshot} */ diff --git a/test/jestMatchers.ts b/test/jestMatchers.ts index 091322303..ee947602a 100644 --- a/test/jestMatchers.ts +++ b/test/jestMatchers.ts @@ -1,16 +1,16 @@ +/* eslint-disable no-invalid-this */ // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// -import { - MatchImageSnapshotOptions, - configureToMatchImageSnapshot, -} from 'jest-image-snapshot'; +import type { MatcherState } from '@vitest/expect'; +import type { MatchImageSnapshotOptions } from 'jest-image-snapshot'; +import { configureToMatchImageSnapshot } from 'jest-image-snapshot'; -import { encodePng, Image } from '../src'; -import { Mask } from '../src/Mask'; +import type { Image } from '../src/index.js'; +import { encodePng, Mask } from '../src/index.js'; -import { TestImagePath } from './TestImagePath'; -import { createImageFromData } from './createImageFromData'; +import type { TestImagePath } from './TestImagePath.js'; +import { createImageFromData } from './createImageFromData.js'; interface MatcherResult { message: () => string; @@ -20,7 +20,6 @@ interface MatcherResult { export interface JestMatcherOptions { /** * Acceptable difference between the received image and the expected for each channel. - * * @default `0` */ error?: number; @@ -28,15 +27,13 @@ export interface JestMatcherOptions { /** * Match a received image to an expected image. - * - * @param this - Jest matcher context. * @param received - Received image. * @param expected - Expected image. * @param options - Jest matcher options. * @returns - Jest matcher result. */ export function toMatchImage( - this: jest.MatcherContext, + this: MatcherState, received: Image, expected: Image | TestImagePath, options: JestMatcherOptions = {}, @@ -94,15 +91,13 @@ export function toMatchImage( /** * Match a received image to expected image data. - * - * @param this - Jest matcher context. * @param received - Received image. * @param expectedData - Expected image data. * @param options - Jest matcher options. * @returns - Jest matcher result. */ export function toMatchImageData( - this: jest.MatcherContext, + this: MatcherState, received: Image, expectedData: number[][] | string, options: JestMatcherOptions = {}, @@ -115,14 +110,12 @@ export function toMatchImageData( /** * Match a received mask to an expected mask. - * - * @param this - Jest matcher context. * @param received - Received mask. * @param expected - Expected mask. * @returns - Jest matcher result. */ export function toMatchMask( - this: jest.MatcherContext, + this: MatcherState, received: Mask, expected: Image | Mask, ): MatcherResult { @@ -153,14 +146,12 @@ export function toMatchMask( /** * Match a received mask to expected mask data. - * - * @param this - Jest matcher context. * @param received - Received mask. * @param expectedData - Expected mask data. * @returns - Jest matcher result. */ export function toMatchMaskData( - this: jest.MatcherContext, + this: MatcherState, received: Mask, expectedData: number[][] | string, ): MatcherResult { @@ -172,14 +163,12 @@ const toMatchImageFileSnapshot = configureToMatchImageSnapshot({}); /** * Snapshot matching with Image objects. - * - * @param this - Jest matcher context. * @param received - Received image. * @param options - Options. * @returns - Jest matcher result. */ export function toMatchImageSnapshot( - this: jest.MatcherContext, + this: MatcherState, received: Image | Mask | Uint8Array, options?: MatchImageSnapshotOptions, ): MatcherResult { diff --git a/test/testUtils.ts b/test/testUtils.ts index c176cd28a..c12ea0419 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -2,11 +2,13 @@ import { mkdtempSync, readFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; -import { fromMask, Image, Point, readSync, Roi } from '../src'; +import type { Image, Point, Roi } from '../src/index.js'; +import { fromMask, readSync } from '../src/index.js'; -import { TestImagePath } from './TestImagePath'; -import { createImageFromData, CreateImageOptions } from './createImageFromData'; -import { createMask } from './createMask'; +import type { TestImagePath } from './TestImagePath.js'; +import type { CreateImageOptions } from './createImageFromData.js'; +import { createImageFromData } from './createImageFromData.js'; +import { createMask } from './createMask.js'; /** * Return the path to a given image. @@ -176,4 +178,4 @@ declare global { }; } -export { createMask } from './createMask'; +export { createMask } from './createMask.js'; diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json index 6b3810c61..2ceb0920c 100644 --- a/tsconfig.cjs.json +++ b/tsconfig.cjs.json @@ -1,15 +1,12 @@ { - "extends": "./tsconfig.json", + "extends": "./tsconfig.esm.json", "compilerOptions": { - "module": "commonjs", - "declaration": true, - "declarationMap": true - }, - "exclude": [ - "./demo/**/*", - "./src/**/__tests__", - "./jest.setup.ts", - "./test/**/*", - "vite.config.ts" - ] + "outDir": "lib-cjs", + "module": "CommonJS", + "moduleResolution": "Node", + "verbatimModuleSyntax": false, + "esModuleInterop": true, + "declaration": false, + "declarationMap": false + } } diff --git a/tsconfig.esm.json b/tsconfig.esm.json index 050b45d8c..4e7f08097 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -1,7 +1,10 @@ { - "extends": "./tsconfig.cjs.json", - "compilerOptions": { - "module": "es2020", - "outDir": "lib-esm" - } + "extends": "./tsconfig.json", + "exclude": [ + "./demo/**/*", + "./src/**/__tests__", + "./vitest.setup.ts", + "./test/**/*", + "vite*.ts" + ] } diff --git a/tsconfig.json b/tsconfig.json index ceaa0c467..daaec1b0d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,23 @@ { "compilerOptions": { - "noImplicitReturns": true, - "esModuleInterop": true, - "moduleResolution": "node", + "lib": ["ES2022", "DOM"], + "types": [], + "target": "ES2022", "outDir": "lib", - "sourceMap": true, - "strict": true, - "target": "es2020", "jsx": "react-jsx", + "module": "NodeNext", + "strict": true, + "skipLibCheck": false, + "resolveJsonModule": false, + "forceConsistentCasingInFileNames": true, + "allowJs": false, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "sourceMap": true, + "declaration": true, + "declarationMap": true, "useUnknownInCatchVariables": false }, - "include": ["./demo/**/*", "./jest.setup.ts", "./src/**/*", "./test/**/*"] + "include": ["./demo/**/*", + "./vitest.setup.ts", "./src/**/*", "./test/**/*"] } diff --git a/vitest.config.js b/vitest.config.js new file mode 100644 index 000000000..6bd7b6c25 --- /dev/null +++ b/vitest.config.js @@ -0,0 +1,15 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + setupFiles: ['./vitest.setup.ts'], + coverage: { + include: ['src/**'], + }, + reporters: [ + 'default', + 'jest-image-snapshot/src/outdated-snapshot-reporter.js', + ], + }, +}); diff --git a/vitest.setup.ts b/vitest.setup.ts new file mode 100644 index 000000000..11ffe4870 --- /dev/null +++ b/vitest.setup.ts @@ -0,0 +1,23 @@ +import { toBeDeepCloseTo, toMatchCloseTo } from 'jest-matcher-deep-close-to'; +import { expect } from 'vitest'; + +import { + toMatchImage, + toMatchImageData, + toMatchImageSnapshot, + toMatchMask, + toMatchMaskData, +} from './test/jestMatchers.js'; +import * as testUtils from './test/testUtils.js'; + +expect.extend({ + toBeDeepCloseTo, + toMatchCloseTo, + toMatchImage, + toMatchImageData, + toMatchImageSnapshot, + toMatchMask, + toMatchMaskData, +}); + +globalThis.testUtils = testUtils;