Skip to content

Commit

Permalink
feat(readImageFileSeries): Support componentType, pixelType
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Nov 4, 2022
1 parent 94460b7 commit d42fbc1
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 33 deletions.
9 changes: 9 additions & 0 deletions src/io/ReadImageFileSeriesOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import CastImageOptions from '../core/CastImageOptions.js'

interface ReadImageFileSeriesOptions extends CastImageOptions {
zSpacing?: number
zOrigin?: number
sortedSeries?: boolean
}

export default ReadImageFileSeriesOptions
1 change: 1 addition & 0 deletions src/io/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { default as readBlob } from './../readBlob.js'

export { default as readImageFile } from './../readImageFile.js'
export { default as readMeshFile } from './../readMeshFile.js'
export { default as ReadImageFileSeriesOptions } from './../ReadImageFileSeriesOptions.js'
export { default as readImageFileSeries } from './../readImageFileSeries.js'
export { default as ReadImageFileSeriesResult } from './../ReadImageFileSeriesResult.js'
export { default as readFile } from './../readFile.js'
Expand Down
3 changes: 1 addition & 2 deletions src/io/readImageArrayBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: Arra
outputs: any[]
}
let mimeType
if (typeof options === 'undefined') {
} else if (typeof options === 'string') {
if (typeof options === 'string') {
// backwards compatibility
mimeType = options
} else if (typeof options === 'object') {
Expand Down
37 changes: 33 additions & 4 deletions src/io/readImageFileSeries.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,46 @@
import stackImages from '../core/stackImages.js'
import readImageArrayBuffer from './readImageArrayBuffer.js'
import WorkerPool from '../core/WorkerPool.js'
import castImage from '../core/castImage.js'

import { readAsArrayBuffer } from 'promise-file-reader'

import ReadImageFileSeriesResult from './ReadImageFileSeriesResult.js'
import ReadImageFileSeriesOptions from './ReadImageFileSeriesOptions.js'

const numberOfWorkers = typeof globalThis.navigator?.hardwareConcurrency === 'number' ? globalThis.navigator.hardwareConcurrency : 6
const workerPool = new WorkerPool(numberOfWorkers, readImageArrayBuffer)

async function readImageFileSeries (
fileList: File[] | FileList,
zSpacing: number = 1.0,
zOrigin: number = 0.0,
sortedSeries: boolean = false
options?: ReadImageFileSeriesOptions | number,
zOriginBackwardsCompatibility?: number,
sortedSeriesBackwardsCompatibility?: boolean
): Promise<ReadImageFileSeriesResult> {
let zSpacing = 1.0
let zOrigin = 0.0
let sortedSeries = false
if (typeof options === 'number') {
// Backwards compatibility
zSpacing = options
}
if (typeof zOriginBackwardsCompatibility !== 'undefined') {
zOrigin = zOriginBackwardsCompatibility
}
if (typeof sortedSeriesBackwardsCompatibility !== 'undefined') {
sortedSeries = sortedSeriesBackwardsCompatibility
}
if (typeof options === 'object') {
if (typeof options.zSpacing !== 'undefined') {
zSpacing = options.zSpacing
}
if (typeof options.zOrigin !== 'undefined') {
zOrigin = options.zOrigin
}
if (typeof options.sortedSeries !== 'undefined') {
sortedSeries = options.sortedSeries
}
}
const fetchFileDescriptions = Array.from(fileList, async function (file) {
return await readAsArrayBuffer(file).then(function (
arrayBuffer
Expand Down Expand Up @@ -58,7 +84,10 @@ async function readImageFileSeries (
image.direction[8] = 1.0
return image
})
const stacked = stackImages(images)
let stacked = stackImages(images)
if (typeof options === 'object' && (typeof options.componentType !== 'undefined' || typeof options.pixelType !== 'undefined')) {
stacked = castImage(stacked, options)
}
return { image: stacked, webWorkerPool: workerPool }
}

Expand Down
73 changes: 50 additions & 23 deletions test/browser/io/readImageFileSeriesTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ import axios from 'axios'
import { IntTypes, PixelTypes, getMatrixElement, readImageFileSeries } from 'browser/index.js'

export default function () {
function verifyImage (t, image) {
function verifyImage (t, image, expectedComponentType, expectedPixelType) {
let componentType = IntTypes.UInt16
if (expectedComponentType) {
componentType = expectedComponentType
}
let pixelType = PixelTypes.Scalar
if (expectedPixelType) {
pixelType = expectedPixelType
}
t.is(image.imageType.dimension, 3, 'dimension')
t.is(image.imageType.componentType, IntTypes.UInt16, 'componentType')
t.is(image.imageType.pixelType, PixelTypes.Scalar, 'pixelType')
t.is(image.imageType.componentType, componentType, 'componentType')
t.is(image.imageType.pixelType, pixelType, 'pixelType')
t.is(image.imageType.components, 1, 'components')
t.is(image.origin[0], 0.0, 'origin[0]')
t.is(image.origin[1], 0.0, 'origin[1]')
Expand Down Expand Up @@ -45,34 +53,53 @@ export default function () {
return fetchFiles
}

test('Test reading sorted PNG file series', t => {
test('Test reading sorted PNG file series', async t => {
const fileNames = ['mri3D_01.png', 'mri3D_02.png', 'mri3D_03.png']
const fetchFiles = fetchTestFiles(fileNames)
const sortedSeries = true

return Promise.all(fetchFiles)
.then(function (files) {
return readImageFileSeries(files, zSpacing, zOrigin, sortedSeries)
})
.then(function ({ image, webWorkerPool }) {
webWorkerPool.terminateWorkers()
verifyImage(t, image)
t.end()
})
const files = await Promise.all(fetchFiles)
const { image, webWorkerPool } = await readImageFileSeries(files, zSpacing, zOrigin, sortedSeries)
webWorkerPool.terminateWorkers()
verifyImage(t, image)
t.end()
})

test('Test reading sorted PNG file series, specify componentType, pixelType', async t => {
const fileNames = ['mri3D_01.png', 'mri3D_02.png', 'mri3D_03.png']
const fetchFiles = fetchTestFiles(fileNames)
const sortedSeries = true

const files = await Promise.all(fetchFiles)
const componentType = IntTypes.Int32
const pixelType = PixelTypes.Vector
const { image, webWorkerPool } = await readImageFileSeries(files, { zSpacing, zOrigin, sortedSeries, componentType, pixelType })
webWorkerPool.terminateWorkers()
verifyImage(t, image, componentType, pixelType)
t.end()
})

test('Test reading unsorted PNG file series', t => {
test('Test reading unsorted PNG file series', async t => {
const fileNames = ['mri3D_02.png', 'mri3D_01.png', 'mri3D_03.png']
const fetchFiles = fetchTestFiles(fileNames)

return Promise.all(fetchFiles)
.then(function (files) {
return readImageFileSeries(files, zSpacing, zOrigin)
})
.then(function ({ image, webWorkerPool }) {
webWorkerPool.terminateWorkers()
verifyImage(t, image)
t.end()
})
const files = await Promise.all(fetchFiles)
const { image, webWorkerPool } = await readImageFileSeries(files, zSpacing, zOrigin)
webWorkerPool.terminateWorkers()
verifyImage(t, image)
t.end()
})

test('Test reading unsorted PNG file series, specify componentType, pixelType', async t => {
const fileNames = ['mri3D_02.png', 'mri3D_01.png', 'mri3D_03.png']
const fetchFiles = fetchTestFiles(fileNames)

const files = await Promise.all(fetchFiles)
const componentType = IntTypes.Int32
const pixelType = PixelTypes.Vector
const { image, webWorkerPool } = await readImageFileSeries(files, { zSpacing, zOrigin, componentType, pixelType })
webWorkerPool.terminateWorkers()
verifyImage(t, image, componentType, pixelType)
t.end()
})
}
4 changes: 2 additions & 2 deletions test/browser/io/readImageTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ for (let ii = 0; ii < byteString.length; ++ii) {
const cthead1SmallBlob = new window.Blob([intArray], { type: mimeString })
const cthead1SmallFile = new window.File([cthead1SmallBlob], 'cthead1Small.png')

function verifyImage(t, image, componentType, pixelType) {
function verifyImage (t, image, componentType, pixelType) {
t.is(image.imageType.dimension, 2, 'dimension')
t.is(image.imageType.componentType, componentType)
t.is(image.imageType.pixelType, pixelType)
Expand Down Expand Up @@ -86,7 +86,7 @@ export default function () {
})

test('readImageFile reads a File', async (t) => {
const { image, webWorker } = await readImageFile(null, cthead1SmallFile)
const { image, webWorker } = await readImageFile(null, cthead1SmallFile)
webWorker.terminate()
const componentType = IntTypes.UInt8
const pixelType = PixelTypes.Scalar
Expand Down
4 changes: 2 additions & 2 deletions test/node/io/image/readImageLocalFileTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { IntTypes, PixelTypes, getMatrixElement, readImageLocalFile } from '../.

const testFilePath = path.resolve('build-emscripten', 'ExternalData', 'test', 'Input', 'cthead1.png')

function verifyImage(t, image, componentType, pixelType) {
function verifyImage (t, image, componentType, pixelType) {
t.is(image.imageType.dimension, 2)
t.is(image.imageType.componentType, componentType)
t.is(image.imageType.pixelType, pixelType)
Expand Down Expand Up @@ -42,4 +42,4 @@ test('readImageLocalFile casts to the specified pixelType', async t => {
const image = await readImageLocalFile(testFilePath, { pixelType })
const componentType = IntTypes.UInt8
verifyImage(t, image, componentType, pixelType)
})
})

0 comments on commit d42fbc1

Please sign in to comment.