├── .envrc ├── .github ├── build.sh ├── setup.sh └── workflows │ ├── build-main.yml │ └── build-pr.yml ├── .gitignore ├── .mailmap ├── README.md ├── UNLICENSE ├── environment.yml ├── images ├── howto_map.png ├── howto_map.yuml ├── maven-projects_map.png ├── maven-projects_map.yuml ├── notebooks_map.png ├── notebooks_map.yuml ├── tutorials_map.png └── tutorials_map.yuml ├── java ├── README.md ├── custom-preprocessor-plugin │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── TrollPreprocessor.java ├── execute-commands │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── ExecuteCommands.java ├── howtos │ ├── images │ │ └── about │ │ │ ├── about1.tif │ │ │ ├── about1.tif.txt │ │ │ ├── about2.tif │ │ │ ├── about2.tif.txt │ │ │ ├── about3.tif │ │ │ ├── about3.tif.txt │ │ │ ├── about4.tif │ │ │ ├── about4.tif.txt │ │ │ ├── about5.tif │ │ │ └── about5.tif.txt │ ├── migration-notes.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── howto │ │ │ ├── README.md │ │ │ ├── Template.java │ │ │ ├── adv │ │ │ ├── IntroToImageJAPI.java │ │ │ └── ModernFromLegacy.java │ │ │ ├── app │ │ │ ├── DisposeImageJ.java │ │ │ ├── GetImageJDirectory.java │ │ │ ├── GetJARsInClassPath.java │ │ │ ├── GetSystemInformation.java │ │ │ └── GetVersionOfMavenArtifact.java │ │ │ ├── commands │ │ │ ├── dynamic │ │ │ │ ├── DynamicCallbacks.java │ │ │ │ ├── DynamicInitialization.java │ │ │ │ └── DynamicNumberOfParameters.java │ │ │ └── simple │ │ │ │ ├── CopyLabels.java │ │ │ │ ├── GradientImage.java │ │ │ │ ├── HelloWorld.java │ │ │ │ ├── OpenImage.java │ │ │ │ └── OpenScaleSaveImage.java │ │ │ ├── datasets │ │ │ ├── AddTwoDatasets.java │ │ │ └── LoadAndDisplayDataset.java │ │ │ ├── displays │ │ │ ├── DisplayError.java │ │ │ ├── DisplayInfo.java │ │ │ └── DisplayWarning.java │ │ │ ├── extensions │ │ │ ├── CommandThatChecksImageType.java │ │ │ ├── ExampleCommand.java │ │ │ ├── ExampleDynamicCommand.java │ │ │ ├── GetExampleCommandResult.java │ │ │ ├── ListAllCommands.java │ │ │ ├── ModifyCommand.java │ │ │ └── RunExampleCommand.java │ │ │ ├── headless │ │ │ └── StartImageJHeadless.java │ │ │ ├── images │ │ │ ├── AddROIs.java │ │ │ ├── ConvertImageClasses.java │ │ │ ├── CreateImage.java │ │ │ ├── DuplicateImage.java │ │ │ ├── GetOpenImages.java │ │ │ ├── OpenAndShowImage.java │ │ │ ├── SaveImage.java │ │ │ ├── SaveImageCompressed.java │ │ │ ├── drawing │ │ │ │ ├── DrawCircle.java │ │ │ │ └── DrawRectangle.java │ │ │ ├── filter │ │ │ │ └── LowPassFilter.java │ │ │ └── processing │ │ │ │ ├── CountCells.java │ │ │ │ └── ProcessChannelsIndividually.java │ │ │ ├── metadata │ │ │ └── GetMetadata.java │ │ │ ├── modules │ │ │ └── WorkingWithModules.java │ │ │ ├── ops │ │ │ ├── ConvolutionOps.java │ │ │ ├── CreateANewOp.java │ │ │ ├── RampOp.java │ │ │ ├── RandomBlobsOp.java │ │ │ ├── UsingOps.java │ │ │ ├── UsingOpsDog.java │ │ │ ├── UsingOpsLabeling.java │ │ │ └── UsingSpecialOps.java │ │ │ ├── plugins │ │ │ └── create │ │ │ │ ├── Animal.java │ │ │ │ ├── AnimalService.java │ │ │ │ ├── Bear.java │ │ │ │ ├── CreateANewPluginType.java │ │ │ │ ├── Lion.java │ │ │ │ └── Tiger.java │ │ │ ├── services │ │ │ ├── CallService.java │ │ │ └── ListAllServices.java │ │ │ ├── tables │ │ │ ├── CreateTable.java │ │ │ ├── SaveAndLoadTable.java │ │ │ └── TableTutorial.java │ │ │ ├── ui │ │ │ ├── CustomWidget.java │ │ │ ├── SwingExample.java │ │ │ ├── WidgetDemo.java │ │ │ └── preview │ │ │ │ ├── CommandWithPreview.java │ │ │ │ └── PreviewCheckbox.java │ │ │ └── userinput │ │ │ ├── AskForFile.java │ │ │ ├── AskYesNo.java │ │ │ └── ValidateParameter.java │ │ └── resources │ │ └── blobs.png ├── ij2-image-plus │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── DatasetWrapping.java ├── listen-to-events │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── ListenToEvents.java └── swing-example │ ├── pom.xml │ └── src │ └── main │ └── java │ ├── DeconvolutionCommand.java │ ├── DeconvolutionCommandSwing.java │ ├── DeconvolutionDialog.java │ └── SwingExample.java ├── notebooks ├── 1-Using-ImageJ │ ├── 1-Fundamentals.ipynb │ ├── 2-ImageJ-Ops.ipynb │ ├── 3-ImgLib2-Basics.ipynb │ ├── 4-Tables.ipynb │ ├── 5-Mixed-World-ImageJ1.ipynb │ ├── 6-ImageJ-with-Python-Kernel.ipynb │ ├── 7-Calling-Scripts-from-Scripts.ipynb │ ├── Ops │ │ ├── copy │ │ │ ├── img.ipynb │ │ │ ├── iterableInterval.ipynb │ │ │ └── rai.ipynb │ │ ├── eval.ipynb │ │ ├── filter │ │ │ ├── addNoise.ipynb │ │ │ ├── addPoissonNoise.ipynb │ │ │ ├── bilateral.ipynb │ │ │ ├── derivativeGauss.ipynb │ │ │ ├── dog.ipynb │ │ │ ├── gauss.ipynb │ │ │ ├── hessian.ipynb │ │ │ ├── ifft.ipynb │ │ │ ├── max.ipynb │ │ │ ├── mean.ipynb │ │ │ ├── median.ipynb │ │ │ ├── min.ipynb │ │ │ ├── padInput.ipynb │ │ │ ├── partialDerivative.ipynb │ │ │ ├── sigma.ipynb │ │ │ ├── sobel.ipynb │ │ │ ├── tubeness.ipynb │ │ │ └── variance.ipynb │ │ ├── help.ipynb │ │ ├── identity.ipynb │ │ ├── labeling │ │ │ └── cca.ipynb │ │ ├── map.ipynb │ │ ├── morphology │ │ │ ├── blackTopHat.ipynb │ │ │ ├── close.ipynb │ │ │ ├── dilate.ipynb │ │ │ ├── erode.ipynb │ │ │ ├── extractHoles.ipynb │ │ │ ├── fillHoles.ipynb │ │ │ ├── floodFill.ipynb │ │ │ ├── open.ipynb │ │ │ ├── outline.ipynb │ │ │ ├── thin.ipynb │ │ │ └── topHat.ipynb │ │ ├── segment │ │ │ └── detectRidges.ipynb │ │ ├── slice.ipynb │ │ ├── stats │ │ │ ├── geometricMean.ipynb │ │ │ ├── harmonicMean.ipynb │ │ │ ├── integralSum.ipynb │ │ │ ├── kurtosis.ipynb │ │ │ ├── max.ipynb │ │ │ ├── mean.ipynb │ │ │ ├── median.ipynb │ │ │ ├── min.ipynb │ │ │ ├── minMax.ipynb │ │ │ ├── moment1AboutMean.ipynb │ │ │ ├── moment2AboutMean.ipynb │ │ │ ├── moment3AboutMean.ipynb │ │ │ ├── moment4AboutMean.ipynb │ │ │ ├── percentile.ipynb │ │ │ ├── quantile.ipynb │ │ │ ├── size.ipynb │ │ │ ├── skewness.ipynb │ │ │ ├── stdDev.ipynb │ │ │ ├── sum.ipynb │ │ │ ├── sumOfInverses.ipynb │ │ │ ├── sumOfLogs.ipynb │ │ │ ├── sumOfSquares.ipynb │ │ │ └── variance.ipynb │ │ ├── threshold │ │ │ └── threshold.ipynb │ │ └── transform │ │ │ ├── addDimensionView.ipynb │ │ │ ├── concatenateView.ipynb │ │ │ ├── crop.ipynb │ │ │ ├── dropSingletonDimensionsView.ipynb │ │ │ ├── extendBorderView.ipynb │ │ │ ├── extendMirrorDoubleView.ipynb │ │ │ ├── extendMirrorSingleView.ipynb │ │ │ ├── extendPeriodicView.ipynb │ │ │ ├── extendRandomView.ipynb │ │ │ ├── extendValueView.ipynb │ │ │ ├── extendView.ipynb │ │ │ ├── extendZeroView.ipynb │ │ │ ├── flatIterableView.ipynb │ │ │ ├── hyperSliceView.ipynb │ │ │ ├── interpolateView.ipynb │ │ │ ├── intervalView.ipynb │ │ │ ├── invertAxisView.ipynb │ │ │ ├── offsetView.ipynb │ │ │ ├── permuteCoordinatesInverseView.ipynb │ │ │ ├── permuteCoordinatesView.ipynb │ │ │ ├── permuteView.ipynb │ │ │ ├── project.ipynb │ │ │ ├── rotateView.ipynb │ │ │ ├── scaleView.ipynb │ │ │ ├── shearView.ipynb │ │ │ ├── stackView.ipynb │ │ │ ├── subsampleView.ipynb │ │ │ ├── translateView.ipynb │ │ │ ├── unshearView.ipynb │ │ │ └── zeroMinView.ipynb │ └── ide-autocomplete.png ├── 2-Extending-ImageJ │ ├── 1-Input-Output.ipynb │ └── 2-Ops.ipynb ├── 3-Advanced-Topics │ ├── 1-SciJava-in-Detail.ipynb │ ├── 2-ImgLib2-in-Detail.ipynb │ └── 3-Using-Special-Ops.ipynb ├── ImageJ-Tutorials-and-Demo.ipynb ├── Intro-to-Jupyter.ipynb └── README.md └── pom.xml /.envrc: -------------------------------------------------------------------------------- 1 | condaScript=$(dirname "$CONDA_EXE")/../etc/profile.d/conda.sh 2 | if [ -e "$condaScript" ] 3 | then 4 | echo "Activating conda environment" 5 | . "$condaScript" 6 | conda activate scijava 7 | else 8 | echo "No conda installation detected; skipping activation" 9 | fi 10 | -------------------------------------------------------------------------------- /.github/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/ci-build.sh 3 | sh ci-build.sh 4 | -------------------------------------------------------------------------------- /.github/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/ci-setup-github-actions.sh 3 | sh ci-setup-github-actions.sh 4 | -------------------------------------------------------------------------------- /.github/workflows/build-main.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - "*-[0-9]+.*" 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up Java 17 | uses: actions/setup-java@v3 18 | with: 19 | java-version: '8' 20 | distribution: 'zulu' 21 | cache: 'maven' 22 | - name: Set up CI environment 23 | run: .github/setup.sh 24 | - name: Execute the build 25 | run: .github/build.sh 26 | env: 27 | GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }} 28 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 29 | MAVEN_USER: ${{ secrets.MAVEN_USER }} 30 | MAVEN_PASS: ${{ secrets.MAVEN_PASS }} 31 | OSSRH_PASS: ${{ secrets.OSSRH_PASS }} 32 | SIGNING_ASC: ${{ secrets.SIGNING_ASC }} 33 | -------------------------------------------------------------------------------- /.github/workflows/build-pr.yml: -------------------------------------------------------------------------------- 1 | name: build PR 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Set up Java 15 | uses: actions/setup-java@v3 16 | with: 17 | java-version: '8' 18 | distribution: 'zulu' 19 | cache: 'maven' 20 | - name: Set up CI environment 21 | run: .github/setup.sh 22 | - name: Execute the build 23 | run: .github/build.sh 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven # 2 | target/ 3 | 4 | # Eclipse # 5 | .classpath 6 | .project 7 | .settings/ 8 | 9 | # IntelliJ # 10 | .idea/ 11 | *.iml 12 | 13 | # Jupyter # 14 | *.ipynb_checkpoints* 15 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Ellen Arena 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://github.com/imagej/tutorials/actions/workflows/build-main.yml/badge.svg)](https://github.com/imagej/tutorials/actions/workflows/build-main.yml) 2 | 3 | **If you want to learn how to *use* ImageJ and/or ImageJ2 (as opposed to *write programs* with ImageJ2), then visit [ImageJ Tutorials](https://imagej.net/tutorials).** 4 | 5 | This project contains example code for working with 6 | [ImageJ2](https://imagej.net/software/imagej2) and [SciJava](https://imagej.net/libs/scijava). 7 | 8 | OVERVIEW 9 | -------- 10 | 11 | This repository is broken down into two main functional parts: [Notebooks](#notebooks) and [Java](#java). 12 | 13 | ## Notebooks 14 | The purpose of the [notebooks](notebooks) is to give a "guided tour" for teaching ImageJ2. 15 | 16 | ## Java 17 | The purpose of the [java](java) section of this repository is to give a collection of examples and howtos for different use cases. 18 | 19 | LICENSING 20 | --------- 21 | 22 | To the extent possible under law, the ImageJ developers have waived 23 | all copyright and related or neighboring rights to this tutorial code. 24 | 25 | See [unlicense.org](https://unlicense.org/) for details. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | 31 | * The [Tutorials](https://imagej.net/tutorials) and [Development](https://imagej.net/develop) sections of the ImageJ wiki. 32 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: scijava 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - beakerx 6 | - jupyter_contrib_nbextensions 7 | - numpy 8 | - openjdk=8 9 | - pyimagej 10 | - python 11 | - rise 12 | - scikit-image 13 | -------------------------------------------------------------------------------- /images/howto_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/images/howto_map.png -------------------------------------------------------------------------------- /images/howto_map.yuml: -------------------------------------------------------------------------------- 1 | // {type:deployment} 2 | // {generate:true} 3 | 4 | [howto]-[datasets] 5 | [howto]-[metadata] 6 | [howto]-[ui] 7 | [ui]-[preview] 8 | [howto]-[app] 9 | [howto]-[headless] 10 | [howto]-[tables] 11 | [howto]-[adv] 12 | [howto]-[plugins] 13 | [plugins]-[create] 14 | [howto]-[userinput] 15 | [howto]-[extensions] 16 | [howto]-[commands] 17 | [commands]-[dynamic] 18 | [commands]-[simple] 19 | [howto]-[images] 20 | [images]-[drawing] 21 | [images]-[processing] 22 | [images]-[filter] 23 | [howto]-[ops] 24 | [howto]-[services] 25 | [howto]-[displays] 26 | -------------------------------------------------------------------------------- /images/maven-projects_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/images/maven-projects_map.png -------------------------------------------------------------------------------- /images/maven-projects_map.yuml: -------------------------------------------------------------------------------- 1 | // {type:deployment} 2 | // {generate:true} 3 | 4 | [maven-projects]-[dynamic-commands] 5 | [maven-projects]-[swing-example] 6 | [maven-projects]-[listen-to-events] 7 | [maven-projects]-[simple-commands] 8 | [maven-projects]-[custom-preprocessor-plugin] 9 | [maven-projects]-[working-with-modules] 10 | [maven-projects]-[execute-commands] 11 | [maven-projects]-[add-two-datasets] 12 | [maven-projects]-[ij2-image-plus] 13 | -------------------------------------------------------------------------------- /images/notebooks_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/images/notebooks_map.png -------------------------------------------------------------------------------- /images/notebooks_map.yuml: -------------------------------------------------------------------------------- 1 | // {type:deployment} 2 | // {generate:true} 3 | 4 | [notebooks]-[5-ImageJ-Core-Libraries] 5 | [notebooks]-[4-Using-Ops] 6 | [4-Using-Ops]-[examples] 7 | [examples]-[threshold] 8 | [examples]-[misc] 9 | [examples]-[morphology] 10 | [examples]-[segment] 11 | [examples]-[labeling] 12 | [examples]-[filtering] 13 | [examples]-[stats] 14 | [examples]-[copy] 15 | [examples]-[transform] 16 | [notebooks]-[2-ImageJ-Basics] 17 | [notebooks]-[1-Introduction] 18 | [notebooks]-[3-Extending-ImageJ] 19 | -------------------------------------------------------------------------------- /images/tutorials_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/images/tutorials_map.png -------------------------------------------------------------------------------- /images/tutorials_map.yuml: -------------------------------------------------------------------------------- 1 | // {type:deployment} 2 | // {generate:true} 3 | 4 | [tutorials]-[note: tutorials_map.png\ntutorials_map.pdf\ntutorials_map.yuml\n{bg:wheat}] 5 | [tutorials]-[maven-projects] 6 | [maven-projects]-[dynamic-commands] 7 | [dynamic-commands]-[note: DynamicInitialization.java\nDynamicNumberOfParameters.java\nDynamicCallbacks.java\n{bg:wheat}] 8 | [maven-projects]-[swing-example] 9 | [swing-example]-[note: DeconvolutionCommand.java\nSwingExample.java\nDeconvolutionCommandSwing.java\nDeconvolutionDialog.java\n{bg:wheat}] 10 | [maven-projects]-[listen-to-events] 11 | [listen-to-events]-[note: ListenToEvents.java\n{bg:wheat}] 12 | [maven-projects]-[simple-commands] 13 | [simple-commands]-[note: GradientImage.java\nHelloWorld.java\nOpenImage.java\nOpenScaleSaveImage.java\n{bg:wheat}] 14 | [maven-projects]-[custom-preprocessor-plugin] 15 | [custom-preprocessor-plugin]-[note: TrollPreprocessor.java\n{bg:wheat}] 16 | [maven-projects]-[working-with-modules] 17 | [working-with-modules]-[note: WorkingWithModules.java\n{bg:wheat}] 18 | [maven-projects]-[execute-commands] 19 | [execute-commands]-[note: ExecuteCommands.java\n{bg:wheat}] 20 | [maven-projects]-[add-two-datasets] 21 | [add-two-datasets]-[note: AddTwoDatasets.java\n{bg:wheat}] 22 | [maven-projects]-[ij2-image-plus] 23 | [ij2-image-plus]-[note: DatasetWrapping.java\n{bg:wheat}] 24 | [tutorials]-[migration-notes] 25 | [migration-notes]-[note: imagej_tutorial_howto_migration.md\n{bg:wheat}] 26 | [tutorials]-[howtos] 27 | [howtos]-[howto] 28 | [howto]-[note: Template.java\n{bg:wheat}] 29 | [howto]-[datasets] 30 | [datasets]-[note: LoadAndDisplayDataset.java\n{bg:wheat}] 31 | [howto]-[metadata] 32 | [metadata]-[note: GetMetadata.java\n{bg:wheat}] 33 | [howto]-[ui] 34 | [ui]-[note: WidgetDemo.java\nSwingExample.java\n{bg:wheat}] 35 | [ui]-[preview] 36 | [preview]-[note: PreviewCheckbox.java\nCommandWithPreview.java\n{bg:wheat}] 37 | [howto]-[app] 38 | [app]-[note: GetVersionOfMavenArtifact.java\nDisposeImageJ.java\nGetSystemInformation.java\nGetImageJDirectory.java\nGetJARsInClassPath.java\n{bg:wheat}] 39 | [howto]-[headless] 40 | [headless]-[note: StartImageJHeadless.java\n{bg:wheat}] 41 | [howto]-[tables] 42 | [tables]-[note: SaveAndLoadTable.java\nCreateTable.java\nTableTutorial.java\n{bg:wheat}] 43 | [howto]-[adv] 44 | [adv]-[note: ModernFromLegacy.java\nIntroToImageJAPI.java\n{bg:wheat}] 45 | [howto]-[plugins] 46 | [plugins]-[create] 47 | [create]-[note: Animal.java\nAnimalService.java\nCreateANewPluginType.java\nLion.java\nBear.java\nTiger.java\n{bg:wheat}] 48 | [howto]-[userinput] 49 | [userinput]-[note: ValidateParameter.java\nAskForFile.java\nAskYesNo.java\n{bg:wheat}] 50 | [howto]-[extensions] 51 | [extensions]-[note: GetExampleCommandResult.java\nListAllCommands.java\nExampleDynamicCommand.java\nExampleCommand.java\nRunExampleCommand.java\nCommandThatChecksImageType.java\nModifyCommand.java\n{bg:wheat}] 52 | [howto]-[commands] 53 | [commands]-[dynamic] 54 | [dynamic]-[note: DynamicInitialization.java\nDynamicNumberOfParameters.java\n{bg:wheat}] 55 | [commands]-[simple] 56 | [simple]-[note: GradientImage.java\nHelloWorld.java\nOpenImage.java\nCopyLabels.java\nOpenScaleSaveImage.java\n{bg:wheat}] 57 | [howto]-[images] 58 | [images]-[note: SaveImage.java\nCreateImage.java\nOpenAndShowImage.java\nDuplicateImage.java\nConvertImageClasses.java\nAddROIs.java\nGetOpenImages.java\n{bg:wheat}] 59 | [images]-[drawing] 60 | [drawing]-[note: DrawCircle.java\nDrawRectangle.java\n{bg:wheat}] 61 | [images]-[processing] 62 | [processing]-[note: ProcessChannelsIndividually.java\nCountCells.java\n{bg:wheat}] 63 | [images]-[filter] 64 | [filter]-[note: LowPassFilter.java\n{bg:wheat}] 65 | [howto]-[ops] 66 | [ops]-[note: RandomBlobsOp.java\nUsingOpsDog.java\nUsingOps.java\nUsingSpecialOps.java\nConvolutionOps.java\nRampOp.java\nCreateANewOp.java\nUsingOpsLabeling.java\n{bg:wheat}] 67 | [howto]-[services] 68 | [services]-[note: CallService.java\nListAllServices.java\n{bg:wheat}] 69 | [howto]-[displays] 70 | [displays]-[note: DisplayError.java\nDisplayWarning.java\nDisplayInfo.java\n{bg:wheat}] 71 | [tutorials]-[notebooks] 72 | [notebooks]-[5-ImageJ-Core-Libraries] 73 | [5-ImageJ-Core-Libraries]-[note: 2-ImgLib2-in-Detail.ipynb\n1-SciJava-in-Detail.ipynb\n3-Using-Special-Ops.ipynb\n{bg:wheat}] 74 | [notebooks]-[4-Using-Ops] 75 | [4-Using-Ops]-[note: 4-Ops.ipynb\n{bg:wheat}] 76 | [4-Using-Ops]-[examples] 77 | [examples]-[threshold] 78 | [threshold]-[note: threshold.ipynb\n{bg:wheat}] 79 | [examples]-[misc] 80 | [examples]-[morphology] 81 | [morphology]-[note: outline.ipynb\nblackTopHat.ipynb\nclose.ipynb\ntopHat.ipynb\nerode.ipynb\nthin.ipynb\nfillHoles.ipynb\nopen.ipynb\ndilate.ipynb\nfloodFill.ipynb\nextractHoles.ipynb\n{bg:wheat}] 82 | [examples]-[segment] 83 | [segment]-[note: map.ipynb\nidentity.ipynb\nslice.ipynb\nhelp.ipynb\ndetectRidges.ipynb\neval.ipynb\n{bg:wheat}] 84 | [examples]-[labeling] 85 | [labeling]-[note: cca.ipynb\n{bg:wheat}] 86 | [examples]-[filtering] 87 | [filtering]-[note: derivativeGauss.ipynb\npadInput.ipynb\ngauss.ipynb\nvariance.ipynb\nifft.ipynb\nsigma.ipynb\ntubeness.ipynb\nsobel.ipynb\nmedian.ipynb\nhessian.ipynb\ndog.ipynb\npartialDerivative.ipynb\nmax.ipynb\nmin.ipynb\naddNoise.ipynb\naddPoissonNoise.ipynb\nbilateral.ipynb\nmean.ipynb\n{bg:wheat}] 88 | [examples]-[stats] 89 | [stats]-[note: percentile.ipynb\nharmonicMean.ipynb\nmoment4AboutMean.ipynb\nsumOfInverses.ipynb\nminMax.ipynb\nintegralSum.ipynb\nvariance.ipynb\nsumOfLogs.ipynb\nstdDev.ipynb\nmoment3AboutMean.ipynb\nmoment1AboutMean.ipynb\nsize.ipynb\ngeometricMean.ipynb\nmedian.ipynb\nmoment2AboutMean.ipynb\nkurtosis.ipynb\nmax.ipynb\nmin.ipynb\nsumOfSquares.ipynb\nsum.ipynb\nquantile.ipynb\nskewness.ipynb\nmean.ipynb\n{bg:wheat}] 90 | [examples]-[copy] 91 | [copy]-[note: iterableInterval.ipynb\nrai.ipynb\nimg.ipynb\n{bg:wheat}] 92 | [examples]-[transform] 93 | [transform]-[note: translateView.ipynb\nextendValueView.ipynb\npermuteCoordinatesView.ipynb\nextendMirrorSingleView.ipynb\nextendView.ipynb\nextendRandomView.ipynb\nextendPeriodicView.ipynb\nzeroMinView.ipynb\naddDimensionView.ipynb\nproject.ipynb\npermuteCoordinatesInverseView.ipynb\ninterpolateView.ipynb\nrotateView.ipynb\nflatIterableView.ipynb\nextendZeroView.ipynb\nconcatenateView.ipynb\ninvertAxisView.ipynb\nscaleView.ipynb\nshearView.ipynb\nextendBorderView.ipynb\nhyperSliceView.ipynb\npermuteView.ipynb\nunshearView.ipynb\nstackView.ipynb\ndropSingletonDimensionsView.ipynb\nintervalView.ipynb\ncrop.ipynb\nsubsampleView.ipynb\noffsetView.ipynb\nextendMirrorDoubleView.ipynb\n{bg:wheat}] 94 | [notebooks]-[2-ImageJ-Basics] 95 | [2-ImageJ-Basics]-[note: ide-autocomplete.png\n2-ImageJ-Ops.ipynb\n4-Tables.ipynb\n5-Mixed-World-ImageJ1.ipynb\n3-ImgLib2-Basics.ipynb\n1-Fundamentals.ipynb\n{bg:wheat}] 96 | [notebooks]-[1-Introduction] 97 | [1-Introduction]-[note: Intro-to-Jupyter.ipynb\nImageJ-Tutorials-and-Demo.ipynb\n{bg:wheat}] 98 | [notebooks]-[3-Extending-ImageJ] 99 | [3-Extending-ImageJ]-[note: 5-Tools.ipynb\n3-Commands.ipynb\n1-Scripting.ipynb\n2-Input-Output.ipynb\n6-ImageJ-with-Python-Kernel.ipynb\n{bg:wheat}] 100 | -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | [![](https://travis-ci.org/imagej/tutorials.svg?branch=master)](https://travis-ci.org/imagej/tutorials) 2 | 3 | This directory contains example Maven projects with Java code for working with 4 | [ImageJ2](https://imagej.net/software/imagej2) and [SciJava](https://imagej.net/libs/scijava). 5 | 6 | 7 | JAVA PROJECTS 8 | ------------- 9 | 10 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/imagej/tutorials) 11 | 12 | Use the "Open in Gitpod" button above to run the (non-GUI) Java projects on the 13 | cloud using [Gitpod](https://gitpod.io), with no local installation necessary. 14 | 15 | Additionally, you can import these projects into your favorite IDE. The Java files in these tutorials have main methods that can be directly ran inside of your IDE. 16 | 17 | * Eclipse: File > Import > Existing Maven Projects > tutorials > java 18 | * NetBeans: File > Open Project 19 | * IntelliJ IDEA: File > Open > tutorials > pom.xml > Open as Project 20 | 21 | 22 | We are in the process of migrating projects into the `howtos` project. As such, that will be an excellent entry point to become familiar with ImageJ2 and SciJava. 23 | 24 | `HelloWorld.Java` and `OpenImage.java` inside of `howtos.commands.simple` are good starting points to see the annotation syntax for creating plugins. From there, you can go to the project that best fits your needs. 25 | 26 | If you would like to learn more about plugin development, see [Writing ImageJ2 plugins](https://imagej.net/develop/plugins). 27 | 28 | LICENSING 29 | --------- 30 | 31 | To the extent possible under law, the ImageJ developers have waived 32 | all copyright and related or neighboring rights to this tutorial code. 33 | 34 | See the [CC0 1.0 Universal license](https://creativecommons.org/publicdomain/zero/1.0/) for details. 35 | 36 | 37 | SEE ALSO 38 | -------- 39 | 40 | * The [Tutorials](https://imagej.net/tutorials) and [Development](https://imagej.net/develop) sections of the ImageJ wiki. 41 | -------------------------------------------------------------------------------- /java/custom-preprocessor-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | custom-preprocessor-plugin 17 | 1.0.0-SNAPSHOT 18 | 19 | Custom Preprocessor Plugin 20 | This example shows how to write your own preprocessor plugin that augments every command execution. 21 | https://github.com/[MY-ORG]/[MY-REPO] 22 | 2012 23 | 24 | [MY-ORGANIZATION-NAME] 25 | [MY-ORGANIZATION-WEB-SITE] 26 | 27 | 28 | 29 | Unlicense 30 | https://unlicense.org/ 31 | repo 32 | 33 | 34 | 35 | 36 | 37 | [MY-GITHUB-ID] 38 | [MY-FULL-NAME] 39 | https://imagej.net/User:[MY-IMAGEJ-WIKI-ACCOUNT] 40 | 41 | 42 | 43 | 44 | None 45 | 46 | 47 | 48 | 49 | 50 | Image.sc Forum 51 | https://forum.image.sc/tags/imagej 52 | 53 | 54 | 55 | 56 | scm:git:git://github.com/[MY-ORG]/[MY-REPO] 57 | scm:git:git@github.com:[MY-ORG]/[MY-REPO] 58 | HEAD 59 | https://github.com/[MY-ORG]/[MY-REPO] 60 | 61 | 62 | GitHub Issues 63 | http://github.com/[MY-ORG]/[MY-REPO]/issues 64 | 65 | 66 | None 67 | 68 | 69 | 70 | TrollPreprocessor 71 | unlicense 72 | N/A 73 | ImageJ software for multidimensional image processing and analysis. 74 | 75 | 76 | 77 | 78 | scijava.public 79 | https://maven.scijava.org/content/groups/public 80 | 81 | 82 | 83 | 84 | 85 | net.imagej 86 | imagej 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /java/custom-preprocessor-plugin/src/main/java/TrollPreprocessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | import net.imagej.ImageJ; 10 | 11 | import org.scijava.module.Module; 12 | import org.scijava.module.process.AbstractPreprocessorPlugin; 13 | import org.scijava.module.process.PreprocessorPlugin; 14 | import org.scijava.plugin.Plugin; 15 | import org.scijava.ui.DialogPrompt.MessageType; 16 | import org.scijava.ui.DialogPrompt.OptionType; 17 | import org.scijava.ui.DialogPrompt.Result; 18 | import org.scijava.ui.UIService; 19 | import org.scijava.util.MersenneTwisterFast; 20 | 21 | /** 22 | * A custom preprocessor plugin that augments every command execution. 23 | *

24 | * It adds an insulting confirmation dialog before each command runs. 25 | *

26 | */ 27 | @Plugin(type = PreprocessorPlugin.class) 28 | public class TrollPreprocessor extends AbstractPreprocessorPlugin { 29 | 30 | private static final String[] INSULTS = { "essentially useless", 31 | "a waste of your time", "complete garbage" }; 32 | 33 | private static final String[] PLATITUDES = { "It's probably for the best.", 34 | "It's easier this way.", "A wise decision.", "That's what I thought." }; 35 | 36 | /** Random number generator for insults and platitudes. */ 37 | private final MersenneTwisterFast random = new MersenneTwisterFast(); 38 | 39 | @Override 40 | public void process(final Module module) { 41 | final String title = module.getInfo().getTitle(); 42 | 43 | // Select a random insult. 44 | final String insult = 45 | "The \"" + title + "\" command is " + random(INSULTS) + "."; 46 | 47 | final String demand = "You must pay a toll of one gold coin to continue."; 48 | final String confirmation = "Are you sure?"; 49 | final String message = insult + "\n" + demand + "\n" + confirmation; 50 | 51 | final MessageType messageType = MessageType.WARNING_MESSAGE; 52 | final OptionType optionType = OptionType.YES_NO_OPTION; 53 | 54 | // Prompt for confirmation. 55 | final UIService uiService = getContext().getService(UIService.class); 56 | final Result result = 57 | uiService.showDialog(message, "Troll", messageType, optionType); 58 | 59 | // Cancel the command execution if the user does not agree. 60 | if (result != Result.YES_OPTION) cancel(random(PLATITUDES)); 61 | } 62 | 63 | /** Chooses a random item from the given list. */ 64 | private String random(final String... list) { 65 | return list[random.nextInt(list.length)]; 66 | } 67 | 68 | /** Tests the custom preprocessor plugin. */ 69 | public static void main(final String... args) throws Exception { 70 | // Launch ImageJ as usual. 71 | final ImageJ ij = new ImageJ(); 72 | ij.launch(args); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /java/execute-commands/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | execute-commands 17 | 1.0.0-SNAPSHOT 18 | 19 | Execute Commands 20 | This example shows how to execute commands programmatically using the ImageJ API. 21 | https://github.com/[MY-ORG]/[MY-REPO] 22 | 2013 23 | 24 | [MY-ORGANIZATION-NAME] 25 | [MY-ORGANIZATION-WEB-SITE] 26 | 27 | 28 | 29 | Unlicense 30 | https://unlicense.org/ 31 | repo 32 | 33 | 34 | 35 | 36 | 37 | [MY-GITHUB-ID] 38 | [MY-FULL-NAME] 39 | https://imagej.net/User:[MY-IMAGEJ-WIKI-ACCOUNT] 40 | 41 | 42 | 43 | 44 | None 45 | 46 | 47 | 48 | 49 | 50 | Image.sc Forum 51 | https://forum.image.sc/tags/imagej 52 | 53 | 54 | 55 | 56 | scm:git:git://github.com/[MY-ORG]/[MY-REPO] 57 | scm:git:git@github.com:[MY-ORG]/[MY-REPO] 58 | HEAD 59 | https://github.com/[MY-ORG]/[MY-REPO] 60 | 61 | 62 | GitHub Issues 63 | http://github.com/[MY-ORG]/[MY-REPO]/issues 64 | 65 | 66 | None 67 | 68 | 69 | 70 | ExecuteCommands 71 | unlicense 72 | N/A 73 | ImageJ software for multidimensional image processing and analysis. 74 | 75 | 76 | 77 | 78 | scijava.public 79 | https://maven.scijava.org/content/groups/public 80 | 81 | 82 | 83 | 84 | 85 | net.imagej 86 | imagej 87 | 88 | 89 | org.scijava 90 | scijava-plugins-commands 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /java/howtos/images/about/about1.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/java/howtos/images/about/about1.tif -------------------------------------------------------------------------------- /java/howtos/images/about/about1.tif.txt: -------------------------------------------------------------------------------- 1 | attribution This image courtesy of Tom Deerinck 2 | attribution via a Creative Commons license 3 | fontsize 45 4 | color 255 255 0 -------------------------------------------------------------------------------- /java/howtos/images/about/about2.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/java/howtos/images/about/about2.tif -------------------------------------------------------------------------------- /java/howtos/images/about/about2.tif.txt: -------------------------------------------------------------------------------- 1 | attribution This image courtesy of Spike Walker 2 | attribution via a Creative Commons license 3 | fontsize 50 4 | color 255 140 0 5 | -------------------------------------------------------------------------------- /java/howtos/images/about/about3.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/java/howtos/images/about/about3.tif -------------------------------------------------------------------------------- /java/howtos/images/about/about3.tif.txt: -------------------------------------------------------------------------------- 1 | attribution This image from ESO/J. Emerson/VISTA 2 | attribution Cambridge Astronomical Survey Unit 3 | fontsize 40 4 | color 255 255 0 -------------------------------------------------------------------------------- /java/howtos/images/about/about4.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/java/howtos/images/about/about4.tif -------------------------------------------------------------------------------- /java/howtos/images/about/about4.tif.txt: -------------------------------------------------------------------------------- 1 | attribution This image courtesy of Hank L. Oppenheimer 2 | attribution via a Creative Commons license 3 | color 255 255 0 -------------------------------------------------------------------------------- /java/howtos/images/about/about5.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/java/howtos/images/about/about5.tif -------------------------------------------------------------------------------- /java/howtos/images/about/about5.tif.txt: -------------------------------------------------------------------------------- 1 | attribution This image courtesy of Annie Cavanagh 2 | attribution via a Creative Commons license 3 | fonstsize 30 4 | color 0 255 0 5 | -------------------------------------------------------------------------------- /java/howtos/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | howtos 17 | 1.0.0-SNAPSHOT 18 | 19 | ImageJ HowTos 20 | This project contains HowTos for ImageJ Java development. 21 | https://github.com/[MY-ORG]/[MY-REPO] 22 | 2013 23 | 24 | [MY-ORGANIZATION-NAME] 25 | [MY-ORGANIZATION-WEB-SITE] 26 | 27 | 28 | 29 | Unlicense 30 | https://unlicense.org/ 31 | repo 32 | 33 | 34 | 35 | 36 | 37 | frauzufall 38 | Deborah Schmidt 39 | https://imagej.net/User:Frauzufall 40 | 41 | 42 | 43 | 44 | None 45 | 46 | 47 | 48 | 49 | 50 | Image.sc Forum 51 | https://forum.image.sc/tags/imagej 52 | 53 | 54 | 55 | 56 | scm:git:git://github.com/[MY-ORG]/[MY-REPO] 57 | scm:git:git@github.com:[MY-ORG]/[MY-REPO] 58 | HEAD 59 | https://github.com/[MY-ORG]/[MY-REPO] 60 | 61 | 62 | GitHub Issues 63 | http://github.com/[MY-ORG]/[MY-REPO]/issues 64 | 65 | 66 | None 67 | 68 | 69 | 70 | HelloWorld 71 | unlicense 72 | N/A 73 | ImageJ software for multidimensional image processing and analysis. 74 | 75 | 76 | 77 | 78 | scijava.public 79 | https://maven.scijava.org/content/groups/public 80 | 81 | 82 | 83 | 84 | 85 | net.imagej 86 | imagej 87 | 88 | 89 | net.imagej 90 | imagej-legacy 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/README.md: -------------------------------------------------------------------------------- 1 | # Java HowTos for ImageJ2 2 | 3 | This repository is supposed to help Java developers write code based on ImageJ2 and SciJava. 4 | 5 | ## How to contribute 6 | 7 | ### Adding questions 8 | Please let us know of missing questions! You can add a comment on [this issue](https://github.com/imagej/tutorials/issues/80). 9 | 10 | ### Adding HowTos 11 | You know a solution to one of the [open questions](https://github.com/imagej/tutorials/issues/80) or there is something you figured out and want to share with others? Great! Either add a comment with a solution in the [open questions](https://github.com/imagej/tutorials/issues/80) issue or create the HowTo youself and file a PR. 12 | 13 | Make use of the [template](Template.java)! 14 | 15 | #### Guidelines 16 | - The idea is to have one class per question (how to do X?). 17 | - Questions are sorted into categories (= directories). 18 | - Keep each solution as simple and short as possible. 19 | - Each solution is represented as a static method. 20 | - The solutions can directly be executed via main method. 21 | - Comments are used to explain what exactly the code is doing. 22 | 23 | ![Howtos directory map](../../../../../images/howto_map.png) -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/Template.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | /** 14 | * How to do X 15 | * @author YOURNAME 16 | */ 17 | public class Template { 18 | 19 | /** 20 | * You can use the JavaDoc to add a note to the solution, if there is only one solution, you can also remove this 21 | */ 22 | public static void firstSolution() { 23 | 24 | // use comments to explain the code 25 | ImageJ ij = new ImageJ(); 26 | 27 | // do something 28 | 29 | //print something to show that it worked, or show a result image, ... 30 | 31 | } 32 | 33 | /** 34 | * .. this is another approach: (maybe explain in which situation to use which approach) 35 | */ 36 | public static void secondSolution() { 37 | 38 | // add your code here 39 | 40 | } 41 | 42 | public static void main(String...args) { 43 | firstSolution(); 44 | secondSolution(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/adv/IntroToImageJAPI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.adv; 9 | 10 | import java.net.URL; 11 | 12 | import net.imagej.ImageJ; 13 | 14 | /** An introduction to the ImageJ API. */ 15 | public class IntroToImageJAPI { 16 | 17 | public static void main(final String... args) throws Exception { 18 | // The first step when working with ImageJ is to create an *ImageJ 19 | // application context*. This is an instance of the class net.imagej.ImageJ, 20 | // and is created as follows: 21 | final ImageJ ij = new ImageJ(); 22 | // This context provides access to ImageJ operations and data structures. 23 | 24 | // ------------------------------------------------------------------------ 25 | // COMPARISON WITH IMAGEJ 1.x: 26 | // ImageJ 1.x has a similar concept with the ij.ImageJ class, which is 27 | // created using "new ImageJ()" and cached statically as a singleton. 28 | // This allows the ImageJ instance to be recovered later by calling 29 | // IJ.getInstance(), and simplifies the API in some ways. 30 | // However, the assumption that there will only ever be one ImageJ per JVM 31 | // limits its flexibility, and the fact that ij.ImageJ extends 32 | // java.awt.Frame makes ImageJ 1.x difficult to use headless or with 33 | // user interfaces other than Java AWT. 34 | // ------------------------------------------------------------------------ 35 | 36 | // ImageJ's functionality is divided into *services*. 37 | // Each service provides some API methods for performing related tasks. 38 | 39 | // ------------------------------------------------------------------------ 40 | // COMPARISON WITH IMAGEJ 1.x: 41 | // ImageJ 1.x is not service-driven, which makes it less extensible, 42 | // since additional functionality cannot be registered with the context. 43 | // ------------------------------------------------------------------------ 44 | 45 | // Here are some examples of the API in action: 46 | 47 | // The plugin service manages the available ImageJ plugins. 48 | final int pluginCount = ij.plugin().getIndex().size(); 49 | System.out.println("There are " + pluginCount + " plugins available."); 50 | // See the intro-to-plugins tutorial for more information on plugins. 51 | 52 | // The log service is used for logging messages. 53 | ij.log().warn("Death Star approaching!"); 54 | 55 | // The status service is used to report the current status of operations. 56 | ij.status().showStatus("It's nine o'clock and all is well."); 57 | 58 | // The menu service organizes a menu hierarchy for ImageJ commands. 59 | final int menuItemCount = ij.menu().getMenu().size(); 60 | System.out.println("There are " + menuItemCount + " menu items total."); 61 | // See the intro-to-menus tutorial for more information on menus. 62 | 63 | // The platform service handles platform-specific functionality. 64 | // E.g., it can open a URL in the default web browser for your system: 65 | ij.platform().open(new URL("http://imagej.net/")); 66 | // See the intro-to-platforms tutorial for more information on platforms. 67 | 68 | // To learn more about the services API, see the intro-to-services tutorial. 69 | // Many services also have their own dedicated tutorials. 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/adv/ModernFromLegacy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.adv; 9 | 10 | import ij.IJ; 11 | import ij.gui.GenericDialog; 12 | import ij.plugin.PlugIn; 13 | 14 | import net.imagej.ImageJ; 15 | 16 | import org.scijava.Context; 17 | import org.scijava.table.DefaultGenericTable; 18 | import org.scijava.table.GenericTable; 19 | 20 | /** 21 | * 22 | * Demonstrates how to call the modern ImageJ API from a legacy ImageJ1 plugin. 23 | * This example displays a table. 24 | * 25 | */ 26 | public class ModernFromLegacy implements PlugIn { 27 | 28 | @Override 29 | public void run(final String arg) { 30 | // ask user for number of rows & columns 31 | final GenericDialog gd = new GenericDialog("Display a Table"); 32 | gd.addNumericField("Rows", 50, 0); 33 | gd.addNumericField("Columns", 10, 0); 34 | gd.showDialog(); 35 | if (gd.wasCanceled()) return; 36 | final int rowCount = (int) gd.getNextNumber(); 37 | final int colCount = (int) gd.getNextNumber(); 38 | 39 | displayTable(rowCount, colCount); 40 | } 41 | 42 | private void displayTable(final int rowCount, final int colCount) { 43 | // retrieve the ImageJ application context 44 | final Context context = (Context) IJ.runPlugIn("org.scijava.Context", ""); 45 | final ImageJ ij = new ImageJ(context); 46 | 47 | // create a spreadsheet 48 | final GenericTable spreadsheet = 49 | new DefaultGenericTable(colCount, rowCount); 50 | for (int col = 0; col < colCount; col++) { 51 | final char letter = (char) ('A' + col); 52 | spreadsheet.setColumnHeader(col, "" + letter); 53 | for (int row = 0; row < rowCount; row++) { 54 | final String data = "" + letter + (row + 1); 55 | spreadsheet.set(col, row, data); 56 | } 57 | } 58 | 59 | // display the spreadsheet 60 | ij.ui().show("Spreadsheet", spreadsheet); 61 | } 62 | 63 | /** Tests the plugin. */ 64 | public static void main(final String... args) { 65 | final ImageJ ij = new ImageJ(); 66 | ij.launch(args); 67 | 68 | IJ.runPlugIn(ModernFromLegacy.class.getName(), ""); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/app/DisposeImageJ.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.app; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | /** 14 | * How to dispose {@link ImageJ} 15 | * 16 | * @author Deborah Schmidt 17 | */ 18 | public class DisposeImageJ { 19 | 20 | public static void run() { 21 | 22 | // start ImageJ 23 | ImageJ ij = new ImageJ(); 24 | 25 | // do something with ImageJ 26 | 27 | // dispose ImageJ 28 | ij.dispose(); 29 | } 30 | 31 | public static void main(String...args) { run(); } 32 | } 33 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/app/GetImageJDirectory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.app; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | import java.io.File; 14 | 15 | /** 16 | * How to get the current SciJava application installation directory 17 | * 18 | * @author Deborah Schmidt 19 | */ 20 | public class GetImageJDirectory { 21 | 22 | private static void run() { 23 | ImageJ ij = new ImageJ(); 24 | File base = ij.app().getApp().getBaseDirectory(); 25 | System.out.println(base.getAbsolutePath()); 26 | } 27 | 28 | public static void main(String...args) { run(); } 29 | } 30 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/app/GetJARsInClassPath.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.app; 10 | 11 | import java.net.URL; 12 | import java.net.URLClassLoader; 13 | 14 | /** 15 | * How to list all JARs in the current classpath 16 | * 17 | * @author Deborah Schmidt 18 | */ 19 | public class GetJARsInClassPath { 20 | 21 | private static void run() { 22 | ClassLoader cl = ClassLoader.getSystemClassLoader(); 23 | for(URL url: ((URLClassLoader)cl).getURLs()){ 24 | System.out.println(url.getPath()); 25 | } 26 | } 27 | 28 | public static void main(String...args) { 29 | run(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/app/GetSystemInformation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.app; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.command.CommandModule; 13 | 14 | import java.util.concurrent.ExecutionException; 15 | 16 | /** 17 | * How to get a bunch of useful information about your system and installation 18 | * 19 | * @author Deborah Schmidt 20 | */ 21 | public class GetSystemInformation { 22 | 23 | /** 24 | * .. using the SciJava command SystemInformation 25 | */ 26 | private static void run() throws ExecutionException, InterruptedException { 27 | ImageJ ij = new ImageJ(); 28 | CommandModule module = ij.command().run("org.scijava.plugins.commands.debug.SystemInformation", true).get(); 29 | String result = (String) module.getOutput("info"); 30 | System.out.println(result); 31 | } 32 | 33 | public static void main(String...args) throws ExecutionException, InterruptedException { run(); } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/app/GetVersionOfMavenArtifact.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.app; 10 | 11 | import org.scijava.util.POM; 12 | 13 | import java.util.List; 14 | import java.util.Optional; 15 | 16 | /** 17 | * How to get the version of a specific maven artifact in the current class loader 18 | * 19 | * @author Deborah Schmidt 20 | */ 21 | public class GetVersionOfMavenArtifact { 22 | 23 | private static void run() { 24 | 25 | List poms = POM.getAllPOMs(); 26 | Optional imageJOpsPOM = poms.stream().filter(pom -> pom.getArtifactId().equalsIgnoreCase("imagej-ops")).findFirst(); 27 | if(imageJOpsPOM.isPresent()) { 28 | String version = imageJOpsPOM.get().getVersion(); 29 | System.out.println(version); 30 | } 31 | 32 | } 33 | 34 | /** 35 | * .. by explicitly asking for the version tag: project/version. This can be used to query any other entries as well. 36 | */ 37 | private static void runWithPath() { 38 | 39 | List poms = POM.getAllPOMs(); 40 | POM imageJOpsPOM = null; 41 | for(POM pom : poms) { 42 | if(pom.getArtifactId().equalsIgnoreCase("imagej-ops")) { 43 | imageJOpsPOM = pom; 44 | break; 45 | } 46 | } 47 | if(imageJOpsPOM != null) { 48 | String version = imageJOpsPOM.cdata("project/version"); 49 | System.out.println(version); 50 | } 51 | 52 | } 53 | 54 | public static void main(String ... args) { 55 | run(); 56 | runWithPath(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/dynamic/DynamicCallbacks.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.dynamic; 9 | 10 | import java.util.Arrays; 11 | 12 | import net.imagej.Dataset; 13 | import net.imagej.ImageJ; 14 | import net.imagej.axis.Axes; 15 | import net.imagej.axis.AxisType; 16 | 17 | import org.scijava.command.Command; 18 | import org.scijava.command.DynamicCommand; 19 | import org.scijava.Initializable; 20 | import org.scijava.module.MutableModuleItem; 21 | import org.scijava.plugin.Parameter; 22 | import org.scijava.plugin.Plugin; 23 | import org.scijava.ui.UIService; 24 | import org.scijava.widget.ChoiceWidget; 25 | 26 | /** 27 | * An ImageJ2 command which dynamically alters aspects of its parameters when 28 | * parameter values change. 29 | *

30 | * NB: As of this writing, this command WILL NOT WORK AS DESIRED in the ImageJ 31 | * Legacy or ImageJ Swing UIs, due to limitations in the scijava-ui-swing input 32 | * harvester implementation. 33 | *

34 | */ 35 | @Plugin(type = Command.class) 36 | public class DynamicCallbacks extends DynamicCommand implements 37 | Initializable 38 | { 39 | 40 | // -- Parameters -- 41 | 42 | @Parameter 43 | private UIService ui; 44 | 45 | @Parameter(callback = "kindOfThingChanged", // 46 | choices = { "Animal", "Vegetable", "Mineral" }, 47 | style = ChoiceWidget.RADIO_BUTTON_HORIZONTAL_STYLE) 48 | private String kindOfThing = "Animal"; 49 | 50 | @Parameter(choices = {"a", "b", "c"}) 51 | private String thing = "a"; 52 | 53 | // -- Callback methods -- 54 | 55 | private void kindOfThingChanged() { 56 | final MutableModuleItem thingItem = // 57 | getInfo().getMutableInput("thing", String.class); 58 | switch (kindOfThing) { 59 | case "Animal": 60 | thingItem.setChoices(Arrays.asList("Lion", "Tiger", "Bear")); 61 | break; 62 | case "Vegetable": 63 | thingItem.setChoices(Arrays.asList("Sage", "Rosemary", "Thyme")); 64 | break; 65 | case "Mineral": 66 | thingItem.setChoices(Arrays.asList("Diamond", "Emerald", "Ruby")); 67 | break; 68 | default: 69 | thingItem.setChoices(Arrays.asList("???", "WAT", "OHNOEZ")); 70 | break; 71 | } 72 | } 73 | 74 | // -- Initializable methods -- 75 | 76 | @Override 77 | public void initialize() { getInfo(); } // HACK: Workaround for bug in SJC. 78 | 79 | // -- Runnable methods -- 80 | 81 | @Override 82 | public void run() { 83 | ui.showDialog("You chose: " + thing); 84 | } 85 | 86 | // -- Main method -- 87 | 88 | /** Tests our command. */ 89 | public static void main(final String... args) throws Exception { 90 | // Launch ImageJ as usual. 91 | final ImageJ ij = new ImageJ(); 92 | ij.launch(args); 93 | 94 | // Create a beautiful test image. 95 | long[] dims = {512, 128}; 96 | String name = "A spiffy blank image"; 97 | AxisType[] axes = {Axes.X, Axes.Y}; 98 | int bitsPerPixel = 8; 99 | boolean signed = false; 100 | boolean floating = false; 101 | final Dataset dataset = 102 | ij.dataset().create(dims, name, axes, bitsPerPixel, signed, floating); 103 | ij.ui().show(dataset); 104 | 105 | // Launch the "DynamicCallbacks" command. 106 | ij.command().run(DynamicCallbacks.class, true); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/dynamic/DynamicInitialization.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.dynamic; 9 | 10 | import net.imagej.Dataset; 11 | import net.imagej.ImageJ; 12 | import net.imagej.axis.Axes; 13 | import net.imagej.axis.AxisType; 14 | 15 | import org.scijava.command.Command; 16 | import org.scijava.command.DynamicCommand; 17 | import org.scijava.Initializable; 18 | import org.scijava.module.MutableModuleItem; 19 | import org.scijava.plugin.Parameter; 20 | import org.scijava.plugin.Plugin; 21 | import org.scijava.ui.UIService; 22 | import org.scijava.widget.NumberWidget; 23 | 24 | /** 25 | * An ImageJ2 command which dynamically computes aspects of its parameters 26 | * during initialization. 27 | */ 28 | @Plugin(type = Command.class) 29 | public class DynamicInitialization extends DynamicCommand implements 30 | Initializable 31 | { 32 | 33 | // -- Parameters -- 34 | 35 | @Parameter 36 | private UIService ui; 37 | 38 | @Parameter 39 | private Dataset image; 40 | 41 | @Parameter(min = "0", style = NumberWidget.SCROLL_BAR_STYLE) 42 | private int dimension; 43 | 44 | // -- Initializable methods -- 45 | 46 | @Override 47 | public void initialize() { 48 | final MutableModuleItem dimensionItem = // 49 | getInfo().getMutableInput("dimension", Integer.class); 50 | dimensionItem.setMaximumValue(image.numDimensions() - 1); 51 | } 52 | 53 | // -- Runnable methods -- 54 | 55 | @Override 56 | public void run() { 57 | ui.showDialog("You chose dimension #" + dimension); 58 | } 59 | 60 | // -- Main method -- 61 | 62 | /** Tests our command. */ 63 | public static void main(final String... args) throws Exception { 64 | // Launch ImageJ as usual. 65 | final ImageJ ij = new ImageJ(); 66 | ij.launch(args); 67 | 68 | // Create a beautiful test image. 69 | long[] dims = {512, 64, 2, 3}; 70 | String name = "A blank 4D image"; 71 | AxisType[] axes = {Axes.X, Axes.Y, Axes.Z, Axes.TIME}; 72 | int bitsPerPixel = 8; 73 | boolean signed = false; 74 | boolean floating = false; 75 | final Dataset dataset = 76 | ij.dataset().create(dims, name, axes, bitsPerPixel, signed, floating); 77 | ij.ui().show(dataset); 78 | 79 | // Launch the "DynamicInitialization" command. 80 | ij.command().run(DynamicInitialization.class, true); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/dynamic/DynamicNumberOfParameters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.dynamic; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import net.imagej.Dataset; 14 | import net.imagej.ImageJ; 15 | import net.imagej.axis.Axes; 16 | import net.imagej.axis.AxisType; 17 | 18 | import org.scijava.command.Command; 19 | import org.scijava.command.DynamicCommand; 20 | import org.scijava.module.DefaultMutableModuleItem; 21 | import org.scijava.Initializable; 22 | import org.scijava.module.ModuleItem; 23 | import org.scijava.plugin.Parameter; 24 | import org.scijava.plugin.Plugin; 25 | import org.scijava.ui.UIService; 26 | 27 | /** 28 | * An ImageJ2 command which dynamically introduces new parameters during 29 | * initialization. 30 | */ 31 | @Plugin(type = Command.class) 32 | public class DynamicNumberOfParameters extends DynamicCommand implements 33 | Initializable 34 | { 35 | 36 | // -- Parameters -- 37 | 38 | @Parameter 39 | private UIService ui; 40 | 41 | @Parameter 42 | private Dataset image; 43 | 44 | private List> checkboxItems = new ArrayList<>(); 45 | 46 | // -- Initializable methods -- 47 | 48 | @Override 49 | public void initialize() { 50 | // Introduce one boolean checkbox per dimension of the image. 51 | for (int d = 0; d < image.numDimensions(); d++) { 52 | final ModuleItem item = new DefaultMutableModuleItem<>(getInfo(), 53 | "axis" + d, boolean.class); 54 | item.setLabel("Axis #" + d + " - " + image.axis(d).type()); 55 | checkboxItems.add(item); 56 | getInfo().addInput(item); 57 | } 58 | } 59 | 60 | // -- Runnable methods -- 61 | 62 | @Override 63 | public void run() { 64 | int count = 0; 65 | for (ModuleItem item : checkboxItems) { 66 | if (item.getValue(this)) count++; 67 | } 68 | switch (count) { 69 | case 0: ui.showDialog("You selected no dimensions"); break; 70 | case 1: ui.showDialog("You selected one dimension"); break; 71 | default: ui.showDialog("You selected " + count + " dimensions"); 72 | } 73 | } 74 | 75 | // -- Main method -- 76 | 77 | /** Tests our command. */ 78 | public static void main(final String... args) throws Exception { 79 | // Launch ImageJ as usual. 80 | final ImageJ ij = new ImageJ(); 81 | ij.launch(args); 82 | 83 | // Create a beautiful test image. 84 | long[] dims = {512, 64, 2, 3}; 85 | String name = "A blank 4D image"; 86 | AxisType[] axes = {Axes.X, Axes.Y, Axes.Z, Axes.TIME}; 87 | int bitsPerPixel = 8; 88 | boolean signed = false; 89 | boolean floating = false; 90 | final Dataset dataset = 91 | ij.dataset().create(dims, name, axes, bitsPerPixel, signed, floating); 92 | ij.ui().show(dataset); 93 | 94 | // Launch the "DynamicNumberOfParameters" command. 95 | ij.command().run(DynamicNumberOfParameters.class, true); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/simple/CopyLabels.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.simple; 9 | 10 | import ij.IJ; 11 | import ij.ImagePlus; 12 | import net.imagej.ImageJ; 13 | 14 | import org.scijava.command.Command; 15 | import org.scijava.command.ContextCommand; 16 | import org.scijava.plugin.Parameter; 17 | import org.scijava.plugin.Plugin; 18 | 19 | /** A command that preserves the labels from one image to another. */ 20 | @Plugin(type = Command.class) 21 | public class CopyLabels extends ContextCommand { 22 | 23 | /** Image with desired labels. */ 24 | @Parameter 25 | private ImagePlus source; 26 | 27 | /** Image to which labels should be assigned. */ 28 | @Parameter 29 | private ImagePlus target; 30 | 31 | @Override 32 | public void run() { 33 | final int sourceSize = source.getStackSize(); 34 | final int targetSize = target.getStackSize(); 35 | if (sourceSize != targetSize) { 36 | cancel("Source and target images must have the same number of slices." + 37 | "(" + sourceSize + " != " + targetSize +")"); 38 | return; 39 | } 40 | for (int i=1; i<=sourceSize; i++) { 41 | final String label = source.getStack().getSliceLabel(i); 42 | target.getStack().setSliceLabel(label, i); 43 | } 44 | target.repaintWindow(); 45 | } 46 | 47 | /** A {@code main()} method for testing. */ 48 | public static void main(final String... args) { 49 | // Launch ImageJ as usual. 50 | final ImageJ ij = new ImageJ(); 51 | ij.launch(args); 52 | 53 | // Create an image with fancy slice labels. 54 | IJ.newImage("Fancy", "8-bit", 384, 64, 2); 55 | final ImagePlus fancy = IJ.getImage(); 56 | fancy.getStack().setSliceLabel("The quick brown fox", 1); 57 | fancy.getStack().setSliceLabel("jumps over the lazy dogs", 2); 58 | fancy.repaintWindow(); 59 | 60 | // Create an image without slice labels. 61 | IJ.newImage("Simple", "8-bit", 400, 50, 2); 62 | final ImagePlus simple = IJ.getImage(); 63 | 64 | // Test our "CopyLabels" command. 65 | ij.command().run(CopyLabels.class, true, "source", fancy, "target", simple); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/simple/GradientImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.simple; 9 | 10 | import net.imagej.Dataset; 11 | import net.imagej.DatasetService; 12 | import net.imagej.ImageJ; 13 | import net.imagej.axis.Axes; 14 | import net.imagej.axis.AxisType; 15 | import net.imglib2.type.numeric.integer.UnsignedByteType; 16 | 17 | import org.scijava.ItemIO; 18 | import org.scijava.command.Command; 19 | import org.scijava.plugin.Parameter; 20 | import org.scijava.plugin.Plugin; 21 | 22 | /** 23 | * A command that generates a diagonal gradient image of user-given size. 24 | *

25 | * For an even simpler command, see {@link HelloWorld} in this same 26 | * package! 27 | *

28 | */ 29 | @Plugin(type = Command.class, headless = true, 30 | menuPath = "File>New>Gradient Image") 31 | public class GradientImage implements Command { 32 | 33 | @Parameter 34 | private DatasetService datasetService; 35 | 36 | @Parameter(min = "1") 37 | private int width = 512; 38 | 39 | @Parameter(min = "1") 40 | private int height = 512; 41 | 42 | @Parameter(type = ItemIO.OUTPUT) 43 | private Dataset dataset; 44 | 45 | @Override 46 | public void run() { 47 | // Generate a byte array containing the diagonal gradient. 48 | final byte[] data = new byte[width * height]; 49 | for (int x = 0; x < width; x++) { 50 | for (int y = 0; y < height; y++) { 51 | final int index = y * width + x; 52 | data[index] = (byte) (x + y); 53 | } 54 | } 55 | 56 | // Create an empty dataset. 57 | final String name = "Gradient Image"; 58 | final long[] dims = { width, height }; 59 | final AxisType[] axes = { Axes.X, Axes.Y }; 60 | dataset = datasetService.create(new UnsignedByteType(), dims, name, axes); 61 | 62 | // Populate the dataset with the gradient data. 63 | dataset.setPlane(0, data); 64 | 65 | // NB: Because the dataset is declared as an "OUTPUT" above, 66 | // ImageJ automatically takes care of displaying it afterwards! 67 | } 68 | 69 | /** Tests our command. */ 70 | public static void main(final String... args) throws Exception { 71 | // Launch ImageJ as usual. 72 | final ImageJ ij = new ImageJ(); 73 | ij.launch(args); 74 | 75 | // Launch the "Gradient Image" command right away. 76 | ij.command().run(GradientImage.class, true); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/simple/HelloWorld.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.simple; 9 | 10 | import net.imagej.ImageJ; 11 | 12 | import org.scijava.ItemIO; 13 | import org.scijava.command.Command; 14 | import org.scijava.plugin.Parameter; 15 | import org.scijava.plugin.Plugin; 16 | 17 | /** 18 | * A very simple plugin. 19 | *

20 | * The annotation {@code @Plugin} lets ImageJ know that this is a plugin. There 21 | * are a vast number of possible plugins; {@code Command} plugins are the most 22 | * common one: they take inputs and produce outputs. 23 | *

24 | *

25 | * A {@link Command} is most useful when it is bound to a menu item; that is 26 | * what the {@code menuPath} parameter of the {@code @Plugin} annotation does. 27 | *

28 | *

29 | * Each input to the command is specified as a field with the {@code @Parameter} 30 | * annotation. Each output is specified the same way, but with a 31 | * {@code @Parameter(type = ItemIO.OUTPUT)} annotation. 32 | *

33 | * 34 | * @author Johannes Schindelin 35 | * @author Curtis Rueden 36 | */ 37 | @Plugin(type = Command.class, headless = true, menuPath = "Help>Hello, World!") 38 | public class HelloWorld implements Command { 39 | 40 | @Parameter(label = "What is your name?") 41 | private String name = "J. Doe"; 42 | 43 | @Parameter(type = ItemIO.OUTPUT) 44 | private String greeting; 45 | 46 | /** 47 | * Produces an output with the well-known "Hello, World!" message. The 48 | * {@code run()} method of every {@link Command} is the entry point for 49 | * ImageJ: this is what will be called when the user clicks the menu entry, 50 | * after the inputs are populated. 51 | */ 52 | @Override 53 | public void run() { 54 | greeting = "Hello, " + name + "!"; 55 | } 56 | 57 | /** 58 | * A {@code main()} method for testing. 59 | *

60 | * When developing a plugin in an Integrated Development Environment (such as 61 | * Eclipse or NetBeans), it is most convenient to provide a simple 62 | * {@code main()} method that creates an ImageJ context and calls the plugin. 63 | *

64 | *

65 | * In particular, this comes in handy when one needs to debug the plugin: 66 | * after setting one or more breakpoints and populating the inputs (e.g. by 67 | * calling something like 68 | * {@code ij.command().run(MyPlugin.class, "inputImage", myImage)} where 69 | * {@code inputImage} is the name of the field specifying the input) debugging 70 | * becomes a breeze. 71 | *

72 | * 73 | * @param args unused 74 | */ 75 | public static void main(final String... args) { 76 | // Launch ImageJ as usual. 77 | final ImageJ ij = new ImageJ(); 78 | ij.launch(args); 79 | 80 | // Launch our "Hello World" command right away. 81 | ij.command().run(HelloWorld.class, true); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/simple/OpenImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.simple; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | 13 | import net.imagej.Dataset; 14 | import net.imagej.ImageJ; 15 | 16 | import org.scijava.ItemIO; 17 | import org.scijava.command.Command; 18 | import org.scijava.log.LogService; 19 | import org.scijava.plugin.Parameter; 20 | import org.scijava.plugin.Plugin; 21 | 22 | import io.scif.services.DatasetIOService; 23 | 24 | /** 25 | * This tutorial shows how to use ImageJ services to open an image and display 26 | * it to the user. 27 | *

28 | * A main method is provided so this class can be run directly from Eclipse (or 29 | * any other IDE). 30 | *

31 | *

32 | * Because this class implements {@link Command} and is annotated with 33 | * {@code @Plugin}, it will show up in the ImageJ menus: under Tutorials > 34 | * Open Image, as specified by the {@code menuPath} field of the {@code @Plugin} 35 | * annotation. 36 | *

37 | *

38 | * See also the {@code LoadAndDisplayDataset} tutorial. 39 | *

40 | */ 41 | @Plugin(type = Command.class, menuPath = "Tutorials>Open Image") 42 | public class OpenImage implements Command { 43 | 44 | /* 45 | * This first @Parameter is a core ImageJ service (and thus @Plugin). The 46 | * context will provide it automatically when this command is created. 47 | */ 48 | 49 | @Parameter 50 | private DatasetIOService datasetIOService; 51 | 52 | /* 53 | * In this command, we will be using functions that can throw exceptions. 54 | * Best practice is to log these exceptions to let the user know what went 55 | * wrong. By using the LogService to do this, we let the framework decide 56 | * the best place to display thrown errors. 57 | */ 58 | @Parameter 59 | private LogService logService; 60 | 61 | /* 62 | * We need to know what image to open. So, the framework will ask the user 63 | * via the active user interface to select a file to open. This command is 64 | * "UI agnostic": it does not need to know the specific user interface 65 | * currently active. 66 | */ 67 | @Parameter 68 | private File imageFile; 69 | 70 | /* 71 | * This command will produce an image that will automatically be shown by 72 | * the framework. Again, this command is "UI agnostic": how the image is 73 | * shown is not specified here. 74 | */ 75 | @Parameter(type = ItemIO.OUTPUT) 76 | private Dataset image; 77 | 78 | /* 79 | * The run() method is where we do the actual 'work' of the command. In this 80 | * case, it is fairly trivial because we are simply calling ImageJ Services. 81 | */ 82 | @Override 83 | public void run() { 84 | try { 85 | image = datasetIOService.open(imageFile.getAbsolutePath()); 86 | } 87 | catch (final IOException exc) { 88 | // Use the LogService to report the error. 89 | logService.error(exc); 90 | } 91 | } 92 | 93 | /* 94 | * This main method is for convenience - so you can run this command 95 | * directly from Eclipse (or any other IDE). 96 | * 97 | * It will launch ImageJ and then run this command using the CommandService. 98 | * This is equivalent to clicking "Tutorials>Open Image" in the UI. 99 | */ 100 | public static void main(final String... args) throws Exception { 101 | // Launch ImageJ as usual. 102 | final ImageJ ij = new ImageJ(); 103 | ij.launch(args); 104 | 105 | // Launch the "OpenImage" command. 106 | ij.command().run(OpenImage.class, true); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/commands/simple/OpenScaleSaveImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.commands.simple; 9 | 10 | import io.scif.services.DatasetIOService; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.util.Arrays; 15 | 16 | import net.imagej.Dataset; 17 | import net.imagej.DefaultDataset; 18 | import net.imagej.ImageJ; 19 | import net.imagej.ImgPlus; 20 | import net.imagej.ops.OpService; 21 | import net.imglib2.RandomAccessible; 22 | import net.imglib2.RandomAccessibleInterval; 23 | import net.imglib2.img.Img; 24 | import net.imglib2.img.ImgView; 25 | import net.imglib2.interpolation.InterpolatorFactory; 26 | import net.imglib2.interpolation.randomaccess.FloorInterpolatorFactory; 27 | import net.imglib2.interpolation.randomaccess.LanczosInterpolatorFactory; 28 | import net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory; 29 | import net.imglib2.interpolation.randomaccess.NearestNeighborInterpolatorFactory; 30 | import net.imglib2.type.numeric.RealType; 31 | 32 | import org.scijava.command.Command; 33 | import org.scijava.log.LogService; 34 | import org.scijava.plugin.Parameter; 35 | import org.scijava.plugin.Plugin; 36 | 37 | /** 38 | * This tutorial shows how to use open an image, scale it, then save it. 39 | *

40 | * A main method is provided so this class can be run directly from Eclipse (or 41 | * any other IDE). 42 | *

43 | *

44 | * Because this class implements {@link Command} and is annotated with 45 | * {@code @Plugin}, it will show up in the ImageJ menus: under Tutorials > 46 | * Open+Scale+Save Image, as specified by the {@code menuPath} field of the 47 | * {@code @Plugin} annotation. 48 | *

49 | *

50 | * See also the {@code LoadAndDisplayDataset} tutorial. 51 | *

52 | */ 53 | @Plugin(type = Command.class, menuPath = "Tutorials>Open+Scale+Save Image") 54 | public class OpenScaleSaveImage implements Command { 55 | 56 | // -- Scale method constants -- 57 | 58 | private static final String LANCZOS = "Lanczos"; 59 | private static final String N_LINEAR = "N-linear"; 60 | private static final String NEAREST_NEIGHBOR = "Nearest neighbor"; 61 | private static final String FLOOR = "Floor"; 62 | 63 | // -- Needed services -- 64 | 65 | // For opening and saving images. 66 | @Parameter 67 | private DatasetIOService datasetIOService; 68 | 69 | // For scaling the image. 70 | @Parameter 71 | private OpService ops; 72 | 73 | // For logging errors. 74 | @Parameter 75 | private LogService log; 76 | 77 | // -- Inputs to the command -- 78 | 79 | /** Location on disk of the input image. */ 80 | @Parameter(label = "Image to load") 81 | private File inputImage; 82 | 83 | /** Factor by which to scale the image. */ 84 | @Parameter(label = "Scale factor") 85 | private double factor = 2; 86 | 87 | @Parameter(label = "Scale method", // 88 | choices = { LANCZOS, N_LINEAR, NEAREST_NEIGHBOR, FLOOR }) 89 | private String method = LANCZOS; 90 | 91 | /** Location on disk to save the processed image. */ 92 | @Parameter(label = "Image to save") 93 | private File outputImage; 94 | 95 | @Override 96 | public void run() { 97 | try { 98 | // load the image 99 | final Dataset image = datasetIOService.open(inputImage.getAbsolutePath()); 100 | 101 | // scale the image 102 | final Dataset result = scaleImage(image); 103 | 104 | // save the image 105 | datasetIOService.save(result, outputImage.getAbsolutePath()); 106 | } 107 | catch (final IOException exc) { 108 | log.error(exc); 109 | } 110 | } 111 | 112 | private Dataset scaleImage(final Dataset dataset) { 113 | // NB: We must do a raw cast through Img, because Dataset does not 114 | // retain the recursive type parameter; it has an ImgPlus>. 115 | // This is invalid for routines that need Img>. 116 | @SuppressWarnings({ "rawtypes", "unchecked" }) 117 | final Img> result = scaleImage((Img) dataset.getImgPlus()); 118 | 119 | // Finally, coerce the result back to an ImageJ Dataset object. 120 | return new DefaultDataset(dataset.context(), new ImgPlus<>(result)); 121 | } 122 | 123 | private > Img scaleImage(final Img image) { 124 | final double[] scaleFactors = new double[image.numDimensions()]; 125 | Arrays.fill(scaleFactors, factor); 126 | 127 | final InterpolatorFactory> interpolator; 128 | switch (method) { 129 | case N_LINEAR: 130 | interpolator = new NLinearInterpolatorFactory<>(); 131 | break; 132 | case NEAREST_NEIGHBOR: 133 | interpolator = new NearestNeighborInterpolatorFactory<>(); 134 | break; 135 | case LANCZOS: 136 | interpolator = new LanczosInterpolatorFactory<>(); 137 | break; 138 | case FLOOR: 139 | interpolator = new FloorInterpolatorFactory<>(); 140 | break; 141 | default: 142 | throw new IllegalArgumentException("Invalid scale method: " + method); 143 | } 144 | 145 | // Perform the transformation using Ops. 146 | final RandomAccessibleInterval rai = // 147 | ops.transform().scaleView(image, scaleFactors, interpolator); 148 | return ImgView.wrap(rai, image.factory()); 149 | } 150 | 151 | /* 152 | * This main method is for convenience - so you can run this command 153 | * directly from Eclipse (or other IDE). 154 | * 155 | * It will launch ImageJ and then run this command using the CommandService. 156 | * This is equivalent to clicking "Tutorials>Open+Scale+Save Image" in the UI. 157 | */ 158 | public static void main(final String... args) throws Exception { 159 | // Launch ImageJ as usual. 160 | final ImageJ ij = new ImageJ(); 161 | ij.launch(args); 162 | 163 | // Launch the "OpenScaleSaveImage" command. 164 | ij.command().run(OpenScaleSaveImage.class, true); 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/datasets/LoadAndDisplayDataset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.datasets; 9 | 10 | import java.io.File; 11 | 12 | import net.imagej.Dataset; 13 | import net.imagej.ImageJ; 14 | 15 | /** Loads and displays a dataset using the ImageJ API. */ 16 | public class LoadAndDisplayDataset { 17 | 18 | public static void main(final String... args) throws Exception { 19 | // create the ImageJ application context with all available services 20 | final ImageJ ij = new ImageJ(); 21 | 22 | // ask the user for a file to open 23 | final File file = ij.ui().chooseFile(null, "open"); 24 | 25 | // load the dataset 26 | final Dataset dataset = ij.scifio().datasetIO().open(file.getPath()); 27 | 28 | // display the dataset 29 | ij.ui().show(dataset); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/displays/DisplayError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.displays; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.ui.DialogPrompt; 13 | 14 | /** 15 | * How to display an error 16 | * 17 | * @author Deborah Schmidt 18 | */ 19 | public class DisplayError { 20 | 21 | private static void run() { 22 | ImageJ ij = new ImageJ(); 23 | // TODO this looks the same as a plain message with legacy dependency 24 | ij.ui().showDialog("EXTERMINATE", DialogPrompt.MessageType.ERROR_MESSAGE); 25 | } 26 | 27 | public static void main(String...args) { 28 | run(); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/displays/DisplayInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.displays; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.ui.DialogPrompt; 13 | 14 | /** 15 | * How to display general information in a popup 16 | * 17 | * @author Deborah Schmidt 18 | */ 19 | public class DisplayInfo { 20 | 21 | private static void run() { 22 | ImageJ ij = new ImageJ(); 23 | ij.ui().showDialog("Everything is fine", DialogPrompt.MessageType.INFORMATION_MESSAGE); 24 | } 25 | 26 | public static void main(String...args) { 27 | run(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/displays/DisplayWarning.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.displays; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.ui.DialogPrompt; 13 | 14 | /** 15 | * How to display a warning 16 | * 17 | * @author Deborah Schmidt 18 | */ 19 | public class DisplayWarning { 20 | 21 | private static void run() { 22 | ImageJ ij = new ImageJ(); 23 | // TODO this looks the same as a plain message with legacy dependency 24 | ij.ui().showDialog("This is a warning", DialogPrompt.MessageType.WARNING_MESSAGE); 25 | ij.context().dispose(); 26 | } 27 | 28 | public static void main(String...args) { 29 | run(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/CommandThatChecksImageType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import net.imagej.Dataset; 12 | import net.imagej.ImageJ; 13 | import net.imagej.axis.Axes; 14 | import net.imagej.axis.AxisType; 15 | import net.imglib2.type.numeric.integer.UnsignedByteType; 16 | import net.imglib2.type.numeric.real.FloatType; 17 | 18 | import org.scijava.command.Command; 19 | import org.scijava.command.ContextCommand; 20 | import org.scijava.plugin.Parameter; 21 | import org.scijava.plugin.Plugin; 22 | 23 | @Plugin(type = Command.class) 24 | public class CommandThatChecksImageType extends ContextCommand { 25 | 26 | @Parameter(validater = "validateDataset") 27 | private Dataset dataset; 28 | 29 | public void validateDataset() { 30 | if (dataset.firstElement() instanceof UnsignedByteType) { 31 | cancel("This command only works with uint8 images."); 32 | } 33 | } 34 | 35 | @Override 36 | public void run() { 37 | System.out.println("The dataset '" + dataset.getName() + "' is uint8."); 38 | // ... do something with the image ... 39 | } 40 | 41 | public static void main(final String[] args) { 42 | final ImageJ ij = new ImageJ(); 43 | ij.ui().showUI(); 44 | 45 | final FloatType type = new FloatType(); 46 | final long[] dims = { 512, 384, 5 }; 47 | final String name = "Example"; 48 | final AxisType[] axes = { Axes.X, Axes.Y, Axes.Z }; 49 | final Dataset d = ij.dataset().create(type, dims, name, axes); 50 | ij.ui().show(d); 51 | 52 | ij.command().run(CommandThatChecksImageType.class, true); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/ExampleCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import org.scijava.ItemIO; 12 | import org.scijava.command.Command; 13 | import org.scijava.plugin.Parameter; 14 | import org.scijava.plugin.Plugin; 15 | 16 | @Plugin(type = Command.class, label = "Example Command") 17 | public class ExampleCommand implements Command { 18 | 19 | @Parameter 20 | String name; 21 | 22 | @Parameter(type = ItemIO.OUTPUT) 23 | String response; 24 | 25 | @Override 26 | public void run() { 27 | response = "I am " + name; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/ExampleDynamicCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import org.scijava.command.Command; 12 | import org.scijava.command.DynamicCommand; 13 | import org.scijava.plugin.Plugin; 14 | 15 | @Plugin(type = Command.class) 16 | public class ExampleDynamicCommand extends DynamicCommand { 17 | 18 | @Override 19 | public void run() { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/GetExampleCommandResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.command.CommandModule; 13 | 14 | import java.util.concurrent.ExecutionException; 15 | 16 | /** 17 | * How to get the result of a {@link org.scijava.command.Command} 18 | * 19 | * @author Deborah Schmidt 20 | */ 21 | public class GetExampleCommandResult { 22 | 23 | private static void run() throws ExecutionException, InterruptedException { 24 | ImageJ ij = new ImageJ(); 25 | CommandModule command = ij.command().run(ExampleCommand.class, true, "name", "Ada").get(); 26 | Object output = command.getOutput("response"); 27 | System.out.println(output); 28 | } 29 | 30 | public static void main(String...args) throws ExecutionException, InterruptedException { run(); } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/ListAllCommands.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.command.CommandInfo; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * How to list all available {@link org.scijava.command.Command}s 18 | * 19 | * @author Deborah Schmidt 20 | */ 21 | public class ListAllCommands { 22 | 23 | private static void run() { 24 | ImageJ ij = new ImageJ(); 25 | List commands = ij.command().getCommands(); 26 | for(CommandInfo info : commands) { 27 | System.out.println(info.getClassName()); 28 | } 29 | } 30 | 31 | public static void main(String...args) { 32 | run(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/ModifyCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.command.DynamicCommand; 13 | import org.scijava.module.MutableModuleItem; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.concurrent.ExecutionException; 18 | 19 | /** 20 | * How to modify a command programmatically and run it 21 | */ 22 | public class ModifyCommand { 23 | 24 | private static void run() throws ExecutionException, InterruptedException { 25 | 26 | ImageJ ij = new ImageJ(); 27 | ij.launch(); 28 | 29 | // create choices 30 | List columnNames = new ArrayList<>(); 31 | columnNames.add("item1"); 32 | columnNames.add("item2"); 33 | // set a name for the choices 34 | String choiceName = "name"; 35 | 36 | // create an instance of a dynamic command 37 | final DynamicCommand command = new ExampleDynamicCommand(); 38 | // inject the context so that the command can use services 39 | ij.context().inject(command); 40 | 41 | // create a string input 42 | MutableModuleItem choiceInput = command.addInput( choiceName, String.class ); 43 | // set the label and the choices of the input 44 | choiceInput.setLabel(choiceName); 45 | choiceInput.setChoices(columnNames); 46 | 47 | //run the command 48 | ij.module().run(command, true).get(); 49 | 50 | // get the choice of the user and print it 51 | String choiceValue = (String) command.getInput(choiceName); 52 | System.out.println(choiceValue); 53 | 54 | } 55 | 56 | public static void main(String...args) throws ExecutionException, InterruptedException { 57 | run(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/extensions/RunExampleCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.extensions; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | import java.util.concurrent.ExecutionException; 14 | 15 | /** 16 | * How to run a {@link org.scijava.command.Command} 17 | * 18 | * @author Deborah Schmidt 19 | */ 20 | public class RunExampleCommand { 21 | 22 | /** 23 | * .. this will run the Command in a new Thread: 24 | */ 25 | private static void run() { 26 | ImageJ ij = new ImageJ(); 27 | ij.ui().showUI(); 28 | ij.command().run(ExampleCommand.class, true); 29 | } 30 | 31 | /** 32 | * .. this is how you can attach parameters to the Command: 33 | */ 34 | private static void runWithParameters() { 35 | ImageJ ij = new ImageJ(); 36 | ij.ui().showUI(); 37 | ij.command().run(ExampleCommand.class, true, "name", "Ada"); 38 | } 39 | 40 | /** 41 | * .. how to wait for the Command to finish: 42 | */ 43 | private static void runAndWait() throws ExecutionException, InterruptedException { 44 | ImageJ ij = new ImageJ(); 45 | ij.ui().showUI(); 46 | ij.command().run(ExampleCommand.class, true, "name", "Ada").get(); 47 | } 48 | 49 | /** 50 | * .. how to avoid pre- and postprocessing (his will prevent the popup to open which asks the user for missing input parameters, this will also prevent output parameters to be displayed automatically): 51 | */ 52 | private static void runWithoutPrePostProcessing() { 53 | ImageJ ij = new ImageJ(); 54 | ij.command().run(ExampleCommand.class, false, "name", "Ada"); 55 | } 56 | 57 | public static void main(String...args) { 58 | run(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/headless/StartImageJHeadless.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.headless; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | /** 14 | * How to start {@link ImageJ} in headless mode 15 | * 16 | * @author Deborah Schmidt 17 | */ 18 | public class StartImageJHeadless { 19 | 20 | /** 21 | * .. using system properties before spinning a new ImageJ (this is "more secure" in that context initialization code will already know that everything is headless): 22 | */ 23 | private static void viaSystemProperty() { 24 | System.setProperty("java.awt.headless", "true"); 25 | ImageJ ij = new ImageJ(); 26 | System.out.println("headless: " + ij.ui().isHeadless()); 27 | } 28 | 29 | /** 30 | * .. by passing a command line argument: 31 | */ 32 | private static void viaCommandLineArgument() { 33 | ImageJ ij = new ImageJ(); 34 | ij.launch("--headless"); 35 | System.out.println("headless: " + ij.ui().isHeadless()); 36 | } 37 | 38 | /** 39 | * .. via UI service: 40 | */ 41 | private static void viaImageJUI() { 42 | ImageJ ij = new ImageJ(); 43 | ij.ui().setHeadless(true); 44 | System.out.println("headless: " + ij.ui().isHeadless()); 45 | } 46 | 47 | public static void main(String...args) { 48 | viaSystemProperty(); 49 | viaCommandLineArgument(); 50 | viaImageJUI(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/AddROIs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.images; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import net.imagej.Dataset; 14 | import net.imagej.ImageJ; 15 | import net.imagej.axis.Axes; 16 | import net.imagej.axis.AxisType; 17 | import net.imagej.display.ImageDisplay; 18 | import net.imagej.overlay.EllipseOverlay; 19 | import net.imagej.overlay.LineOverlay; 20 | import net.imagej.overlay.Overlay; 21 | import net.imagej.overlay.RectangleOverlay; 22 | 23 | import org.scijava.util.Colors; 24 | 25 | /** 26 | * Adds ROIs to a display. 27 | *

28 | * Please note that this API is not stable and will almost certainly 29 | * change prior to the final 2.0.0 release! 30 | *

31 | */ 32 | public class AddROIs { 33 | 34 | public static void main(final String... args) throws Exception { 35 | // create the ImageJ application context with all available services 36 | final ImageJ ij = new ImageJ(); 37 | 38 | // display the "swing" user interface 39 | ij.ui().showUI("swing"); 40 | 41 | // create a new dataset 42 | final int w = 512, h = 384; 43 | final Dataset dataset = 44 | ij.dataset().create(new long[] { w, h }, "ROI Demo", 45 | new AxisType[] { Axes.X, Axes.Y }, 8, false, false); 46 | 47 | // create a display for the dataset 48 | final ImageDisplay imageDisplay = 49 | (ImageDisplay) ij.display().createDisplay(dataset); 50 | 51 | // create a line 52 | final LineOverlay line = new LineOverlay(ij.getContext(), 53 | new double[] { 0, 0 }, new double[] { w, h }); 54 | line.setLineColor(Colors.PLUM); 55 | line.setLineWidth(1.5); 56 | 57 | // create a rectangle 58 | final RectangleOverlay rectangle = new RectangleOverlay(ij.getContext()); 59 | rectangle.setOrigin(3 * w / 5, 0); 60 | rectangle.setOrigin(h / 5, 1); 61 | rectangle.setExtent(w / 4, 0); 62 | rectangle.setExtent(h / 4, 1); 63 | rectangle.setLineColor(Colors.HONEYDEW); 64 | rectangle.setLineWidth(2); 65 | rectangle.setFillColor(Colors.TOMATO); 66 | rectangle.setAlpha(190); 67 | 68 | // create an ellipse 69 | final EllipseOverlay ellipse = new EllipseOverlay(ij.getContext()); 70 | ellipse.setOrigin(w / 4, 0); 71 | ellipse.setOrigin(3 * h / 4, 1); 72 | ellipse.setRadius(w / 8, 0); 73 | ellipse.setRadius(h / 8, 1); 74 | ellipse.setLineColor(Colors.CHOCOLATE); 75 | ellipse.setLineWidth(8); 76 | ellipse.setFillColor(Colors.PEACHPUFF); 77 | ellipse.setAlpha(120); 78 | 79 | // add the overlays to the display 80 | final List overlays = new ArrayList(); 81 | overlays.add(line); 82 | overlays.add(rectangle); 83 | overlays.add(ellipse); 84 | ij.overlay().addOverlays(imageDisplay, overlays); 85 | 86 | // show the display 87 | ij.ui().show(imageDisplay); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/ConvertImageClasses.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import ij.ImagePlus; 12 | import io.scif.img.IO; 13 | import net.imagej.ImageJ; 14 | import net.imagej.ImgPlus; 15 | import net.imagej.axis.Axes; 16 | import net.imagej.axis.AxisType; 17 | import net.imglib2.IterableInterval; 18 | import net.imglib2.RandomAccessibleInterval; 19 | import net.imglib2.img.Img; 20 | import net.imglib2.img.display.imagej.ImageJFunctions; 21 | import net.imglib2.view.Views; 22 | 23 | import java.io.IOException; 24 | 25 | /** 26 | * How to convert between various image class representations 27 | * 28 | * @author Deborah Schmidt 29 | */ 30 | public class ConvertImageClasses { 31 | 32 | /** 33 | * .. wrapping {@link Img} as {@link ImgPlus}: 34 | */ 35 | private static void imgToImgPlus() throws IOException { 36 | ImageJ ij = new ImageJ(); 37 | Img img = ij.op().create().img(new int[]{10, 20, 3}); 38 | ImgPlus imgPlus = new ImgPlus(img, "image", new AxisType[]{Axes.X, Axes.Y, Axes.CHANNEL}); 39 | System.out.println(imgPlus); 40 | } 41 | 42 | /** 43 | * .. converting {@link RandomAccessibleInterval} to {@link IterableInterval}: 44 | */ 45 | private static void raiToIterableInterval() throws IOException { 46 | ImageJ ij = new ImageJ(); 47 | RandomAccessibleInterval rai = ij.op().create().img(new int[]{10, 20, 3}); 48 | IterableInterval ii = Views.iterable(rai); 49 | System.out.println(ii); 50 | } 51 | 52 | /** 53 | * .. converting {@link RandomAccessibleInterval} to {@link Img}: 54 | */ 55 | private static void raiToImg() { 56 | ImageJ ij = new ImageJ(); 57 | RandomAccessibleInterval rai = ij.op().create().img(new int[]{10, 20, 3}); 58 | Img img = (Img) rai; 59 | System.out.println(img); 60 | } 61 | 62 | /** 63 | * .. converting {@link RandomAccessibleInterval} to IJ1 {@link ImagePlus}: 64 | */ 65 | private static void raiToImagePlus() { 66 | ImageJ ij = new ImageJ(); 67 | RandomAccessibleInterval rai = ij.op().create().img(new int[]{10, 20, 3}); 68 | ImagePlus imp = ImageJFunctions.wrap(rai, "image"); 69 | System.out.println(imp); 70 | } 71 | 72 | /** 73 | * .. converting IJ1 {@link ImagePlus} to {@link Img}: 74 | */ 75 | private static void imagePlusToImgPlus() { 76 | ImagePlus imp = new ImagePlus("https://samples.fiji.sc/blobs.png"); 77 | Img img = ImageJFunctions.wrap(imp); 78 | System.out.println(img); 79 | } 80 | 81 | public static void main(String... args) throws IOException { 82 | imgToImgPlus(); 83 | raiToIterableInterval(); 84 | raiToImg(); 85 | raiToImagePlus(); 86 | imagePlusToImgPlus(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/CreateImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imagej.ImgPlus; 13 | import net.imagej.axis.Axes; 14 | import net.imagej.axis.AxisType; 15 | import net.imglib2.cache.img.DiskCachedCellImgFactory; 16 | import net.imglib2.img.Img; 17 | import net.imglib2.img.array.ArrayImgFactory; 18 | import net.imglib2.type.numeric.integer.IntType; 19 | import net.imglib2.type.numeric.real.DoubleType; 20 | import net.imglib2.type.numeric.real.FloatType; 21 | 22 | /** 23 | * How to create an image 24 | * 25 | * @author Deborah Schmidt 26 | */ 27 | public class CreateImage { 28 | 29 | /** 30 | * .. this will create an {@link Img} using an ImgLib2 factory: 31 | */ 32 | public static void createImgWithImgLib2() { 33 | Img img = new ArrayImgFactory<>(new FloatType()).create(20, 30, 40); 34 | System.out.println(img); 35 | } 36 | 37 | /** 38 | * .. this will create an {@link Img} using imagej-ops: 39 | */ 40 | public static void createImgWithOps() { 41 | ImageJ ij = new ImageJ(); 42 | Img img = ij.op().create().img(new long[] { 20, 30, 40}); 43 | System.out.println(img); 44 | } 45 | 46 | /** 47 | * .. this will create a {@code Img} with the dimensions of an existing {@code Img} 48 | */ 49 | public static void createImgFromExistingDimensions() { 50 | ImageJ ij = new ImageJ(); 51 | Img existing = ij.op().create().img(new long[] { 20, 30, 40 }); 52 | Img img = ij.op().create().img(existing, new IntType()); 53 | System.out.println(img); 54 | } 55 | /** 56 | * .. this will create an {@link Img} cached to disk (e.g. in case it does not fit in memory) 57 | */ 58 | public static void createCachedImg() { 59 | Img img = new DiskCachedCellImgFactory<>(new FloatType()).create(1000, 2000, 500); 60 | System.out.println(img); 61 | } 62 | 63 | /** 64 | * .. this will create an {@link ImgPlus} which can for example hold information about the axes of the image: 65 | */ 66 | public static void createImgPlus() { 67 | Img img = new ArrayImgFactory<>(new FloatType()).create(100, 200, 50); 68 | ImgPlus imgPlus = new ImgPlus(img, "raw", new AxisType[]{Axes.X, Axes.Y, Axes.TIME}); 69 | System.out.println(imgPlus); 70 | } 71 | 72 | /** 73 | * .. this will create an {@link ImgPlus} from {@link Img} using imagej-ops 74 | */ 75 | public static void createImgPlusWithOps() { 76 | ImageJ ij = new ImageJ(); 77 | Img img = ij.op().create().img(new long[] { 20, 30, 40 }); 78 | ImgPlus imgPlus = ij.op().create().imgPlus(img); 79 | System.out.println(imgPlus); 80 | } 81 | 82 | public static void main(String... args) { 83 | createImgWithImgLib2(); 84 | createImgWithOps(); 85 | createImgFromExistingDimensions(); 86 | createCachedImg(); 87 | createImgPlus(); 88 | createImgPlusWithOps(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/DuplicateImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imglib2.RandomAccessibleInterval; 13 | import net.imglib2.img.Img; 14 | import net.imglib2.img.array.ArrayImgFactory; 15 | import net.imglib2.type.numeric.real.FloatType; 16 | 17 | /** 18 | * How to copy / duplicate an image 19 | * 20 | * @author Deborah Schmidt 21 | */ 22 | public class DuplicateImage { 23 | 24 | /** 25 | * .. copy an {@link Img}: 26 | */ 27 | private static void copyImg() { 28 | Img img = new ArrayImgFactory<>(new FloatType()).create(100, 200, 50); 29 | Img imgCopy = img.copy(); 30 | System.out.println(imgCopy); 31 | } 32 | 33 | /** 34 | * .. copy a {@link RandomAccessibleInterval} using imagej-ops: 35 | */ 36 | private static void copyRaiUsingOps() { 37 | ImageJ ij = new ImageJ(); 38 | RandomAccessibleInterval rai = new ArrayImgFactory<>(new FloatType()).create(100, 200, 50); 39 | RandomAccessibleInterval raiCopy = ij.op().copy().rai(rai); 40 | System.out.println(raiCopy); 41 | } 42 | 43 | public static void main(String... args) { 44 | copyImg(); 45 | copyRaiUsingOps(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/GetOpenImages.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import net.imagej.Dataset; 12 | import net.imagej.ImageJ; 13 | 14 | import java.io.IOException; 15 | import java.util.List; 16 | 17 | /** 18 | * How to get all open images 19 | * 20 | * @author Deborah Schmidt 21 | */ 22 | public class GetOpenImages { 23 | 24 | private static void run() throws IOException { 25 | 26 | ImageJ ij = new ImageJ(); 27 | 28 | // open images 29 | Object img1 = ij.io().open("http://samples.fiji.sc/blobs.png"); 30 | Object img2 = ij.io().open("http://samples.fiji.sc/new-lenna.jpg"); 31 | 32 | // show images 33 | ij.ui().show(img1); 34 | ij.ui().show(img2); 35 | 36 | // get open images 37 | List datasets = ij.dataset().getDatasets(); 38 | 39 | // print their names 40 | String name1 = datasets.get(0).getName(); 41 | String name2 = datasets.get(1).getName(); 42 | System.out.println(name1); 43 | System.out.println(name2); 44 | 45 | } 46 | 47 | public static void main(String...args) throws IOException { 48 | run(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/OpenAndShowImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import io.scif.img.IO; 12 | import net.imagej.ImageJ; 13 | import net.imglib2.RandomAccessibleInterval; 14 | import net.imglib2.img.Img; 15 | import net.imglib2.img.display.imagej.ImageJFunctions; 16 | 17 | import java.io.IOException; 18 | 19 | /** 20 | * How to open and show an image 21 | * 22 | * @author Deborah Schmidt 23 | */ 24 | public class OpenAndShowImage { 25 | 26 | /** 27 | * .. from the ImageJ instance: 28 | */ 29 | private static void run() throws IOException { 30 | 31 | ImageJ ij = new ImageJ(); 32 | 33 | // open image from local resource 34 | Img img = (Img) ij.io().open(Object.class.getResource("/blobs.png").getPath()); 35 | 36 | // show image 37 | ij.ui().show(img); 38 | 39 | } 40 | 41 | /** 42 | * .. by using static methods:
43 | * (NOTE1: Only open images like this if you don't have and don't want a {@link org.scijava.Context}.) 44 | * (NOTE2: {@link ImageJFunctions#show} relies on ImageJ1.) 45 | */ 46 | private static void runStatic() { 47 | 48 | // open image statically 49 | Img img = IO.openAll(Object.class.getResource("/blobs.png").getPath()).get(0); 50 | 51 | // display image statically 52 | ImageJFunctions.show(img); 53 | } 54 | 55 | public static void main(String...args) throws IOException { 56 | run(); 57 | runStatic(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/SaveImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imglib2.img.Img; 13 | 14 | import java.io.IOException; 15 | import java.nio.file.Files; 16 | 17 | /** 18 | * How to save an image 19 | * 20 | * @author Deborah Schmidt 21 | */ 22 | public class SaveImage { 23 | 24 | private static void run() throws IOException { 25 | ImageJ ij = new ImageJ(); 26 | ij.ui().showUI(); 27 | 28 | // open image from resource 29 | Img img = (Img) ij.io().open(Object.class.getResource("/blobs.png").getPath()); 30 | 31 | // create temporary path to save image to 32 | String dest = Files.createTempFile("img", ".png").toString(); 33 | System.out.println("Saving image to " + dest); 34 | 35 | // save image 36 | ij.io().save(img, dest); 37 | 38 | // load and show saved image 39 | Object savedImg = ij.io().open(dest); 40 | ij.ui().show("saved image", savedImg); 41 | 42 | } 43 | 44 | public static void main(String...args) throws IOException { 45 | run(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/SaveImageCompressed.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images; 10 | 11 | import io.scif.config.SCIFIOConfig; 12 | import io.scif.formats.TIFFFormat; 13 | import io.scif.services.DatasetIOService; 14 | 15 | import java.io.IOException; 16 | import java.nio.file.Files; 17 | 18 | import net.imagej.Dataset; 19 | import net.imagej.DefaultDataset; 20 | import net.imagej.ImageJ; 21 | import net.imagej.ImgPlus; 22 | import net.imglib2.img.Img; 23 | 24 | import org.scijava.io.location.FileLocation; 25 | 26 | /** 27 | * How to save an image as LZW compressed TIFF 28 | * 29 | * @author Deborah Schmidt 30 | */ 31 | public class SaveImageCompressed { 32 | 33 | public static void run() throws IOException { 34 | 35 | ImageJ ij = new ImageJ(); 36 | 37 | // open image from resource 38 | Img img = (Img) ij.io().open(Object.class.getResource("/blobs.png").getPath()); 39 | 40 | // create temporary path to save image to 41 | FileLocation dest = new FileLocation(Files.createTempFile("img", ".tif").toFile()); 42 | System.out.println("Saving image to " + dest); 43 | 44 | // create SCIFIO config to set compression algorithm 45 | SCIFIOConfig config = new SCIFIOConfig().writerSetCompression(TIFFFormat.Writer.COMPRESSION_LZW); 46 | 47 | // create dataset from image 48 | Dataset dataset = new DefaultDataset(ij.context(), new ImgPlus<>(img)); 49 | 50 | // save image via DatasetIOService with SCIFIO config 51 | ij.get(DatasetIOService.class).save(dataset, dest, config); 52 | 53 | // load and show saved image 54 | Object savedImg = ij.io().open(dest.getFile().getAbsolutePath()); 55 | ij.ui().show("saved image", savedImg); 56 | } 57 | 58 | public static void main(String...args) throws IOException { 59 | run(); 60 | }; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/drawing/DrawCircle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images.drawing; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imglib2.RandomAccess; 13 | import net.imglib2.algorithm.region.hypersphere.HyperSphere; 14 | import net.imglib2.img.Img; 15 | import net.imglib2.type.numeric.real.DoubleType; 16 | 17 | /** 18 | * How to draw a circle 19 | * 20 | * @author Deborah Schmidt 21 | */ 22 | public class DrawCircle { 23 | 24 | private static void run() { 25 | 26 | ImageJ ij = new ImageJ(); 27 | 28 | Img img = ij.op().create().img(new long[] { 256, 254 }); 29 | 30 | RandomAccess ra = img.randomAccess(); 31 | ra.setPosition(new long[] { 70, 98 }); 32 | 33 | // draws circle of radius 30 at position [70, 98] 34 | new HyperSphere<>(img, ra, 30).forEach(value -> value.set(25)); 35 | 36 | ij.ui().show(img); 37 | 38 | } 39 | 40 | public static void main(String...args) { 41 | run(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/drawing/DrawRectangle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images.drawing; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imglib2.img.Img; 13 | import net.imglib2.type.numeric.real.DoubleType; 14 | import net.imglib2.util.Intervals; 15 | import net.imglib2.view.Views; 16 | 17 | /** 18 | * How to draw a rectangle 19 | * 20 | * @author Deborah Schmidt 21 | */ 22 | public class DrawRectangle { 23 | 24 | private static void run() { 25 | 26 | ImageJ ij = new ImageJ(); 27 | 28 | Img img = ij.op().create().img(new long[] { 256, 254 }); 29 | 30 | // draws rectangle at position [50. 60] with a size of 20x20 px 31 | Views.interval(img, Intervals.createMinSize( 50, 60, 20, 20 )).forEach(pixel -> pixel.set(25)); 32 | 33 | ij.ui().show(img); 34 | 35 | } 36 | 37 | public static void main(String...args) { 38 | run(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/filter/LowPassFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.images.filter; 9 | 10 | import java.io.File; 11 | 12 | import net.imagej.Dataset; 13 | import net.imagej.ImageJ; 14 | import net.imagej.ops.OpService; 15 | import net.imglib2.Cursor; 16 | import net.imglib2.RandomAccessibleInterval; 17 | import net.imglib2.img.Img; 18 | import net.imglib2.type.numeric.ComplexType; 19 | import net.imglib2.type.numeric.RealType; 20 | import net.imglib2.type.numeric.real.FloatType; 21 | import net.imglib2.util.Util; 22 | import net.imglib2.view.Views; 23 | 24 | import org.scijava.ItemIO; 25 | import org.scijava.command.Command; 26 | import org.scijava.plugin.Parameter; 27 | import org.scijava.plugin.Plugin; 28 | import org.scijava.widget.FileWidget; 29 | 30 | /** 31 | * A {@link Command} plugin performing a 32 | * low-pass filter 33 | * on an image. 34 | */ 35 | @Plugin(type = Command.class, headless = true, 36 | menuPath = "Tutorials > Low-pass Filter...") 37 | public class LowPassFilter> implements Command { 38 | 39 | @Parameter 40 | private OpService ops; 41 | 42 | @Parameter 43 | private Img image; 44 | 45 | @Parameter 46 | private double radius = 10; 47 | 48 | @Parameter(type = ItemIO.OUTPUT) 49 | private Img result; 50 | 51 | /** The run method executes the command. */ 52 | @Override 53 | public void run() { 54 | process(); 55 | } 56 | 57 | /** We use a helper method here to declare a type variable {@code C}. */ 58 | private > void process() { 59 | // Perform FFT of the input. 60 | // To make typing simpler here, we use a raw return type. 61 | RandomAccessibleInterval fft = ops.filter().fft(image); 62 | 63 | // Filter it. 64 | lowPass(fft, radius); 65 | 66 | // Reverse the FFT. 67 | result = ops.create().img(image, new FloatType()); 68 | ops.filter().ifft(result, fft); 69 | } 70 | 71 | /** 72 | * Performs an inplace low-pass filter on an image in Fourier space. 73 | *

74 | * It is a good practice to structure non-trivial routines as 75 | * {@code public static} so that it can be conveniently called from external 76 | * code. 77 | *

78 | * 79 | * @param fft The image in Fourier space to be filtered. 80 | * @param radius The radius of the filter. 81 | */ 82 | public static > void lowPass( 83 | final RandomAccessibleInterval fft, final double radius) 84 | { 85 | // Declare an array to hold the current position of the cursor. 86 | final long[] pos = new long[fft.numDimensions()]; 87 | 88 | // Define origin as 0,0. 89 | final long[] origin = {0, 0}; 90 | 91 | // Define a 2nd 'origin' at bottom left of image. 92 | // This is a bit of a hack. We want to draw a circle around the origin, 93 | // since the origin is at 0,0 - the circle will 'reflect' to the bottom. 94 | final long[] origin2 = {0, fft.dimension(1)}; 95 | 96 | // Loop through all pixels. 97 | final Cursor cursor = Views.iterable(fft).localizingCursor(); 98 | while (cursor.hasNext()) { 99 | cursor.fwd(); 100 | cursor.localize(pos); 101 | 102 | // Calculate distance from 0,0 and bottom left corner 103 | // (so we can form the reflected semi-circle). 104 | final double dist = Util.distance(origin, pos); 105 | final double dist2 = Util.distance(origin2, pos); 106 | 107 | // If distance is above radius (cutoff frequency), 108 | // set value of FFT to zero. 109 | if (dist > radius && dist2 > radius) 110 | cursor.get().setZero(); 111 | } 112 | } 113 | 114 | /** The main method enables standalone testing of the command. */ 115 | public static void main(final String... args) throws Exception { 116 | // create the ImageJ application context with all available services 117 | final ImageJ ij = new ImageJ(); 118 | 119 | // display the user interface 120 | ij.ui().showUI(); 121 | 122 | // open and display an image 123 | final File imageFile = ij.ui().chooseFile(null, FileWidget.OPEN_STYLE); 124 | final Dataset image = ij.scifio().datasetIO().open(imageFile.getAbsolutePath()); 125 | ij.ui().show(image); 126 | 127 | // execute the filter, waiting for the operation to finish. 128 | ij.command().run(LowPassFilter.class, true).get().getOutput("result"); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/processing/CountCells.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images.processing; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imglib2.algorithm.labeling.ConnectedComponents; 13 | import net.imglib2.img.Img; 14 | import net.imglib2.roi.labeling.ImgLabeling; 15 | import net.imglib2.roi.labeling.LabelRegions; 16 | import net.imglib2.type.numeric.IntegerType; 17 | 18 | import java.io.IOException; 19 | 20 | /** 21 | * How to count cells / blobs in an image (2D) 22 | * 23 | * @author Deborah Schmidt 24 | */ 25 | public class CountCells { 26 | 27 | private static void run() throws IOException { 28 | 29 | ImageJ ij = new ImageJ(); 30 | 31 | //load image 32 | Img img = (Img) ij.io().open(Object.class.getResource("/blobs.png").getPath()); 33 | 34 | //blur image 35 | Img blurredImg = (Img) ij.op().filter().gauss(img, 3); 36 | 37 | //threshold image 38 | Img segmentedImg = (Img) ij.op().threshold().otsu(blurredImg); 39 | 40 | //calculate connected components 41 | ImgLabeling cca = ij.op().labeling().cca(segmentedImg, ConnectedComponents.StructuringElement.FOUR_CONNECTED); 42 | 43 | //show result 44 | ij.ui().show(cca.getIndexImg()); 45 | 46 | //get count of connected components 47 | LabelRegions regions = new LabelRegions(cca); 48 | int cells = regions.getExistingLabels().size(); 49 | 50 | //print result 51 | System.out.println("Counted " + cells + " cells."); 52 | 53 | } 54 | 55 | public static void main(String...args) throws IOException { run(); } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/images/processing/ProcessChannelsIndividually.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.images.processing; 10 | 11 | import net.imagej.ImageJ; 12 | import net.imglib2.RandomAccess; 13 | import net.imglib2.RandomAccessibleInterval; 14 | import net.imglib2.algorithm.region.hypersphere.HyperSphere; 15 | import net.imglib2.img.array.ArrayImgFactory; 16 | import net.imglib2.type.numeric.real.FloatType; 17 | import net.imglib2.view.IntervalView; 18 | 19 | import java.io.IOException; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | /** 24 | * How to split the channels of an image and process them individually 25 | * 26 | * @author Deborah Schmidt 27 | */ 28 | public class ProcessChannelsIndividually { 29 | 30 | private static void run() { 31 | 32 | ImageJ ij = new ImageJ(); 33 | 34 | // create image with 3 channels 35 | RandomAccessibleInterval input = new ArrayImgFactory<>(new FloatType()).create(20, 30, 3); 36 | 37 | // defining which dimension of the image represents channels 38 | int channelDim = 2; 39 | 40 | // how many channels do we have? 41 | long numChannels = input.dimension(channelDim); 42 | 43 | List outputChannels = new ArrayList<>(); 44 | 45 | // iterate over all channels 46 | for (int channelIndex = 0; channelIndex < numChannels; channelIndex++) { 47 | 48 | // get channel 49 | IntervalView inputChannel = ij.op().transform().hyperSliceView(input, channelDim, channelIndex); 50 | 51 | // draw a circle at position [10, 15] with radius 5 52 | RandomAccess ra = inputChannel.randomAccess(); 53 | ra.setPosition(new long[]{10, 15}); 54 | new HyperSphere<>(inputChannel, ra, 5).forEach(value -> value.set(25)); 55 | 56 | // apply gauss 57 | RandomAccessibleInterval outputChannel = ij.op().filter().gauss(inputChannel, channelIndex); 58 | 59 | // add to output channel list 60 | outputChannels.add(outputChannel); 61 | } 62 | 63 | // stack channels back together 64 | RandomAccessibleInterval result = ij.op().transform().stackView(outputChannels); 65 | 66 | // display result 67 | ij.ui().show(result); 68 | 69 | } 70 | 71 | public static void main(String...args) throws IOException { run(); } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/metadata/GetMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.metadata; 9 | 10 | import io.scif.FieldPrinter; 11 | import io.scif.Format; 12 | import io.scif.Metadata; 13 | import io.scif.services.FormatService; 14 | 15 | import net.imagej.Dataset; 16 | import net.imagej.ImageJ; 17 | 18 | import org.scijava.ItemIO; 19 | import org.scijava.io.location.Location; 20 | import org.scijava.io.location.LocationService; 21 | import org.scijava.log.LogService; 22 | import org.scijava.plugin.Parameter; 23 | 24 | /** 25 | * This example illustrates how to access and display image metadata using the {@link FormatService} and 26 | * {@link FieldPrinter}. 27 | *

28 | * We use the {@link FormatService} to determine the {@link Format} of the input image. Then, we parse 29 | * the metadata from the image file and use {@link FieldPrinter} to retrieve the metadata fields as strings. 30 | *

31 | *

32 | * An optional {@code formatMetadata} method is included to (hopefully) make the text more readable. 33 | *

34 | */ 35 | public class GetMetadata { 36 | 37 | // -- Needed services -- 38 | 39 | // for determining the Format of the input image 40 | @Parameter 41 | private FormatService formatService; 42 | 43 | @Parameter 44 | private LocationService locationService; 45 | 46 | // for logging errors 47 | @Parameter 48 | private LogService log; 49 | 50 | // -- Inputs and outputs to the command -- 51 | 52 | // output metadata string 53 | @Parameter(label = "Metadata", type = ItemIO.OUTPUT) 54 | private String mString; 55 | 56 | public static void run() throws Exception { 57 | ImageJ ij = new ImageJ(); 58 | 59 | // open a sample image 60 | final Dataset img = ij.scifio().datasetIO().open("http://imagej.net/images/FluorescentCells.jpg"); 61 | 62 | // we need the file path to determine the file format 63 | Location source = ij.get(LocationService.class).resolve(img.getSource()); 64 | 65 | // catch any Format or IO exceptions 66 | // determine the Format based on the extension and, if necessary, the source data 67 | Format format = ij.scifio().format().getFormat(source); 68 | 69 | // create an instance of the associated Parser and parse metadata from the image file 70 | Metadata metadata = format.createParser().parse(source); 71 | 72 | // use FieldPrinter to traverse metadata tree and return as a String 73 | String metadataTree = new FieldPrinter(metadata).toString(); 74 | 75 | // (optional) remove some of the tree formatting to make the metadata easier to read 76 | String mString = formatMetadata(metadataTree); 77 | 78 | // print out our precious metadata! 79 | ij.log().info(mString); 80 | 81 | // close out our ImageJ 82 | ij.dispose(); 83 | } 84 | 85 | /** 86 | * This function makes the metadata easier to read by removing some of the tree formatting from FieldPrinter. 87 | * @param metadataTree raw metadata string returned by FieldPrinter().toString() 88 | * @return formatted version of metadataTree 89 | */ 90 | private static String formatMetadata(String metadataTree) { 91 | 92 | // remove ending braces | replace ", " between OME fields 93 | String tmp = metadataTree.replaceAll("(\\t+}\\n)|(,\\s)", "\n"); 94 | 95 | // remove beginning braces | remove indenting 96 | return tmp.replaceAll("(\\t+\\{\\n)|(\\t+)", ""); 97 | } 98 | 99 | public static void main(String...args) throws Exception { run(); } 100 | } 101 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/modules/WorkingWithModules.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.modules; 10 | 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | import net.imagej.ImageJ; 17 | import net.imagej.app.AboutImageJ; 18 | 19 | import org.scijava.module.ModuleInfo; 20 | import org.scijava.module.ModuleItem; 21 | import org.scijava.module.process.InitPreprocessor; 22 | import org.scijava.module.process.ModulePreprocessor; 23 | import org.scijava.module.process.ValidityPreprocessor; 24 | 25 | /** How to work with ImageJ modules. */ 26 | public class WorkingWithModules { 27 | 28 | public static void main(final String... args) { 29 | final ImageJ ij = new ImageJ(); 30 | 31 | // First of all, what is the difference between a "module" and a "command"? 32 | // - A "module" is Java code which implements the interfaces in the 33 | // org.scijava.module package (Module, ModuleInfo, ModuleItem). 34 | // - A "command" is a particular type of ImageJ plugin (implementing 35 | // org.scijava.command.Command) which is executable (i.e., also 36 | // implements the Runnable interface). 37 | // 38 | // Not all modules are commands. The plugin service will automatically 39 | // discover all available commands, whereas non-command modules are not 40 | // necessarily discoverable automatically (though some might be; and it is 41 | // possible to register modules with the module service manually as well). 42 | // 43 | // Any command can be expressed as a module (via the 44 | // org.scijava.command.CommandModule adapter class). However, not all 45 | // modules are commands. There are two services for working with modules 46 | // and commands respectively. As a rule of thumb, the module service is 47 | // more "low-level" while the command service is more "high-level". 48 | // 49 | // If you want to expose ImageJ functionality from your software, your best 50 | // bet is to work with modules rather than commands, since as stated above, 51 | // not all modules are commands. 52 | 53 | // You can ask ImageJ's module service for a list of available modules. 54 | 55 | final List modules = ij.module().getModules(); 56 | for (final ModuleInfo info : modules) { 57 | if (!info.canRunHeadless()) { 58 | // You may wish to skip modules which do not purport to run headless. 59 | continue; 60 | } 61 | 62 | // We dump some information about the module in question: 63 | final String title = info.getTitle(); 64 | final String className = info.getDelegateClassName(); 65 | ij.log().info("Module '" + title + "' [" + className + "]:"); 66 | 67 | // A module consists of typed inputs and outputs. 68 | // Now we dump some details of each such input to the ImageJ log. 69 | for (final ModuleItem input : info.inputs()) { 70 | final String inputName = input.getName(); 71 | final Class inputType = input.getType(); 72 | ij.log().info("\t" + inputName + ": " + inputType.getName()); 73 | } 74 | } 75 | 76 | // We choose a module of interest, for some additional fun! 77 | final ModuleInfo myInfo = ij.command().getCommand(AboutImageJ.class); 78 | 79 | // To execute a module, use the ModuleService#run methods. 80 | // To execute a command by name, use the CommandService#run methods. 81 | // 82 | // In either case, take particular note of the "boolean process" flag. 83 | // When set, the module will be preprocessed with all available 84 | // preprocessing plugins before being executed, and then after execution 85 | // will be postprocessed with all available postprocessing plugins. 86 | // 87 | // In particular, the preprocessors will "fill in" many parameter values 88 | // for you, such as single dataset parameters. 89 | // 90 | // See the "custom-preprocessor-plugin" tutorial for details on how to 91 | // customize such preprocessing. 92 | 93 | // To run a module with pre- and postprocessing: 94 | ij.log().info("Running " + myInfo.getTitle()); 95 | ij.module().run(myInfo, true); 96 | 97 | // It may sometimes be the case that even with preprocessing, your module 98 | // still requires additional input values. In such situations, you can pass 99 | // the map of such input values explicitly as follows: 100 | final Map myInputs = new HashMap<>(); 101 | /* 102 | myInputs.put("requiredStringInput", "requiredStringValue"); 103 | myInputs.put("requiredDoubleInput", 5.6); 104 | // etc. 105 | ij.module().run(myInfo, true, myInputs); 106 | 107 | // Or if you prefer, there is a succinct varargs method signature: 108 | ij.module().run(myInfo, true, 109 | "requiredStringInput", "requiredStringValue", 110 | "requiredDoubleInput", 5.6); 111 | */ 112 | 113 | // If you desire more control over pre- and postprocessing, you can instead 114 | // invoke the module with the process flag set to false. 115 | // In this case, *no* pre- or postprocessing happens automatically. 116 | 117 | // The invocation is as follows: 118 | ij.module().run(myInfo, false); 119 | 120 | // Alternately, if you want to exercise complete manual control over the 121 | // pre- and postprocessing, you can also pass an explicit list of module 122 | // pre- and postprocessors. 123 | 124 | final List pre = new ArrayList<>(); 125 | 126 | // The validity preprocessor ensures the module does not break the rules. 127 | final ValidityPreprocessor validPre = new ValidityPreprocessor(); 128 | validPre.setContext(ij.getContext()); 129 | pre.add(validPre); 130 | 131 | // The init preprocessor calls the module's initializer callbacks. 132 | final InitPreprocessor initPre = new InitPreprocessor(); 133 | initPre.setContext(ij.getContext()); 134 | pre.add(initPre); 135 | 136 | // Finally, we invoke the module service with our preprocessors: 137 | ij.module().run(myInfo, pre, null, myInputs); 138 | 139 | // Launch ImageJ as usual with AboutImageJ images. 140 | ij.launch(args); 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ops/ConvolutionOps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ops; 9 | 10 | import net.imagej.ImageJ; 11 | import net.imglib2.Point; 12 | import net.imglib2.RandomAccess; 13 | import net.imglib2.RandomAccessibleInterval; 14 | import net.imglib2.algorithm.region.hypersphere.HyperSphere; 15 | import net.imglib2.img.Img; 16 | import net.imglib2.img.array.ArrayImgFactory; 17 | import net.imglib2.outofbounds.OutOfBoundsConstantValueFactory; 18 | import net.imglib2.outofbounds.OutOfBoundsFactory; 19 | import net.imglib2.type.numeric.real.FloatType; 20 | import net.imglib2.util.Util; 21 | import net.imglib2.view.Views; 22 | 23 | /** How to do convolution with ImageJ Ops. */ 24 | public class ConvolutionOps { 25 | 26 | public static void main(final String... args) throws Exception { 27 | final ImageJ ij = new ImageJ(); 28 | 29 | final int[] size = new int[] { 200, 200 }; 30 | 31 | // create an input with a small sphere at the center 32 | final Img in = new ArrayImgFactory(new FloatType()).create(size); 33 | placeSphereInCenter(in); 34 | 35 | // show the image in a window 36 | ij.ui().show("input", in); 37 | 38 | final int[] kernelSize = new int[] { 3, 3 }; 39 | final Img kernel = new ArrayImgFactory(new FloatType()).create( 40 | kernelSize); 41 | final RandomAccess kernelRa = kernel.randomAccess(); 42 | // long[] borderSize = new long[] {1, 1}; 43 | 44 | // Second derivative filter 45 | final int[] k = new int[] { 1, -2, 1, 2, -4, 2, 1, -2, 1 }; 46 | 47 | int h = 0; 48 | for (int i = 0; i < 3; i++) { 49 | for (int j = 0; j < 3; j++) { 50 | kernelRa.setPosition(new Point(i, j)); 51 | kernelRa.get().set(k[h]); 52 | h++; 53 | } 54 | } 55 | 56 | // show the image in a window 57 | ij.ui().show("kernel", kernel); 58 | 59 | final Img out = new ArrayImgFactory(new FloatType()).create(in); 60 | 61 | final OutOfBoundsFactory> obf = 62 | new OutOfBoundsConstantValueFactory<>(// 63 | Util.getTypeFromInterval(in).createVariable()); 64 | 65 | // extend the input 66 | final RandomAccessibleInterval extendedIn = // 67 | Views.interval(Views.extend(in, obf), in); 68 | 69 | // extend the output 70 | final RandomAccessibleInterval extendedOut = // 71 | Views.interval(Views.extend(out, obf), out); 72 | 73 | // convolve 74 | ij.op().filter().convolve(extendedOut, extendedIn, kernel); 75 | 76 | // show the image in a window 77 | ij.ui().show("convolved", out); 78 | } 79 | 80 | /** Places a small sphere at the center of the image. */ 81 | private static void placeSphereInCenter(final Img img) { 82 | final Point center = new Point(img.numDimensions()); 83 | 84 | for (int d = 0; d < img.numDimensions(); d++) 85 | center.setPosition(img.dimension(d) / 2, d); 86 | 87 | final HyperSphere hyperSphere = // 88 | new HyperSphere<>(img, center, 10); 89 | 90 | for (final FloatType value : hyperSphere) { 91 | value.setReal(1); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ops/CreateANewOp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ops; 9 | 10 | import net.imagej.ImageJ; 11 | import net.imagej.ops.AbstractOp; 12 | import net.imagej.ops.Op; 13 | 14 | import org.scijava.ItemIO; 15 | import org.scijava.plugin.Parameter; 16 | import org.scijava.plugin.Plugin; 17 | 18 | /** How to use create a new ImageJ OP. */ 19 | public class CreateANewOp { 20 | 21 | public static void main(final String... args) throws Exception { 22 | final ImageJ ij = new ImageJ(); 23 | 24 | // Run our op! 25 | final Object narf = ij.op().run("narf", "Put some trousers on"); 26 | 27 | // And what value did our op return? 28 | ij.log().info("The op said: " + narf); 29 | } 30 | 31 | @Plugin(type = Op.class, name = "narf") 32 | public static class Narf extends AbstractOp { 33 | 34 | @Parameter 35 | private String input; 36 | 37 | @Parameter(type = ItemIO.OUTPUT) 38 | private String output; 39 | 40 | @Override 41 | public void run() { 42 | output = "Egads! " + input.toUpperCase(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ops/RampOp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ops; 9 | 10 | import net.imagej.ImageJ; 11 | import net.imagej.ops.AbstractOp; 12 | import net.imagej.ops.Op; 13 | import net.imglib2.Cursor; 14 | import net.imglib2.img.array.ArrayImg; 15 | import net.imglib2.img.array.ArrayImgs; 16 | import net.imglib2.img.basictypeaccess.array.DoubleArray; 17 | import net.imglib2.type.numeric.RealType; 18 | import net.imglib2.type.numeric.real.DoubleType; 19 | 20 | import org.scijava.ItemIO; 21 | import org.scijava.plugin.Parameter; 22 | import org.scijava.plugin.Plugin; 23 | 24 | @Plugin(type = Op.class, name = "ramp") 25 | public class RampOp> extends AbstractOp { 26 | 27 | @Parameter(type = ItemIO.OUTPUT) 28 | private ArrayImg rampImg; 29 | 30 | @Override 31 | public void run() { 32 | rampImg = ArrayImgs.doubles(256, 256); 33 | 34 | final Cursor c = rampImg.localizingCursor(); 35 | final long[] pos = new long[rampImg.numDimensions()]; 36 | 37 | // Iterate the image and get the each pixel location 38 | // Every pixel value is assigned its locations sum, 39 | // so generate the ramp pattern image. 40 | while (c.hasNext()) { 41 | c.fwd(); 42 | c.localize(pos); 43 | c.get().setReal(sum(pos)); 44 | } 45 | } 46 | 47 | private float sum(long[] pos) { 48 | float sum = 0; 49 | for (long p : pos) sum += p; 50 | return sum; 51 | } 52 | 53 | public static void main(final String... args) throws Exception { 54 | final ImageJ ij = new ImageJ(); 55 | 56 | // Run our op 57 | final Object ramp = ij.op().run("ramp"); 58 | 59 | // And display the result! 60 | ij.ui().showUI(); 61 | ij.ui().show(ramp); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ops/RandomBlobsOp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ops; 9 | 10 | import java.util.Random; 11 | 12 | import net.imagej.ImageJ; 13 | import net.imagej.ops.AbstractOp; 14 | import net.imagej.ops.Op; 15 | import net.imglib2.RandomAccess; 16 | import net.imglib2.RandomAccessibleInterval; 17 | import net.imglib2.img.array.ArrayImgs; 18 | import net.imglib2.type.numeric.RealType; 19 | import net.imglib2.util.IntervalIndexer; 20 | import net.imglib2.util.Intervals; 21 | 22 | import org.scijava.ItemIO; 23 | import org.scijava.log.LogService; 24 | import org.scijava.plugin.Parameter; 25 | import org.scijava.plugin.Plugin; 26 | 27 | /** 28 | * Creates a series of blobs across a new image based on given inputs. 29 | * 30 | * @author Aparna Pal 31 | */ 32 | @Plugin(type = Op.class, name = "blobs") 33 | public class RandomBlobsOp> extends AbstractOp { 34 | 35 | @Parameter(type = ItemIO.OUTPUT) 36 | private RandomAccessibleInterval image; 37 | 38 | @Parameter 39 | private LogService log; 40 | 41 | @Parameter 42 | private int blobNum; 43 | 44 | @Parameter 45 | private int blobSize; 46 | 47 | @Parameter 48 | private int xDim; 49 | 50 | @Parameter 51 | private int yDim; 52 | 53 | @Parameter(required = false) 54 | private long seed = 0xcafebabe; 55 | 56 | @Override 57 | public void run() { 58 | // produce a XxY float64 array-backed image using the input parameters 59 | @SuppressWarnings({ "rawtypes", "unchecked" }) 60 | final RandomAccessibleInterval newImage = 61 | (RandomAccessibleInterval) ArrayImgs.doubles(xDim, yDim); 62 | image = newImage; 63 | final long[] pos = new long[image.numDimensions()]; 64 | 65 | final long[] blobCenter = new long[image.numDimensions()]; 66 | final long[] dims = new long[image.numDimensions()]; 67 | image.dimensions(dims); 68 | 69 | final long total = Intervals.numElements(image); 70 | 71 | final Random r = new Random(seed); 72 | 73 | // Iterate to generate each blob 74 | final RandomAccess ra = image.randomAccess(image); 75 | for (int i = 0; i < blobNum; i++) { 76 | // generate a random positon in [0, total) 77 | final long index = (long) (r.nextDouble() * total); 78 | // convert the linear index to the 2-D index 79 | // For example, index = 59662, dims = [256,256], 80 | // then blobCenter = [14,233] 81 | IntervalIndexer.indexToPosition(index, dims, blobCenter); 82 | 83 | // For generating current blob, it is necessary to scan 84 | // the whole image to determine the elements which are 85 | // locate in the radius of the blobCenter. 86 | for (int j = 0; j < total; j++) { 87 | IntervalIndexer.indexToPosition(j, dims, pos); 88 | final double dist = distance(pos, blobCenter); 89 | if (dist > blobSize) continue; 90 | 91 | // This element is in the radius of the blobCenter, so it is 92 | // assigned with value inversely proportional to the distance. 93 | // Namely, if the distance is 0.0, then the norm is 1.0; if the 94 | // distance is blobSize, then the norm is 0.0, and so on. 95 | ra.setPosition(pos); 96 | final double norm = 1.0 - dist / blobSize; 97 | ra.get().setReal(Math.max(ra.get().getRealDouble(), norm)); 98 | } 99 | } 100 | } 101 | 102 | public static void main(final String... args) throws Exception { 103 | final ImageJ ij = new ImageJ(); 104 | 105 | // Run our op 106 | final Object blobs = ij.op().run("blobs", 20, 16, 256, 256); 107 | 108 | // And display the result! 109 | ij.ui().showUI(); 110 | ij.ui().show(blobs); 111 | } 112 | 113 | // -- Helper methods -- 114 | 115 | /** Computes distance between the given position and a center point. */ 116 | private double distance(final long[] pos, final long[] center) { 117 | long sumDistSquared = 0; 118 | for (int d = 0; d < center.length; d++) { 119 | final long dist = pos[d] - center[d]; 120 | sumDistSquared += dist * dist; 121 | } 122 | return Math.sqrt(sumDistSquared); 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ops/UsingOps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ops; 9 | 10 | import net.imagej.ImageJ; 11 | import net.imagej.ops.Op; 12 | import net.imagej.ops.special.computer.UnaryComputerOp; 13 | import net.imglib2.IterableInterval; 14 | import net.imglib2.type.numeric.real.DoubleType; 15 | 16 | /** 17 | * How to use ImageJ Operations. 18 | */ 19 | public class UsingOps { 20 | 21 | public static void main(final String... args) throws Exception { 22 | final ImageJ ij = new ImageJ(); 23 | 24 | ij.log().info("-------- How many ops? --------"); 25 | final int opCount = ij.command().getCommandsOfType(Op.class).size(); 26 | ij.log().info("Found " + opCount + " ops"); 27 | 28 | ij.log().info("-------- Learn about an op --------"); 29 | ij.log().info(ij.op().help("math.mul")); 30 | 31 | ij.log().info("-------- Add two numbers --------"); 32 | final int seven = ij.op().math().add(2, 5); 33 | ij.log().info("What is 2 + 5? " + seven); 34 | 35 | ij.log().info("-------- Create a new blank image --------"); 36 | final long[] dims = {150, 100}; 37 | final IterableInterval blank = ij.op().create().img(dims); 38 | 39 | ij.log().info("-------- Fill in an image with a formula --------"); 40 | final String formula = "10 * (Math.cos(0.3*p[0]) + Math.sin(0.3*p[1]))"; 41 | final IterableInterval sinusoid = ij.op().image().equation(blank, formula); 42 | 43 | ij.log().info("-------- Add a constant value to an image --------"); 44 | final DoubleType d = new DoubleType(13.0); 45 | ij.op().math().add(sinusoid, d); 46 | 47 | ij.log().info("-------- Generate gradient image using a formula --------"); 48 | final IterableInterval gBlank = ij.op().create().img(dims); 49 | final IterableInterval gradient = ij.op().image().equation(gBlank, "p[0]+p[1]"); 50 | 51 | ij.log().info("-------- Add two images --------"); 52 | final IterableInterval composite = ij.op().math().add(sinusoid, gradient); 53 | 54 | ij.log().info("-------- Dump an image to the console --------"); 55 | final String ascii = ij.op().image().ascii(composite); 56 | ij.log().info("Composite image:\n" + ascii); 57 | 58 | ij.log().info("-------- Show the image in a window --------"); 59 | ij.ui().show("composite", composite); 60 | 61 | ij.log().info("-------- Execute op on every pixel of an image --------"); 62 | final Op addOp = ij.op().op("math.add", DoubleType.class, new DoubleType(5.0)); 63 | final IterableInterval mblank = ij.op().create().img(composite); 64 | ij.op().map(mblank, composite, (UnaryComputerOp) addOp); 65 | 66 | ij.log().info("-------- All done! --------"); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ops/UsingOpsDog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ops; 9 | 10 | import java.io.File; 11 | 12 | import net.imagej.display.ImageDisplayService; 13 | import net.imagej.Dataset; 14 | import net.imagej.ImageJ; 15 | import net.imagej.display.ImageDisplay; 16 | import net.imagej.ops.OpService; 17 | import net.imagej.ops.convert.RealTypeConverter; 18 | import net.imglib2.img.Img; 19 | import net.imglib2.type.numeric.real.FloatType; 20 | import org.scijava.ItemIO; 21 | import org.scijava.command.Command; 22 | import org.scijava.plugin.Parameter; 23 | import org.scijava.plugin.Plugin; 24 | import net.imglib2.type.NativeType; 25 | import net.imglib2.type.numeric.RealType; 26 | 27 | /** 28 | * This tutorial shows how to use the ImageJ Ops DoG filter, and how to use 29 | * ImageJ Ops normalizeScale op to do image type conversion. 30 | *

31 | * A main method is provided so this class can be run directly from Eclipse (or 32 | * any other IDE). 33 | *

34 | *

35 | * Also, because this class implements {@link Command} and is annotated as an 36 | * {@code @Plugin}, it will show up in the ImageJ menus: under Tutorials>DoG 37 | * Filtering, as specified by the {@code menuPath} field of the {@code @Plugin} 38 | * annotation. 39 | *

40 | */ 41 | @Plugin(type = Command.class, menuPath = "Tutorials>DoG Filtering") 42 | public class UsingOpsDog & NativeType> implements Command { 43 | 44 | /* 45 | * This {@code @Parameter} is for Image Display service. 46 | * The context will provide it automatically when this command is created. 47 | */ 48 | @Parameter 49 | private ImageDisplayService imageDisplayService; 50 | 51 | /* 52 | * This {@code @Parameter} is for ImageJ Ops service. The 53 | * context will provide it automatically when this command is created. 54 | */ 55 | @Parameter 56 | private OpService opService; 57 | 58 | @Parameter(type = ItemIO.INPUT) 59 | private ImageDisplay displayIn; 60 | 61 | /* 62 | * This command will produce an image that will automatically be shown by 63 | * the framework. Again, this command is "UI agnostic": how the image is 64 | * shown is not specified here. 65 | */ 66 | //@Parameter(type = ItemIO.INPUT) 67 | //private Dataset imageDataset; 68 | @Parameter(type = ItemIO.OUTPUT) 69 | private Img output; 70 | 71 | /* 72 | * The run() method is where we do the actual 'work' of the command. In this 73 | * case, it is fairly trivial because we are simply calling ImageJ Services. 74 | */ 75 | @Override 76 | public void run() { 77 | final Dataset input = imageDisplayService.getActiveDataset(displayIn); 78 | Img image = (Img) input.getImgPlus(); 79 | 80 | // Convert image to FloatType for better numeric precision 81 | Img converted = opService.convert().float32(image); 82 | 83 | // Create the filtering result 84 | Img dog = opService.create().img(converted); 85 | 86 | // Do the DoG filtering using ImageJ Ops 87 | opService.filter().dog(dog, converted, 1.0, 1.25); 88 | 89 | // Create a NormalizeScaleRealTypes op 90 | RealTypeConverter scale_op; 91 | scale_op = (RealTypeConverter) opService.op("convert.normalizeScale", dog.firstElement(), image.firstElement()); 92 | 93 | // Create the output image 94 | output = opService.create().img(image); 95 | 96 | // Run the op to do type conversion for better displaying 97 | opService.convert().imageType(output, dog, scale_op); 98 | 99 | // You can also use the OpService to run the op 100 | // opService.run(Ops.Convert.ImageType.class, output, dog, scale_op); 101 | } 102 | 103 | /* 104 | * This main method is for convenience - so you can run this command 105 | * directly from Eclipse (or other IDE). 106 | *

107 | * It will launch ImageJ and then run this command using the CommandService. 108 | * This is equivalent to clicking "Tutorials>DoG Filtering" in the UI. 109 | *

110 | */ 111 | public static void main(final String... args) throws Exception { 112 | // Launch ImageJ as usual. 113 | final ImageJ ij = new ImageJ(); 114 | ij.launch(args); 115 | 116 | // ask the user for a file to open 117 | final File file = ij.ui().chooseFile(null, "open"); 118 | 119 | if (file != null) { 120 | // load the dataset 121 | final Dataset dataset = ij.scifio().datasetIO().open(file.getPath()); 122 | 123 | // show the image 124 | ij.ui().show(dataset); 125 | 126 | // Launch the "UsingOpsDog" command. 127 | ij.command().run(UsingOpsDog.class, true); 128 | } 129 | 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/plugins/create/Animal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.plugins.create; 9 | 10 | import net.imagej.ImageJPlugin; 11 | 12 | import org.scijava.plugin.Plugin; 13 | 14 | /** 15 | * A new type of ImageJ plugin that allows discovery of animal species. 16 | *

17 | * Animals discoverable at runtime must implement this 18 | * interface and be annotated with @{@link Plugin} with attribute 19 | * {@link Plugin#type()} = {@link Animal}.class. 20 | *

21 | * 22 | * @author Curtis Rueden 23 | * @see AnimalService 24 | */ 25 | public interface Animal extends ImageJPlugin { 26 | 27 | /** Gets whether the animal is a feline subspecies. */ 28 | boolean isCat(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/plugins/create/AnimalService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.plugins.create; 9 | 10 | import java.util.HashMap; 11 | import java.util.Set; 12 | 13 | import net.imagej.ImageJService; 14 | 15 | import org.scijava.plugin.AbstractPTService; 16 | import org.scijava.plugin.Plugin; 17 | import org.scijava.plugin.PluginInfo; 18 | import org.scijava.service.Service; 19 | 20 | /** Service which manages available {@link Animal}s. */ 21 | @Plugin(type = Service.class) 22 | public class AnimalService extends AbstractPTService implements 23 | ImageJService 24 | { 25 | 26 | // When creating a new type of plugin (such as Animal), it is very nice to 27 | // have a corresponding service that provides operations relevant to your 28 | // new plugin type. 29 | 30 | // This service is a PTService (extending AbstractPTService), so that 31 | // discovery of all available plugins is automatically handled for you. 32 | 33 | // You can easily get the list of available plugins by calling getPlugins(), 34 | // or use the plugin service (available via getPluginService()) to 35 | // instantiate any given plugin. 36 | 37 | /** Map of each animal name to its corresponding plugin metadata. */ 38 | private HashMap> animals = new HashMap<>(); 39 | 40 | /** 41 | * Gets the list of available animals. The names on this list can be passed to 42 | * {@link #createAnimal(String)} to create instances of that animal. 43 | */ 44 | public Set getAnimalNames() { 45 | return animals.keySet(); 46 | } 47 | 48 | /** Creates an animal of the given name. */ 49 | public Animal createAnimal(final String name) { 50 | // First, we get the animal plugin with the given name. 51 | final PluginInfo info = animals.get(name); 52 | 53 | if (info == null) { 54 | throw new IllegalArgumentException("No animal of that name"); 55 | } 56 | 57 | // Next, we use the plugin service to create an animal of that kind. 58 | final Animal animal = getPluginService().createInstance(info); 59 | 60 | return animal; 61 | } 62 | 63 | @Override 64 | public void initialize() { 65 | // This Service method is called when the animal service is first created. 66 | // It loops over the list of available animals, adding them to its own 67 | // animal map, which is indexed by animal name. 68 | 69 | // We loop over all available animal plugins. 70 | for (final PluginInfo info : getPlugins()) { 71 | String name = info.getName(); 72 | if (name == null || name.isEmpty()) { 73 | // The animal's @Plugin annotation does not specify a name, 74 | // so we use the fully qualified class name as a fallback. 75 | name = info.getClassName(); 76 | } 77 | // Add the plugin to the list of known animals. 78 | animals.put(name, info); 79 | } 80 | } 81 | 82 | @Override 83 | public Class getPluginType() { 84 | return Animal.class; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/plugins/create/Bear.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.plugins.create; 9 | 10 | import org.scijava.plugin.Plugin; 11 | 12 | /** An animal with tremendous strength and adorable cubs. */ 13 | @Plugin(type = Animal.class, name = "Bear") 14 | public class Bear implements Animal { 15 | 16 | @Override 17 | public boolean isCat() { 18 | return false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/plugins/create/CreateANewPluginType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.plugins.create; 9 | 10 | import java.util.Set; 11 | 12 | import net.imagej.Dataset; 13 | import net.imagej.DatasetService; 14 | import net.imagej.ImageJ; 15 | import net.imagej.display.ImageDisplay; 16 | import net.imagej.display.ImageDisplayService; 17 | import net.imagej.display.OverlayService; 18 | import net.imagej.overlay.Overlay; 19 | 20 | import org.scijava.Context; 21 | import org.scijava.Contextual; 22 | import org.scijava.Prioritized; 23 | import org.scijava.plugin.AbstractRichPlugin; 24 | import org.scijava.plugin.Plugin; 25 | import org.scijava.plugin.PluginService; 26 | 27 | /** 28 | * Demonstrates how to create your own new type of plugin. 29 | *

30 | * We define our new plugin type in the {@link Animal} interface, with the 31 | * {@link Lion}, {@link Tiger} and {@link Bear} classes providing three example 32 | * animals. 33 | *

34 | *

35 | * Animal-related features are provided in an API: the {@link AnimalService}. 36 | * While not required, it is recommended to provide such a companion service to 37 | * your new plugin type, to make things easier for downstream code interested in 38 | * plugins of your new type. 39 | *

40 | *

41 | * There are many other cases of new plugin types throughout ImageJ; e.g.: 42 | *

43 | *
    44 | *
  • The {@link net.imagej} package provides a 45 | * {@link DatasetService} for working with {@link Dataset}s.
  • 46 | *
  • The {@link net.imagej.overlay} package provides a 47 | * {@link OverlayService} for working with {@link Overlay}s.
  • 48 | *
  • The {@link net.imagej.display} package provides an 49 | * {@link ImageDisplayService} for working with {@link ImageDisplay}s.
  • 50 | *
51 | *

52 | * The biggest advantage of structuring things in this way is 53 | * extensibility: in ImageJ1, both Image Calculator and Auto-Threshold 54 | * commands are hardcoded into those plugins, whereas in ImageJ2, the operations 55 | * available to those commands is obtained dynamically from the appropriate 56 | * service, making it possible for anyone to add a new operation to the list 57 | * merely by implementing a new plugin of that type, rather than changing the 58 | * core code of ImageJ itself. 59 | *

60 | *

61 | * Two final side notes: 62 | *

63 | *
    64 | *
  1. Unlike the core ImageJ services, the {@link AnimalService} is not split 65 | * between interface ({@code AnimalService}) and implementation ( 66 | * {@code DefaultAnimalService}). The core ImageJ services all provide such a 67 | * split so that it is possible for downstream code to easily override the 68 | * behavior of services, by providing an alternative service implementation with 69 | * a higher priority. While we believe that such an interface/implementation 70 | * split is better for extensibility, we did not want to complicate this example 71 | * by splitting the {@code AnimalService} in such a way.
  2. 72 | *
  3. Most ImageJ plugin types extend the core {@link Contextual} and 73 | * {@link Prioritized} interfaces (in practice, this is easily accomplished by 74 | * providing e.g. an {@code AbstractAnimal} class that extends 75 | * {@link AbstractRichPlugin}). The advantage of extending the 76 | * {@link Prioritized} interface is that the {@link PluginService} will return 77 | * your available plugins in prioritized order; i.e., sorted by the 78 | * {@link Plugin#priority()} attribute. For some kinds of plugins, 79 | * prioritization can be very helpful. The advantage of extending the 80 | * {@link Contextual} interface is that plugin instances will then have a handle 81 | * on their {@link Context}, and hence have access to services. In particular, 82 | * it can be nice e.g. for an {@link Animal} to be able to make calls to the 83 | * {@link AnimalService} in various situations. 84 | *
85 | */ 86 | public class CreateANewPluginType { 87 | 88 | public static void main(String... args) { 89 | // Create a new ImageJ application context, from which 90 | // we will access all the functionality we need. 91 | final ImageJ ij = new ImageJ(); 92 | 93 | // Grab our animal service from the ImageJ context. 94 | final AnimalService animals = ij.get(AnimalService.class); 95 | 96 | // Ask the animal service for the names of all available animals. 97 | final Set names = animals.getAnimalNames(); 98 | ij.log().info("Total number of animals: " + names.size()); 99 | 100 | // Print out a little more information about each animal. 101 | for (final String name : animals.getAnimalNames()) { 102 | // Create a new instance of this animal. 103 | final Animal animal = animals.createAnimal(name); 104 | 105 | // Report on the most vital detail: is this animal a type of cat? 106 | final String catStatus = animal.isCat() ? " is " : " is not "; 107 | ij.log().info("- " + name + catStatus + "a cat"); 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/plugins/create/Lion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.plugins.create; 9 | 10 | import org.scijava.plugin.Plugin; 11 | 12 | /** An animal that rules the jungle. */ 13 | @Plugin(type = Animal.class, name = "Lion") 14 | public class Lion implements Animal { 15 | 16 | @Override 17 | public boolean isCat() { 18 | return true; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/plugins/create/Tiger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.plugins.create; 9 | 10 | import org.scijava.plugin.Plugin; 11 | 12 | /** A fierce animal that likes to pounce with powerful linear motion. */ 13 | @Plugin(type = Animal.class, name = "Tiger") 14 | public class Tiger implements Animal { 15 | 16 | @Override 17 | public boolean isCat() { 18 | return true; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/services/CallService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.services; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.Context; 13 | import org.scijava.io.IOService; 14 | 15 | /** 16 | * How to call a service 17 | * 18 | * @author Deborah Schmidt 19 | */ 20 | public class CallService { 21 | 22 | /** 23 | * .. get an instance of the {@link IOService} 24 | */ 25 | public static void call() { 26 | 27 | // get an IOService instance 28 | ImageJ ij = new ImageJ(); 29 | IOService io = ij.io(); 30 | 31 | // print the name of the class implementing the IOService 32 | System.out.println(io.getClass().getName()); 33 | 34 | } 35 | 36 | /** 37 | * .. get an instance of the {@link IOService} without using the {@link ImageJ} gateway 38 | * (e.g. for repositories with a SciJava but no ImageJ dependency) 39 | */ 40 | public static void callWithoutImageJ() { 41 | 42 | // get an IOService instance 43 | Context context = new Context(IOService.class); 44 | IOService io = context.getService(IOService.class); 45 | 46 | // print the name of the class implementing the IOService 47 | System.out.println(io.getClass().getName()); 48 | 49 | } 50 | 51 | public static void main(String...args) { 52 | call(); 53 | callWithoutImageJ(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/services/ListAllServices.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.services; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.plugin.PluginInfo; 13 | import org.scijava.service.Service; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * How to list all available services 19 | * 20 | * @author Deborah Schmidt 21 | */ 22 | public class ListAllServices { 23 | 24 | private static void run() { 25 | ImageJ ij = new ImageJ(); 26 | List> services = ij.plugin().getPluginsOfType(Service.class); 27 | for(PluginInfo service : services) { 28 | System.out.println(service.getPluginClass()); 29 | } 30 | } 31 | 32 | public static void main(String...args) { 33 | run(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/tables/CreateTable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.tables; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.table.DefaultGenericTable; 13 | import org.scijava.table.GenericTable; 14 | 15 | /** 16 | * How to create a table 17 | * 18 | * @author Deborah Schmidt 19 | */ 20 | public class CreateTable { 21 | 22 | private static void run() { 23 | 24 | //create table 25 | GenericTable table = new DefaultGenericTable(); 26 | table.appendColumn("X"); 27 | table.appendColumn("Y"); 28 | table.appendRow(); 29 | table.set("X", 0, 10); 30 | table.set("Y", 0, 20); 31 | table.appendRow(); 32 | table.set("X", 1, 30); 33 | table.set("Y", 1, 40); 34 | 35 | //show table 36 | ImageJ ij = new ImageJ(); 37 | ij.ui().show("tables", table); 38 | 39 | //print value in the first row of column "X" 40 | System.out.println(table.get("X", 1)); 41 | 42 | } 43 | 44 | public static void main(String...args) { 45 | run(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/tables/SaveAndLoadTable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.tables; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.table.DefaultGenericTable; 13 | import org.scijava.table.GenericTable; 14 | 15 | import java.io.IOException; 16 | import java.nio.file.Files; 17 | 18 | /** 19 | * How to save and load a table 20 | * 21 | * @author Deborah Schmidt 22 | */ 23 | public class SaveAndLoadTable { 24 | 25 | private static void run() throws IOException { 26 | 27 | ImageJ ij = new ImageJ(); 28 | 29 | //create table 30 | GenericTable table = new DefaultGenericTable(); 31 | table.appendColumn("X"); 32 | table.appendColumn("Y"); 33 | table.appendRow(); 34 | table.set("X", 0, 10); 35 | table.set("Y", 0, 20); 36 | table.appendRow(); 37 | table.set("X", 1, 30); 38 | table.set("Y", 1, 40); 39 | 40 | 41 | // create temporary path to save image to 42 | String dest = Files.createTempFile("table", ".csv").toString(); 43 | System.out.println("Saving table to " + dest); 44 | 45 | // save table 46 | ij.io().save(table, dest); 47 | 48 | // load and show saved image 49 | Object savedTable = null; 50 | try { 51 | savedTable = ij.io().open(dest); 52 | } catch (Exception e) { 53 | e.printStackTrace(); 54 | } 55 | ij.ui().show("saved table", savedTable); 56 | 57 | } 58 | 59 | public static void main(String...args) throws IOException { 60 | run(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/tables/TableTutorial.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.tables; 9 | 10 | import net.imagej.ImageJ; 11 | 12 | import org.scijava.table.DefaultGenericTable; 13 | import org.scijava.table.DoubleColumn; 14 | import org.scijava.table.GenericColumn; 15 | import org.scijava.table.GenericTable; 16 | 17 | /** 18 | * This tutorial shows how to work with tables using ImageJ API 19 | * 20 | * Author: Robert Haase, Scientific Computing Facility, MPI-CBG Dresden, rhaase@mpi-cbg.de 21 | * Date: September 2016 22 | */ 23 | public class TableTutorial { 24 | 25 | 26 | public static void main(final String... args) { 27 | new TableTutorial(); 28 | } 29 | 30 | final ImageJ ij; 31 | 32 | public TableTutorial() 33 | { 34 | // we need an instance of ImageJ to show the table finally. 35 | ij = new ImageJ(); 36 | 37 | // first, we create a table 38 | GenericTable table = createTable(); 39 | 40 | // after creating a table, you can show it to the user 41 | ij.ui().show("Population of largest towns", table); 42 | 43 | // now we will analyse the content of the table 44 | analyseTable(table); 45 | } 46 | 47 | 48 | /** 49 | * This function shows how to create a table with information 50 | * about the largest towns in the world. 51 | * 52 | * @return a table with strings and numbers 53 | */ 54 | private GenericTable createTable() 55 | { 56 | // we create two columns 57 | GenericColumn nameColumn = new GenericColumn("Town"); 58 | DoubleColumn populationColumn = new DoubleColumn("Population"); 59 | 60 | // we fill the columns with information about the largest towns in the world. 61 | nameColumn.add("Karachi"); 62 | populationColumn.add(23500000.0); 63 | 64 | nameColumn.add("Bejing"); 65 | populationColumn.add(21516000.0); 66 | 67 | nameColumn.add("Sao Paolo"); 68 | populationColumn.add(21292893.0); 69 | 70 | // but actually, the largest town is Shanghai, 71 | // so let's add it at the beginning of the table. 72 | nameColumn.add(0, "Shanghai"); 73 | populationColumn.add(0, 24256800.0); 74 | 75 | // After filling the columns, you can create a table 76 | GenericTable table = new DefaultGenericTable(); 77 | 78 | // and add the columns to that table 79 | table.add(nameColumn); 80 | table.add(populationColumn); 81 | 82 | return table; 83 | } 84 | 85 | /** 86 | * This function shows how to read out information from tables, 87 | * such as 88 | * - the header of a column 89 | * - an entry from the table 90 | * 91 | * @param table A table with two columns, Town and Population 92 | */ 93 | private void analyseTable(GenericTable table) 94 | { 95 | // read out the header of the second column 96 | String header = table.get(1).getHeader(); 97 | 98 | ij.log().info("The header of the second column is: " + header); 99 | 100 | // get a certain column 101 | DoubleColumn populationColumn = (DoubleColumn)table.get("Population"); 102 | 103 | // get a value from the first line in the column 104 | double populationOfLargestTown = populationColumn.get(0); 105 | 106 | ij.log().info("The population of the largest town is: " + populationOfLargestTown); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ui/CustomWidget.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ui; 9 | 10 | import java.awt.BorderLayout; 11 | 12 | import javax.swing.DefaultListModel; 13 | import javax.swing.JButton; 14 | import javax.swing.JFrame; 15 | import javax.swing.JList; 16 | import javax.swing.JOptionPane; 17 | import javax.swing.JPanel; 18 | 19 | import org.scijava.Priority; 20 | import org.scijava.plugin.Plugin; 21 | import org.scijava.ui.swing.widget.SwingInputWidget; 22 | import org.scijava.widget.ChoiceWidget; 23 | import org.scijava.widget.InputWidget; 24 | import org.scijava.widget.WidgetModel; 25 | 26 | @Plugin(type = InputWidget.class, priority = Priority.HIGH) 27 | public class CustomWidget extends SwingInputWidget implements ChoiceWidget { 28 | 29 | public static final String CUSTOM_STYLE = "custom"; 30 | 31 | private final JButton addButton = new JButton("Add"); 32 | 33 | private DefaultListModel choices; 34 | private JList listComponent; 35 | 36 | 37 | // -- InputWidget methods -- 38 | 39 | @Override 40 | public String getValue() { 41 | return listComponent.getSelectedValue(); 42 | } 43 | 44 | // -- WrapperPlugin methods -- 45 | 46 | @Override 47 | public void set(final WidgetModel model) { 48 | super.set(model); 49 | 50 | addButton.addActionListener(actionEvent -> addChoice()); 51 | 52 | JPanel component = getComponent(); 53 | 54 | choices = new DefaultListModel<>(); 55 | final String[] items = model.getChoices(); 56 | for (final String item : items) { 57 | choices.addElement(item); 58 | } 59 | 60 | listComponent = new JList<>(choices); 61 | listComponent.addListSelectionListener(e -> { 62 | if (!e.getValueIsAdjusting()) { 63 | updateModel(); 64 | } 65 | }); 66 | 67 | JPanel container = new JPanel(); 68 | 69 | container.setLayout(new BorderLayout()); 70 | container.add(listComponent, BorderLayout.CENTER); 71 | container.add(addButton, BorderLayout.EAST); 72 | 73 | component.add(container); 74 | 75 | refreshWidget(); 76 | } 77 | 78 | // -- Typed methods -- 79 | 80 | @Override 81 | public boolean supports(final WidgetModel model) { 82 | return super.supports(model) && model.isMultipleChoice() && model.isStyle(CUSTOM_STYLE); 83 | } 84 | 85 | // -- Helper methods -- 86 | 87 | private void addChoice() { 88 | JFrame frame = new JFrame("Input"); 89 | String choice = JOptionPane.showInputDialog(frame, "Enter animal"); 90 | if (choice != null) { 91 | choices.addElement(choice); 92 | } 93 | } 94 | 95 | // -- AbstractUIInputWidget methods --- 96 | 97 | @Override 98 | public void doRefresh() { /* No-op. */ } 99 | } 100 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ui/SwingExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ui; 9 | 10 | import net.imagej.ImageJ; 11 | 12 | public class SwingExample { 13 | 14 | public static void main(final String[] args) { 15 | final ImageJ ij = new ImageJ(); 16 | ij.ui().showUI("swing"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ui/preview/CommandWithPreview.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ui.preview; 9 | 10 | import ij.ImagePlus; 11 | import net.imagej.Dataset; 12 | import net.imagej.ImageJ; 13 | import net.imagej.axis.Axes; 14 | import net.imagej.axis.AxisType; 15 | 16 | import org.scijava.command.Command; 17 | import org.scijava.command.Previewable; 18 | import org.scijava.plugin.Parameter; 19 | import org.scijava.plugin.Plugin; 20 | 21 | /** An ImageJ2 command with preview capabilities. */ 22 | @Plugin(type = Command.class, 23 | menuPath = "Tutorials>Command with Preview") 24 | public class CommandWithPreview implements Command, Previewable { 25 | 26 | // -- Parameters -- 27 | 28 | @Parameter 29 | private ImagePlus imp; 30 | 31 | @Parameter(persist = false, initializer = "initTitle") 32 | private String title; 33 | 34 | // -- Other fields -- 35 | 36 | /** The original title of the image. */ 37 | private String initialTitle; 38 | 39 | // -- Command methods -- 40 | 41 | @Override 42 | public void run() { 43 | // Set the image's title to the specified value. 44 | imp.setTitle(title); 45 | } 46 | 47 | // -- Previewable methods -- 48 | 49 | @Override 50 | public void preview() { 51 | run(); 52 | } 53 | 54 | @Override 55 | public void cancel() { 56 | // Set the image's title back to the original value. 57 | imp.setTitle(initialTitle); 58 | } 59 | 60 | // -- Initializer methods -- 61 | 62 | /** Initializes the {@link #title} parameter. */ 63 | protected void initTitle() { 64 | title = initialTitle = imp.getTitle(); 65 | } 66 | 67 | // -- Main method -- 68 | 69 | /** Tests our command. */ 70 | public static void main(final String... args) throws Exception { 71 | // Launch ImageJ as usual. 72 | final ImageJ ij = new ImageJ(); 73 | ij.launch(args); 74 | 75 | // Create a beautiful test image. 76 | long[] dims = {512, 128}; 77 | String name = "A spiffy blank image"; 78 | AxisType[] axes = {Axes.X, Axes.Y}; 79 | int bitsPerPixel = 8; 80 | boolean signed = false; 81 | boolean floating = false; 82 | final Dataset dataset = 83 | ij.dataset().create(dims, name, axes, bitsPerPixel, signed, floating); 84 | ij.ui().show(dataset); 85 | 86 | // Launch the "CommandWithPreview" command. 87 | ij.command().run(CommandWithPreview.class, true); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/ui/preview/PreviewCheckbox.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | package howto.ui.preview; 9 | 10 | import ij.ImagePlus; 11 | import net.imagej.Dataset; 12 | import net.imagej.ImageJ; 13 | import net.imagej.axis.Axes; 14 | import net.imagej.axis.AxisType; 15 | 16 | import org.scijava.ItemVisibility; 17 | import org.scijava.command.Command; 18 | import org.scijava.command.Previewable; 19 | import org.scijava.plugin.Parameter; 20 | import org.scijava.plugin.Plugin; 21 | 22 | /** 23 | * An ImageJ2 command with preview that is triggered only when the Preview 24 | * checkbox is active. 25 | */ 26 | @Plugin(type = Command.class, 27 | menuPath = "Tutorials>Preview Checkbox") 28 | public class PreviewCheckbox implements Command, Previewable { 29 | 30 | // -- Parameters -- 31 | 32 | @Parameter 33 | private ImagePlus imp; 34 | 35 | @Parameter(persist = false, initializer = "initTitle") 36 | private String title; 37 | 38 | @Parameter(visibility = ItemVisibility.INVISIBLE, persist = false, 39 | callback = "previewChanged") 40 | private boolean preview; 41 | 42 | // -- Other fields -- 43 | 44 | /** The original title of the image. */ 45 | private String initialTitle; 46 | 47 | // -- Command methods -- 48 | 49 | @Override 50 | public void run() { 51 | // Set the image's title to the specified value. 52 | imp.setTitle(title); 53 | } 54 | 55 | // -- Previewable methods -- 56 | 57 | @Override 58 | public void preview() { 59 | if (preview) run(); 60 | } 61 | 62 | @Override 63 | public void cancel() { 64 | // Set the image's title back to the original value. 65 | imp.setTitle(initialTitle); 66 | } 67 | 68 | // -- Initializer methods -- 69 | 70 | /** Initializes the {@link #title} parameter. */ 71 | protected void initTitle() { 72 | title = initialTitle = imp.getTitle(); 73 | } 74 | 75 | // -- Callback methods -- 76 | 77 | /** Called when the {@link #preview} parameter value changes. */ 78 | protected void previewChanged() { 79 | // When preview box is unchecked, reset the image title back to original. 80 | if (!preview) cancel(); 81 | } 82 | 83 | // -- Main method -- 84 | 85 | /** Tests our command. */ 86 | public static void main(final String... args) throws Exception { 87 | // Launch ImageJ as usual. 88 | final ImageJ ij = new ImageJ(); 89 | ij.launch(args); 90 | 91 | // Create a beautiful test image. 92 | long[] dims = {512, 128}; 93 | String name = "A spiffy blank image"; 94 | AxisType[] axes = {Axes.X, Axes.Y}; 95 | int bitsPerPixel = 8; 96 | boolean signed = false; 97 | boolean floating = false; 98 | final Dataset dataset = 99 | ij.dataset().create(dims, name, axes, bitsPerPixel, signed, floating); 100 | ij.ui().show(dataset); 101 | 102 | // Launch the "PreviewCheckbox" command. 103 | ij.command().run(PreviewCheckbox.class, true); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/userinput/AskForFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.userinput; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | import java.io.File; 14 | 15 | /** 16 | * How to ask the user for a file 17 | * 18 | * @author Deborah Schmidt 19 | */ 20 | public class AskForFile { 21 | 22 | private static void run() { 23 | ImageJ ij = new ImageJ(); 24 | File chosenFile = ij.ui().chooseFile(ij.getApp().getBaseDirectory(), ""); 25 | System.out.println(chosenFile.getAbsolutePath()); 26 | } 27 | 28 | public static void main(String...args) { run(); } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/userinput/AskYesNo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.userinput; 10 | 11 | import net.imagej.ImageJ; 12 | import org.scijava.ui.DialogPrompt; 13 | 14 | /** 15 | * How to ask a yes / no question 16 | * 17 | * @author Deborah Schmidt 18 | */ 19 | public class AskYesNo { 20 | 21 | private static void run() { 22 | ImageJ ij = new ImageJ(); 23 | final DialogPrompt.Result result = 24 | ij.ui().showDialog("Do you want to run this action?", "Action confirmation", 25 | DialogPrompt.MessageType.QUESTION_MESSAGE, 26 | DialogPrompt.OptionType.YES_NO_OPTION); 27 | 28 | if( result == DialogPrompt.Result.YES_OPTION ) { 29 | System.out.println("Action confirmed"); 30 | } else { 31 | System.out.println("Action denied"); 32 | } 33 | } 34 | 35 | public static void main(String...args) { 36 | run(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java/howtos/src/main/java/howto/userinput/ValidateParameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | package howto.userinput; 10 | 11 | import net.imagej.Dataset; 12 | import net.imagej.ImageJ; 13 | import net.imagej.axis.Axes; 14 | import net.imagej.axis.AxisType; 15 | import net.imglib2.type.numeric.integer.UnsignedByteType; 16 | 17 | import org.scijava.command.Command; 18 | import org.scijava.command.ContextCommand; 19 | import org.scijava.plugin.Parameter; 20 | import org.scijava.plugin.Plugin; 21 | import org.scijava.ui.UIService; 22 | 23 | /** 24 | * How to use the validater method for SciJava parameters. Here, the execution 25 | * is canceled if the {@link Dataset} does not have the expected number of 26 | * dimensions. 27 | */ 28 | @Plugin(type = Command.class) 29 | public class ValidateParameter extends ContextCommand { 30 | 31 | @Parameter 32 | private UIService uiService; 33 | 34 | @Parameter(validater = "validateDims") 35 | private Dataset dataset; 36 | 37 | public void validateDims() { 38 | if (dataset.numDimensions() != 2) { 39 | cancel("This command only works with 2D images."); 40 | } 41 | } 42 | 43 | @Override 44 | public void run() { 45 | uiService.showDialog("Yay, dataset '" + dataset.getName() + "' is 2D!"); 46 | // ... do something with the image ... 47 | } 48 | 49 | public static void main(final String[] args) { 50 | final ImageJ ij = new ImageJ(); 51 | ij.ui().showUI(); 52 | 53 | final UnsignedByteType type = new UnsignedByteType(); 54 | final long[] dims = { 512, 384, 5 }; 55 | final String name = "Blank"; 56 | final AxisType[] axes = { Axes.X, Axes.Y, Axes.Z }; 57 | final Dataset d = ij.dataset().create(type, dims, name, axes); 58 | ij.ui().show(d); 59 | 60 | ij.command().run(ValidateParameter.class, true); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /java/howtos/src/main/resources/blobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/java/howtos/src/main/resources/blobs.png -------------------------------------------------------------------------------- /java/ij2-image-plus/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | ij2-image-plus 17 | 1.0.0-SNAPSHOT 18 | 19 | IJ2 ImagePlus 20 | 21 | This project provides examples on how to work with ImagePlus with the new image types in IJ2. 22 | It's goal is to help transition from IJ1 style plugins to IJ2. 23 | 24 | https://github.com/[MY-ORG]/[MY-REPO] 25 | 2016 26 | 27 | [MY-ORGANIZATION-NAME] 28 | [MY-ORGANIZATION-WEB-SITE] 29 | 30 | 31 | 32 | Unlicense 33 | https://unlicense.org/ 34 | repo 35 | 36 | 37 | 38 | 39 | 40 | [MY-GITHUB-ID] 41 | [MY-FULL-NAME] 42 | https://imagej.net/User:[MY-IMAGEJ-WIKI-ACCOUNT] 43 | 44 | 45 | 46 | 47 | None 48 | 49 | 50 | 51 | 52 | 53 | Image.sc Forum 54 | https://forum.image.sc/tags/imagej 55 | 56 | 57 | 58 | 59 | scm:git:git://github.com/[MY-ORG]/[MY-REPO] 60 | scm:git:git@github.com:[MY-ORG]/[MY-REPO] 61 | HEAD 62 | https://github.com/[MY-ORG]/[MY-REPO] 63 | 64 | 65 | GitHub Issues 66 | http://github.com/[MY-ORG]/[MY-REPO]/issues 67 | 68 | 69 | None 70 | 71 | 72 | 73 | DatasetWrapping 74 | unlicense 75 | N/A 76 | ImageJ software for multidimensional image processing and analysis. 77 | 78 | 79 | 80 | 81 | scijava.public 82 | https://maven.scijava.org/content/groups/public 83 | 84 | 85 | 86 | 87 | 88 | net.imagej 89 | imagej 90 | 91 | 92 | 93 | 94 | net.imagej 95 | ij 96 | 97 | 98 | net.imagej 99 | imagej-legacy 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /java/listen-to-events/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | listen-to-events 17 | 1.0.0-SNAPSHOT 18 | 19 | Listen to Events 20 | This example shows how to listen to events of interest using the event service. 21 | https://github.com/[MY-ORG]/[MY-REPO] 22 | 2013 23 | 24 | [MY-ORGANIZATION-NAME] 25 | [MY-ORGANIZATION-WEB-SITE] 26 | 27 | 28 | 29 | Unlicense 30 | https://unlicense.org/ 31 | repo 32 | 33 | 34 | 35 | 36 | 37 | [MY-GITHUB-ID] 38 | [MY-FULL-NAME] 39 | https://imagej.net/User:[MY-IMAGEJ-WIKI-ACCOUNT] 40 | 41 | 42 | 43 | 44 | None 45 | 46 | 47 | 48 | 49 | 50 | Image.sc Forum 51 | https://forum.image.sc/tags/imagej 52 | 53 | 54 | 55 | 56 | scm:git:git://github.com/[MY-ORG]/[MY-REPO] 57 | scm:git:git@github.com:[MY-ORG]/[MY-REPO] 58 | HEAD 59 | https://github.com/[MY-ORG]/[MY-REPO] 60 | 61 | 62 | GitHub Issues 63 | http://github.com/[MY-ORG]/[MY-REPO]/issues 64 | 65 | 66 | None 67 | 68 | 69 | 70 | ListenToEvents 71 | unlicense 72 | N/A 73 | ImageJ software for multidimensional image processing and analysis. 74 | 75 | 76 | 77 | 78 | scijava.public 79 | https://maven.scijava.org/content/groups/public 80 | 81 | 82 | 83 | 84 | 85 | net.imagej 86 | imagej 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /java/listen-to-events/src/main/java/ListenToEvents.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | import net.imagej.Dataset; 10 | import net.imagej.ImageJ; 11 | import net.imagej.axis.Axes; 12 | import net.imagej.axis.AxisType; 13 | import net.imagej.event.DatasetCreatedEvent; 14 | 15 | import org.scijava.display.event.DisplayEvent; 16 | import org.scijava.display.event.input.MsEnteredEvent; 17 | import org.scijava.display.event.input.MsEvent; 18 | import org.scijava.display.event.window.WinEvent; 19 | import org.scijava.event.EventHandler; 20 | import org.scijava.event.SciJavaEvent; 21 | import org.scijava.log.LogService; 22 | import org.scijava.plugin.Parameter; 23 | import org.scijava.service.Service; 24 | 25 | /** 26 | * Listens to events of interest. 27 | *

28 | * ImageJ features a granular class hierarchy of event types. See 29 | * {@link SciJavaEvent} for the top level class. You can also watch events as 30 | * they occur by running ImageJ's "Watch Events" command. 31 | *

32 | *

33 | * If you register an event handling method on a particular type of event, that 34 | * method will receive a callback for any event published of that type, 35 | * including subtypes. For example, if you specify an event handler for 36 | * {@link MsEvent}s, it will be called when e.g. a {@link MsEnteredEvent} 37 | * occurs. 38 | *

39 | *

40 | * This example demonstrates how to subscribe to events from arbitrary code. 41 | * Note that if you want to subscribe to events from a {@link Service}, you need 42 | * only add a method with the @{@link EventHandler} annotation; it will be 43 | * automatically subscribed. 44 | *

45 | */ 46 | public class ListenToEvents { 47 | 48 | private static MyEventSubscriber myEventSubscriber; 49 | 50 | public static void main(final String... args) throws Exception { 51 | // Create the ImageJ application context with all available services. 52 | final ImageJ ij = new ImageJ(); 53 | 54 | // Create an event subscriber and inject the application context; 55 | // this step will automatically subscribe to event notifications 56 | // for all methods labeled with the "@EventHandler" annotation. 57 | myEventSubscriber = new MyEventSubscriber(); 58 | ij.getContext().inject(myEventSubscriber); 59 | 60 | // NB: If the myEventSubscriber object falls out of scope, it may be 61 | // garbage collected, and then your event handling methods will no longer 62 | // get called. So it is important to keep a reference to any object which 63 | // is subscribing to ImageJ events! 64 | 65 | // Create a new dataset. 66 | final int w = 512, h = 384; 67 | final Dataset dataset = 68 | ij.dataset().create(new long[] { w, h }, "Events Demo", 69 | new AxisType[] { Axes.X, Axes.Y }, 8, false, false); 70 | 71 | // Display the dataset. 72 | ij.ui().show(dataset); 73 | } 74 | 75 | /** A class for subscribing to ImageJ events of interest. */ 76 | public static class MyEventSubscriber { 77 | 78 | @Parameter 79 | private LogService log; 80 | 81 | /** Responds to dataset creation events. */ 82 | @EventHandler 83 | public void onEvent(final DatasetCreatedEvent evt) { 84 | logEvent(evt); 85 | } 86 | 87 | /** Responds to display events. */ 88 | @EventHandler 89 | public void onEvent(final DisplayEvent evt) { 90 | logEvent(evt); 91 | } 92 | 93 | /** Responds to mouse events. */ 94 | @EventHandler 95 | public void onEvent(final MsEvent evt) { 96 | logEvent(evt); 97 | } 98 | 99 | /** Responds to window events. */ 100 | @EventHandler 101 | public void onEvent(final WinEvent evt) { 102 | logEvent(evt); 103 | } 104 | 105 | private void logEvent(final SciJavaEvent evt) { 106 | log.info("[" + evt.getClass().getSimpleName() + "] " + evt); 107 | } 108 | 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /java/swing-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | swing-example 17 | 1.0.0-SNAPSHOT 18 | 19 | Swing UI Command 20 | This example shows how to use a swing GUI with imagej2. 21 | https://github.com/[MY-ORG]/[MY-REPO] 22 | 2016 23 | 24 | [MY-ORGANIZATION-NAME] 25 | [MY-ORGANIZATION-WEB-SITE] 26 | 27 | 28 | 29 | Unlicense 30 | https://unlicense.org/ 31 | repo 32 | 33 | 34 | 35 | 36 | 37 | [MY-GITHUB-ID] 38 | [MY-FULL-NAME] 39 | https://imagej.net/User:[MY-IMAGEJ-WIKI-ACCOUNT] 40 | 41 | 42 | 43 | 44 | None 45 | 46 | 47 | 48 | 49 | 50 | Image.sc Forum 51 | https://forum.image.sc/tags/imagej 52 | 53 | 54 | 55 | 56 | scm:git:git://github.com/[MY-ORG]/[MY-REPO] 57 | scm:git:git@github.com:[MY-ORG]/[MY-REPO] 58 | HEAD 59 | https://github.com/[MY-ORG]/[MY-REPO] 60 | 61 | 62 | GitHub Issues 63 | http://github.com/[MY-ORG]/[MY-REPO]/issues 64 | 65 | 66 | None 67 | 68 | 69 | 70 | SwingExample 71 | unlicense 72 | N/A 73 | ImageJ software for multidimensional image processing and analysis. 74 | 75 | 76 | 77 | 78 | scijava.public 79 | https://maven.scijava.org/content/groups/public 80 | 81 | 82 | 83 | 84 | 85 | net.imagej 86 | imagej 87 | 88 | 89 | net.imglib2 90 | imglib2-ij 91 | 92 | 93 | net.imagej 94 | imagej-legacy 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /java/swing-example/src/main/java/DeconvolutionCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | import net.imagej.ImgPlus; 10 | import net.imagej.ops.OpService; 11 | import net.imglib2.RandomAccessibleInterval; 12 | import net.imglib2.img.Img; 13 | import net.imglib2.type.numeric.real.FloatType; 14 | 15 | import org.scijava.ItemIO; 16 | import org.scijava.command.Command; 17 | import org.scijava.log.LogService; 18 | import org.scijava.plugin.Parameter; 19 | import org.scijava.plugin.Plugin; 20 | import org.scijava.ui.UIService; 21 | 22 | @Plugin(type = Command.class, headless = true, 23 | menuPath = "Deconvolution>Deconvolution Command") 24 | public class DeconvolutionCommand implements Command { 25 | 26 | @Parameter 27 | OpService ops; 28 | 29 | @Parameter 30 | LogService log; 31 | 32 | @Parameter 33 | UIService ui; 34 | 35 | @Parameter 36 | ImgPlus img; 37 | 38 | @Parameter 39 | Double sxy; 40 | 41 | @Parameter 42 | Double sz; 43 | 44 | @Parameter 45 | Integer numIterations; 46 | 47 | @Parameter(type = ItemIO.OUTPUT) 48 | RandomAccessibleInterval deconvolved; 49 | 50 | /** 51 | * Run the deconvolution process 52 | */ 53 | @Override 54 | public void run() { 55 | final Img imgFloat = ops.convert().float32(img); 56 | 57 | RandomAccessibleInterval psf = null; 58 | 59 | if (imgFloat.numDimensions() == 3) { 60 | psf = ops.create().kernelGauss(new double[] { sxy, sxy, sz }, 61 | new FloatType()); 62 | } 63 | else { 64 | psf = ops.create().kernelGauss(new double[] { sxy, sxy }, 65 | new FloatType()); 66 | } 67 | 68 | log.info("starting deconvolution"); 69 | final Img deconvolved = ops.create().img(imgFloat); 70 | ops.deconvolve().richardsonLucy(deconvolved, imgFloat, psf, numIterations); 71 | log.info("finished deconvolution"); 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /java/swing-example/src/main/java/DeconvolutionCommandSwing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | import javax.swing.SwingUtilities; 10 | 11 | import net.imglib2.RandomAccessibleInterval; 12 | import net.imglib2.type.numeric.real.FloatType; 13 | 14 | import org.scijava.Context; 15 | import org.scijava.ItemIO; 16 | import org.scijava.command.Command; 17 | import org.scijava.plugin.Parameter; 18 | import org.scijava.plugin.Plugin; 19 | 20 | @Plugin(type = Command.class, headless = true, 21 | menuPath = "Deconvolution>Deconvolution Swing") 22 | public class DeconvolutionCommandSwing implements Command { 23 | 24 | @Parameter 25 | private Context ctx; 26 | 27 | @Parameter(type = ItemIO.OUTPUT) 28 | private RandomAccessibleInterval deconvolved; 29 | 30 | private static DeconvolutionDialog dialog = null; 31 | 32 | /** 33 | * show a dialog and give the dialog access to required IJ2 Services 34 | */ 35 | @Override 36 | public void run() { 37 | SwingUtilities.invokeLater(() -> { 38 | if (dialog == null) { 39 | dialog = new DeconvolutionDialog(ctx); 40 | } 41 | dialog.setVisible(true); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java/swing-example/src/main/java/DeconvolutionDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | import java.awt.BorderLayout; 10 | import java.awt.FlowLayout; 11 | import java.awt.event.ActionEvent; 12 | import java.awt.event.ActionListener; 13 | 14 | import javax.swing.JButton; 15 | import javax.swing.JDialog; 16 | import javax.swing.JPanel; 17 | import javax.swing.border.EmptyBorder; 18 | 19 | import net.imagej.ops.OpService; 20 | import net.imglib2.RandomAccessibleInterval; 21 | import net.imglib2.img.Img; 22 | import net.imglib2.img.display.imagej.ImageJFunctions; 23 | import net.imglib2.type.numeric.real.FloatType; 24 | 25 | import org.scijava.Context; 26 | import org.scijava.app.StatusService; 27 | import org.scijava.command.CommandService; 28 | import org.scijava.log.LogService; 29 | import org.scijava.plugin.Parameter; 30 | import org.scijava.thread.ThreadService; 31 | import org.scijava.ui.UIService; 32 | 33 | import ij.IJ; 34 | import ij.ImagePlus; 35 | 36 | public class DeconvolutionDialog extends JDialog { 37 | 38 | @Parameter 39 | private OpService ops; 40 | 41 | @Parameter 42 | private LogService log; 43 | 44 | @Parameter 45 | private StatusService status; 46 | 47 | @Parameter 48 | private CommandService cmd; 49 | 50 | @Parameter 51 | private ThreadService thread; 52 | 53 | @Parameter 54 | private UIService ui; 55 | 56 | private final JPanel contentPanel = new JPanel(); 57 | 58 | /** 59 | * Create the dialog. 60 | */ 61 | public DeconvolutionDialog(final Context ctx) { 62 | ctx.inject(this); 63 | setBounds(100, 100, 450, 300); 64 | getContentPane().setLayout(new BorderLayout()); 65 | contentPanel.setLayout(new FlowLayout()); 66 | contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); 67 | getContentPane().add(contentPanel, BorderLayout.CENTER); 68 | { 69 | final JButton btnDeconvolve = new JButton("Deconvolve via ThreadService"); 70 | btnDeconvolve.addActionListener(new ActionListener() { 71 | 72 | @Override 73 | public void actionPerformed(final ActionEvent arg0) { 74 | 75 | // start deconvolution with the scijava ThreadService 76 | thread.run(() -> deconvolve()); 77 | } 78 | }); 79 | contentPanel.add(btnDeconvolve); 80 | } 81 | { 82 | final JButton btnDeconvolveViaCommand = new JButton( 83 | "Deconvolve via Command"); 84 | btnDeconvolveViaCommand.addActionListener(new ActionListener() { 85 | 86 | @Override 87 | public void actionPerformed(final ActionEvent arg0) { 88 | deconvolveViaCommand(); 89 | } 90 | }); 91 | contentPanel.add(btnDeconvolveViaCommand); 92 | } 93 | } 94 | 95 | /** 96 | * Perform deconvolution 97 | */ 98 | public void deconvolve() { 99 | final ImagePlus imp = IJ.getImage(); 100 | 101 | final Img img = ImageJFunctions.wrap(imp); 102 | 103 | final Img imgFloat = ops.convert().float32(img); 104 | 105 | RandomAccessibleInterval psf = null; 106 | 107 | if (imgFloat.numDimensions() == 3) { 108 | psf = ops.create().kernelGauss(new double[] { 3, 3, 7 }, new FloatType()); 109 | } 110 | else { 111 | psf = ops.create().kernelGauss(new double[] { 3, 3 }, new FloatType()); 112 | } 113 | 114 | log.info("starting deconvolution with thread service"); 115 | final Img deconvolved = ops.create().img(imgFloat); 116 | ops.deconvolve().richardsonLucy(deconvolved, imgFloat, psf, 50); 117 | log.info("finished deconvolution"); 118 | 119 | ui.show(deconvolved); 120 | } 121 | 122 | /** 123 | * perform deconvolution by calling a command 124 | */ 125 | public void deconvolveViaCommand() { 126 | final ImagePlus imp = IJ.getImage(); 127 | final Img img = ImageJFunctions.wrap(imp); 128 | 129 | cmd.run(DeconvolutionCommand.class, true, "img", img, "sxy", 3, "sz", 7, 130 | "numIterations", 50); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /java/swing-example/src/main/java/SwingExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To the extent possible under law, the ImageJ developers have waived 3 | * all copyright and related or neighboring rights to this tutorial code. 4 | * 5 | * See the Unlicense for details: 6 | * https://unlicense.org/ 7 | */ 8 | 9 | import javax.swing.WindowConstants; 10 | 11 | import net.imagej.ImageJ; 12 | 13 | public class SwingExample { 14 | 15 | public static void main(final String[] args) { 16 | final ImageJ ij = new ImageJ(); 17 | ij.launch(args); 18 | 19 | try { 20 | final DeconvolutionDialog dialog = new DeconvolutionDialog(ij.context()); 21 | dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 22 | dialog.setVisible(true); 23 | } 24 | catch (final Exception e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /notebooks/1-Using-ImageJ/7-Calling-Scripts-from-Scripts.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Scripting: the easy way to extend ImageJ" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Parameterized scripting!" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "Added new repo: scijava.public\n" 27 | ] 28 | }, 29 | { 30 | "data": { 31 | "application/vnd.jupyter.widget-view+json": { 32 | "model_id": "", 33 | "version_major": 2, 34 | "version_minor": 0 35 | }, 36 | "method": "display_data" 37 | }, 38 | "metadata": {}, 39 | "output_type": "display_data" 40 | }, 41 | { 42 | "data": { 43 | "application/vnd.jupyter.widget-view+json": { 44 | "model_id": "d2990d05-e083-4f37-8397-7924a5d67f6f", 45 | "version_major": 2, 46 | "version_minor": 0 47 | }, 48 | "method": "display_data" 49 | }, 50 | "metadata": {}, 51 | "output_type": "display_data" 52 | }, 53 | { 54 | "data": { 55 | "text/plain": [ 56 | "ImageJ v2.0.0-rc-71 is ready to go." 57 | ] 58 | }, 59 | "execution_count": 1, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "%classpath config resolver scijava.public https://maven.scijava.org/content/groups/public\n", 66 | "%classpath add mvn net.imagej imagej 2.0.0-rc-71\n", 67 | "ij = new net.imagej.ImageJ()\n", 68 | "\"ImageJ v${ij.getVersion()} is ready to go.\"" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 2, 74 | "metadata": {}, 75 | "outputs": [ 76 | { 77 | "data": { 78 | "application/vnd.jupyter.widget-view+json": { 79 | "model_id": "2bb3d168-c5b3-40f5-a5e2-8bfe111d3ba2", 80 | "version_major": 2, 81 | "version_minor": 0 82 | }, 83 | "method": "display_data" 84 | }, 85 | "metadata": {}, 86 | "output_type": "display_data" 87 | } 88 | ], 89 | "source": [ 90 | "script = \"\"\"\n", 91 | "#@String name\n", 92 | "#@output String greeting\n", 93 | "greeting = \"Hello, \" + name + \"!\"\n", 94 | "\"\"\"\n", 95 | "task = ij.script().run(\"hello.groovy\", script, true, [\"name\": \"Johnny\"])\n", 96 | "// it runs asynchronously! let's wait for it to complete.\n", 97 | "module = task.get()\n", 98 | "// let's see what it computed\n", 99 | "module.getOutputs()" 100 | ] 101 | } 102 | ], 103 | "metadata": { 104 | "kernelspec": { 105 | "display_name": "Groovy", 106 | "language": "groovy", 107 | "name": "groovy" 108 | }, 109 | "language_info": { 110 | "codemirror_mode": "groovy", 111 | "file_extension": ".groovy", 112 | "mimetype": "", 113 | "name": "Groovy", 114 | "nbconverter_exporter": "", 115 | "version": "2.5.6" 116 | }, 117 | "toc": { 118 | "base_numbering": 1, 119 | "nav_menu": {}, 120 | "number_sections": true, 121 | "sideBar": true, 122 | "skip_h1_title": true, 123 | "title_cell": "Table of Contents", 124 | "title_sidebar": "Contents", 125 | "toc_cell": false, 126 | "toc_position": { 127 | "height": "calc(100% - 180px)", 128 | "left": "10px", 129 | "top": "150px", 130 | "width": "307px" 131 | }, 132 | "toc_section_display": true, 133 | "toc_window_display": true 134 | } 135 | }, 136 | "nbformat": 4, 137 | "nbformat_minor": 2 138 | } 139 | -------------------------------------------------------------------------------- /notebooks/1-Using-ImageJ/Ops/filter/ifft.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Inverse Fast Fourier Transform (WIP: mostly incomplete)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "Added new repo: scijava.public\n" 20 | ] 21 | }, 22 | { 23 | "data": { 24 | "application/vnd.jupyter.widget-view+json": { 25 | "model_id": "", 26 | "version_major": 2, 27 | "version_minor": 0 28 | }, 29 | "method": "display_data" 30 | }, 31 | "metadata": {}, 32 | "output_type": "display_data" 33 | }, 34 | { 35 | "data": { 36 | "application/vnd.jupyter.widget-view+json": { 37 | "model_id": "dedfaca0-af15-4bc5-aa88-d3a0308e0659", 38 | "version_major": 2, 39 | "version_minor": 0 40 | }, 41 | "method": "display_data" 42 | }, 43 | "metadata": {}, 44 | "output_type": "display_data" 45 | }, 46 | { 47 | "data": { 48 | "text/plain": [ 49 | "net.imagej.ImageJ@565027b" 50 | ] 51 | }, 52 | "execution_count": 1, 53 | "metadata": {}, 54 | "output_type": "execute_result" 55 | } 56 | ], 57 | "source": [ 58 | "//load ImageJ\n", 59 | "%classpath config resolver scijava.public https://maven.scijava.org/content/groups/public\n", 60 | "%classpath add mvn net.imagej imagej 2.0.0-rc-67\n", 61 | "\n", 62 | "//create ImageJ object\n", 63 | "ij = new net.imagej.ImageJ()" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "This `Op` does ...." 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 2, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "Available operations:\n", 82 | "\t(RandomAccessibleInterval out) =\n", 83 | "\tnet.imagej.ops.filter.convolve.ConvolveNaiveF(\n", 84 | "\t\tRandomAccessibleInterval in1,\n", 85 | "\t\tRandomAccessibleInterval in2,\n", 86 | "\t\tOutOfBoundsFactory obf?,\n", 87 | "\t\tType outType?)\n", 88 | "\t(RandomAccessibleInterval out) =\n", 89 | "\tnet.imagej.ops.filter.convolve.ConvolveFFTF(\n", 90 | "\t\tRandomAccessibleInterval in1,\n", 91 | "\t\tRandomAccessibleInterval in2,\n", 92 | "\t\tlong[] borderSize?,\n", 93 | "\t\tOutOfBoundsFactory obfInput?,\n", 94 | "\t\tOutOfBoundsFactory obfKernel?,\n", 95 | "\t\tType outType?,\n", 96 | "\t\tComplexType fftType?)\n", 97 | "\t(RandomAccessibleInterval out) =\n", 98 | "\tnet.imagej.ops.filter.convolve.ConvolveNaiveC(\n", 99 | "\t\tRandomAccessibleInterval out,\n", 100 | "\t\tRandomAccessible in,\n", 101 | "\t\tRandomAccessibleInterval kernel)\n", 102 | "\t(RandomAccessibleInterval out) =\n", 103 | "\tnet.imagej.ops.filter.convolve.ConvolveFFTC(\n", 104 | "\t\tRandomAccessibleInterval out,\n", 105 | "\t\tRandomAccessibleInterval in1,\n", 106 | "\t\tRandomAccessibleInterval in2,\n", 107 | "\t\tRandomAccessibleInterval fftInput,\n", 108 | "\t\tRandomAccessibleInterval fftKernel,\n", 109 | "\t\tboolean performInputFFT?,\n", 110 | "\t\tboolean performKernelFFT?)" 111 | ] 112 | }, 113 | "execution_count": 2, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "ij.op().help(\"convolve\")" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "This is how the Op works..." 127 | ] 128 | } 129 | ], 130 | "metadata": { 131 | "kernelspec": { 132 | "display_name": "Groovy", 133 | "language": "groovy", 134 | "name": "groovy" 135 | }, 136 | "language_info": { 137 | "codemirror_mode": "groovy", 138 | "file_extension": ".groovy", 139 | "mimetype": "", 140 | "name": "Groovy", 141 | "nbconverter_exporter": "", 142 | "version": "2.4.3" 143 | }, 144 | "toc": { 145 | "base_numbering": 1, 146 | "nav_menu": {}, 147 | "number_sections": false, 148 | "sideBar": false, 149 | "skip_h1_title": false, 150 | "title_cell": "Table of Contents", 151 | "title_sidebar": "Contents", 152 | "toc_cell": false, 153 | "toc_position": {}, 154 | "toc_section_display": false, 155 | "toc_window_display": false 156 | } 157 | }, 158 | "nbformat": 4, 159 | "nbformat_minor": 2 160 | } 161 | -------------------------------------------------------------------------------- /notebooks/1-Using-ImageJ/Ops/transform/interpolateView.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## InterpolateView Op" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "Added new repo: scijava.public\n" 20 | ] 21 | }, 22 | { 23 | "data": { 24 | "application/vnd.jupyter.widget-view+json": { 25 | "model_id": "", 26 | "version_major": 2, 27 | "version_minor": 0 28 | }, 29 | "method": "display_data" 30 | }, 31 | "metadata": {}, 32 | "output_type": "display_data" 33 | }, 34 | { 35 | "data": { 36 | "application/vnd.jupyter.widget-view+json": { 37 | "model_id": "2735a867-3146-4388-8ec0-13df7645e5db", 38 | "version_major": 2, 39 | "version_minor": 0 40 | }, 41 | "method": "display_data" 42 | }, 43 | "metadata": {}, 44 | "output_type": "display_data" 45 | }, 46 | { 47 | "data": { 48 | "text/plain": [ 49 | "net.imagej.ImageJ@7b00c550" 50 | ] 51 | }, 52 | "execution_count": 1, 53 | "metadata": {}, 54 | "output_type": "execute_result" 55 | } 56 | ], 57 | "source": [ 58 | "//load ImageJ\n", 59 | "%classpath config resolver scijava.public https://maven.scijava.org/content/groups/public\n", 60 | "%classpath add mvn net.imagej imagej 2.0.0-rc-67\n", 61 | "\n", 62 | "//create ImageJ object\n", 63 | "ij = new net.imagej.ImageJ()" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "This `Op` wraps the `Views.interpolate()` method of ImgLib2, [interpolating](https://en.wikipedia.org/wiki/Interpolation) any image type into a `RealRandomAccessible`. This allows a `RealRandomAccess` to be created on the `RealRandomAccessible`, allowing decimal pixels to be interrogated. Let's see how the `Op` is called:" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 2, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "Available operations:\n", 82 | "\t(RealRandomAccessible out) =\n", 83 | "\tnet.imagej.ops.transform.interpolateView.DefaultInterpolateView(\n", 84 | "\t\tEuclideanSpace in,\n", 85 | "\t\tInterpolatorFactory factory)" 86 | ] 87 | }, 88 | "execution_count": 2, 89 | "metadata": {}, 90 | "output_type": "execute_result" 91 | } 92 | ], 93 | "source": [ 94 | "ij.op().help('interpolateView')" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "There are two parameters to `interpolate`:\n", 102 | "* `EuclideanSpace in`: [`EuclideanSpace`](http://javadoc.scijava.org/ImgLib2/net/imglib2/EuclideanSpace.html) is a low-level interface that all image types implement. Any image can be passed in as an argument here.\n", 103 | "* `InterpolatorFactory factory`: The [`InterpolatorFactory`](http://javadoc.scijava.org/ImgLib2/index.html?net/imglib2/interpolation/InterpolatorFactory.html) tells `interpolateView()` how to create the subpixel data. As listed in the Javadoc there are many different varieties of `InterpolatorFactory`, such as [nearest neighbor](https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation), [lanzcos resampling](https://en.wikipedia.org/wiki/Lanczos_resampling), and [N-Linear](https://en.wikipedia.org/wiki/Linear_interpolation).\n", 104 | "\n", 105 | "Let's get a really small image and interpolate it:" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 3, 111 | "metadata": {}, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "[INFO] Verifying GIF format\n", 118 | "[INFO] Reading dimensions\n", 119 | "[INFO] Reading data blocks\n" 120 | ] 121 | }, 122 | { 123 | "data": { 124 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAnklEQVR42u2WXQrAIAyD48k9mkfbmFAoA39qqx2sQh4ln9hEcRkuAFWiPdYApZQACAAfAEpAzrkqAP4F8Bi6AZChGwCZugBw0+MAZOpyBdz8eAr4aV3+Az0Td4ClQV4FsIJQAXDR8L01ep6hyf9IM2mAtoS0V2HShAHwGYDZwdsKIIUwTcFKMkQArbLpyaSIUkqi9pNAwKr1Ro3YmosbRJ9MlGVXVHcAAAAASUVORK5CYII=" 125 | }, 126 | "execution_count": 3, 127 | "metadata": {}, 128 | "output_type": "execute_result" 129 | } 130 | ], 131 | "source": [ 132 | "import net.imglib2.interpolation.randomaccess.NearestNeighborInterpolatorFactory\n", 133 | "import net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory\n", 134 | "import net.imglib2.interpolation.randomaccess.LanczosInterpolatorFactory\n", 135 | "\n", 136 | "scaleFactors = [4, 4, 1] // Enlarge X and Y by 4x; leave channel count the same.\n", 137 | "\n", 138 | "input = ij.scifio().datasetIO().open(\"http://imagej.net/images/ij-icon.gif\")\n", 139 | "\n", 140 | "interpolated= ij.op().run(\"interpolateView\", input, new NLinearInterpolatorFactory())\n", 141 | "\n", 142 | "ij.notebook().display(input)" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "Note that we cannot display the interpolated image since it is a `RealRandomAccessible`. However we can interrogate the image for values at decimal pixel values:" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 4, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "168.0\n" 162 | ] 163 | }, 164 | { 165 | "data": { 166 | "text/plain": [ 167 | "null" 168 | ] 169 | }, 170 | "execution_count": 4, 171 | "metadata": {}, 172 | "output_type": "execute_result" 173 | } 174 | ], 175 | "source": [ 176 | "access = interpolated.realRandomAccess()\n", 177 | "\n", 178 | "//coordinates to interrogate\n", 179 | "x = 16.6 as double\n", 180 | "y = 10.2 as double\n", 181 | "\n", 182 | "//set the randomAccess to x in the first dimension and y in the second\n", 183 | "access.setPosition(x, 0)\n", 184 | "access.setPosition(y, 1)\n", 185 | "\n", 186 | "println(access.get().getRealDouble())" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "If you want to be able to get a `RandomAccessible` from your `RealRandomAccessible`, check out [`rasterView`](rasterView.ipynb)" 194 | ] 195 | } 196 | ], 197 | "metadata": { 198 | "kernelspec": { 199 | "display_name": "Groovy", 200 | "language": "groovy", 201 | "name": "groovy" 202 | }, 203 | "language_info": { 204 | "codemirror_mode": "groovy", 205 | "file_extension": ".groovy", 206 | "mimetype": "", 207 | "name": "Groovy", 208 | "nbconverter_exporter": "", 209 | "version": "2.4.3" 210 | }, 211 | "toc": { 212 | "base_numbering": 1, 213 | "nav_menu": {}, 214 | "number_sections": false, 215 | "sideBar": false, 216 | "skip_h1_title": false, 217 | "title_cell": "Table of Contents", 218 | "title_sidebar": "Contents", 219 | "toc_cell": false, 220 | "toc_position": {}, 221 | "toc_section_display": false, 222 | "toc_window_display": false 223 | } 224 | }, 225 | "nbformat": 4, 226 | "nbformat_minor": 2 227 | } 228 | -------------------------------------------------------------------------------- /notebooks/1-Using-ImageJ/ide-autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/tutorials/586267dc1e84d722b1765eddb5cb69c3ea28c0b6/notebooks/1-Using-ImageJ/ide-autocomplete.png -------------------------------------------------------------------------------- /notebooks/README.md: -------------------------------------------------------------------------------- 1 | This project contains example code for working with 2 | [ImageJ](https://imagej.net/ImageJ) and [SciJava](https://imagej.net/SciJava). 3 | 4 | WHY JUPYTER NOTEBOOKS 5 | --------------------- 6 | [Jupyter Notebooks](https://jupyter.org/) are a great outreach tool to demonstrate how programs work interactively in real time. We use Jupyter for teaching ImageJ2 so that you can try and change the code yourself easily. See the [Intro to Jupyter notebook](Intro-to-Jupyter.ipynb) if you have never used Jupyter notebook before. 7 | 8 | RUNNING JUPYTER NOTEBOOKS 9 | ------------------------- 10 | 11 | There are multiple ways to [run the Jupyter Notebooks](https://jupyter.org/install): 12 | 13 | | Method | Pros | Cons | Running Live? | 14 | | --- | --- | --- | --- | 15 | | [Local
Environment](#recommended-local-environment) | Run code locally on your machine. | Must install developer tools. | Yes | 16 | | [On GitHub](#on-github) | View notebooks quickly on GitHub's website. | Code does not run live; rendering is less
complete & correct than on nbviewer. | No | 17 | | [Binder](#binder) | Run code on the cloud, no local installation. | Slow to spin up the web container. | Yes | 18 | | [Nbviewer](#nbviewer) | View notebooks nicely rendered on nbviewer.org. | Code does not run live;
not integrated with GitHub. | No | 19 | 20 | ### (Recommended) Local Environment 21 | 1. Install [Miniconda](https://conda.io/miniconda.html). 22 | 2. Clone this `imagej/tutorials` repository. 23 | 3. Open a console and `cd` to your cloned working copy. 24 | 4. `conda env create -f environment.yml` to create a conda environment with the 25 | dependencies these notebooks need. 26 | 5. `conda activate scijava` to activate the environment. 27 | 6. `jupyter notebook` to launch Jupyter Notebook in a web browser window. 28 | 7. In the browser, click into `notebooks`, then click on the 29 | `ImageJ-Tutorials-and-Demo.ipynb` notebook to open it. 30 | 31 | ### On GitHub 32 | The easiest way to get started with the ImageJ and SciJava APIs is via the 33 | ImageJ Jupyter notebooks, located in the `notebooks` subfolder of this repository. 34 | 35 | ### Binder 36 | [![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/imagej/tutorials/master) 37 | 38 | Use the "launch binder" badge above to try the Jupyter notebooks on the cloud 39 | using [Binder](https://mybinder.org), with no local installation necessary. 40 | 41 | Note: Binder startup may take a minute 42 | 43 | ### Nbviewer 44 | [![Nbviewer](https://camo.githubusercontent.com/a2b8b49ec63c501c07f7f5d73ced6fdee58a337609d4a6962d6ec5b4fbd3fec9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72656e6465722d6e627669657765722d6f72616e67652e737667)](https://nbviewer.org/github/imagej/tutorials/tree/master/) 45 | 46 | Use the "render nbviewer" badge above to access the Jupyter Notebooks on your machine through nbviewer. 47 | 48 | ## Notebook Technologies 49 | The introductory notebooks use the Groovy kernel from 50 | [BeakerX](http://beakerx.com). Several other JVM-based kernels 51 | are usable as well, including Clojure, Java, Kotlin and Scala. 52 | 53 | There are also notebooks using the standard Python kernel plus 54 | the [pyimagej](https://pypi.org/project/pyimagej) package, 55 | enabling use of ImageJ from Python programs. 56 | 57 | LICENSING 58 | --------- 59 | 60 | To the extent possible under law, the ImageJ developers have waived 61 | all copyright and related or neighboring rights to this tutorial code. 62 | 63 | See [unlicense.org](https://unlicense.org/) for details. 64 | 65 | 66 | SEE ALSO 67 | -------- 68 | 69 | * The [Tutorials](https://imagej.net/tutorials) and [Development](https://imagej.net/develop) sections of the ImageJ wiki. 70 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.scijava 10 | pom-scijava 11 | 34.1.0 12 | 13 | 14 | 15 | imagej-tutorials 16 | imagej-tutorials-aggregator 17 | 1.0.0-SNAPSHOT 18 | pom 19 | 20 | ImageJ Tutorials 21 | A collection of tutorials for ImageJ. 22 | https://github.com/imagej/tutorials 23 | 2012 24 | 25 | ImageJ 26 | https://imagej.net/ 27 | 28 | 29 | 30 | Unlicense 31 | https://unlicense.org/ 32 | repo 33 | 34 | 35 | 36 | 37 | 38 | ctrueden 39 | Curtis Rueden 40 | https://imagej.net/User:Rueden 41 | 42 | founder 43 | lead 44 | developer 45 | debugger 46 | reviewer 47 | support 48 | maintainer 49 | 50 | 51 | 52 | 53 | 54 | Johannes Schindelin 55 | https://imagej.net/User:Schindelin 56 | dscho 57 | 58 | 59 | Brian Northan 60 | https://imagej.net/User:Bnorthan 61 | bnorthan 62 | 63 | 64 | Barry DeZonia 65 | https://imagej.net/User:Bdezonia 66 | bdezonia 67 | 68 | 69 | Mark Hiner 70 | https://imagej.net/User:Hinerm 71 | hinerm 72 | 73 | 74 | Ellen Arena 75 | https://imagej.net/User:Etarena 76 | etarena 77 | 78 | 79 | Jan Eglinger 80 | https://imagej.net/User:Eglinger 81 | imagejan 82 | 83 | 84 | Aparna Pal 85 | https://imagej.net/User:Apal4 86 | apal4 87 | 88 | 89 | 90 | 91 | 92 | Image.sc Forum 93 | https://forum.image.sc/tags/imagej 94 | 95 | 96 | 97 | 98 | java/howtos 99 | java/custom-preprocessor-plugin 100 | java/execute-commands 101 | java/ij2-image-plus 102 | java/listen-to-events 103 | java/swing-example 104 | 105 | 106 | 107 | scm:git:https://github.com/imagej/tutorials 108 | scm:git:git@github.com:imagej/tutorials 109 | HEAD 110 | https://github.com/imagej/tutorials 111 | 112 | 113 | GitHub Issues 114 | http://github.com/imagej/tutorials/issues 115 | 116 | 117 | GitHub Actions 118 | https://github.com/imagej/tutorials/actions 119 | 120 | 121 | 122 | unlicense 123 | N/A 124 | ImageJ software for multidimensional image processing and analysis. 125 | 126 | 127 | sign,deploy-to-scijava 128 | 129 | 130 | 131 | 132 | scijava.public 133 | https://maven.scijava.org/content/groups/public 134 | 135 | 136 | 137 | --------------------------------------------------------------------------------