I’m using ImageJ 1.52 as a Java library. for my own Java application.
I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? The code below does what I want, but is it future safe? Also why are not all ImagePlus properties persisted? Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. /** * Adds a key-value pair to this ImagePlus's Info properties. The key is * removed from the properties table if value is null. * * @param imagePlus * @param key * @param value * @throws IOException * @see #getInfoProperties */ void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { Properties infoProperties = getInfoProperties(imagePlus); if (value == null) { infoProperties.remove(key); } else { infoProperties.setProperty(key, value); } StringWriter sw = new StringWriter(); infoProperties.store(sw, null); imagePlus.setProperty("Info", sw.toString()); } /** * Get a property from an ImagePlus's Info properties. * * @param imagePlus * @param key * @return the * @see #getInfoProperties */ String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { return getInfoProperties(imagePlus).getProperty(key); } /** * Get the specified ImagePlus's Info properties. The "Info" properties are * a list of properties nested within the ImagePlus's property indexed with * the key value "Info". ImagePlus's "Info" property is saved and restored * by the default ImagePlus save and open operations. * * @param imagePlus * @param key * @return the */ Properties getInfoProperties(ImagePlus imagePlus) throws IOException { Properties infoProps = new Properties(); infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); return infoProps; } Michael Ellis (Managing Director) Digital Scientific UK Ltd. http://www.dsuk.biz <http://www.dsuk.biz/> [hidden email] tel: +44(0)1223 911215 The Commercial Centre 6 Green End Cambridge CB23 7DY === END OF EMAIL === -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Michael
maybe an incomplete answer, but better than no answer: - I guess that the 'info' String will remain there for as long as we have ImageJ. - At least in ImageJ1, I am not aware of any convention to avoid duplicate keywords. - The reason why other ImagePlus properties are not saved is probably that (i) the lack of a mechanism to save and read them (they can be any type of object; java serialization would not guarantee that they can be read at a later stage when the code of the class changes) and (ii) one might store objects for temporary use in the properties. Michael ________________________________________________________________ On 15.04.20 15:58, Michael Ellis wrote: > I’m using ImageJ 1.52 as a Java library. for my own Java application. > > I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. > > I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) > > The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? > The code below does what I want, but is it future safe? > Also why are not all ImagePlus properties persisted? > Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? > I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. > > /** > * Adds a key-value pair to this ImagePlus's Info properties. The key is > * removed from the properties table if value is null. > * > * @param imagePlus > * @param key > * @param value > * @throws IOException > * @see #getInfoProperties > */ > void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { > Properties infoProperties = getInfoProperties(imagePlus); > if (value == null) { > infoProperties.remove(key); > } else { > infoProperties.setProperty(key, value); > } > StringWriter sw = new StringWriter(); > infoProperties.store(sw, null); > imagePlus.setProperty("Info", sw.toString()); > } > > /** > * Get a property from an ImagePlus's Info properties. > * > * @param imagePlus > * @param key > * @return the > * @see #getInfoProperties > */ > String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { > return getInfoProperties(imagePlus).getProperty(key); > } > > /** > * Get the specified ImagePlus's Info properties. The "Info" properties are > * a list of properties nested within the ImagePlus's property indexed with > * the key value "Info". ImagePlus's "Info" property is saved and restored > * by the default ImagePlus save and open operations. > * > * @param imagePlus > * @param key > * @return the > */ > Properties getInfoProperties(ImagePlus imagePlus) throws IOException { > Properties infoProps = new Properties(); > infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); > return infoProps; > } > > Michael Ellis (Managing Director) > Digital Scientific UK Ltd. > http://www.dsuk.biz <http://www.dsuk.biz/> > [hidden email] > tel: +44(0)1223 911215 > > The Commercial Centre > 6 Green End > Cambridge > CB23 7DY > > === END OF EMAIL === > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Michael,
Many thanks! Mindful of your reply, I think I will go forward with hijacking the “Info” property then, even though it seems like an awful hack. Just before I do though, is there any hope, or reason that ImageJ 1 could be enhanced to save and restore just the properties of type String? As far as I can see this would: - Have no compatibility issues. - Offer the functionality of extensible persistent properties without any API changes. - Arbitrary data could be saved as JSON or XML (as indeed the existing “Info” property does for native BioFormats OME.TIFF Would such a change be considered for inclusion, and if so how? How would I find out if it would be included if I were to implement it? ALSO I have spent a lot of time trying to use ImageJ 2. In the end I gave up, for as wonderful as it might be, it managed to confound my every attempt to work with it. - I could not make it play nice with Java 11 and modules, the worked example just do not work with Java 11 - The extensive use of advanced Java facilities confused my small brain: - Generics, Annotations, Lambda’s to a lesser extent, all feel like layer language features. To me they make what was originally a simple language ugly. Whilst these features may well offer advantages for large scale development, they also crush my creativity and imagination and rob me of the will to live when attempting to do simple things. - Maven seems like a dark art for but the simplest things, and trying to find the right dependencies sent me round in circles - there seems even less documentation that there is for ImageJ 1 I do not mean to be criticising off ImageJ2, I am sure it is amazingly good, but for the uninitiated, it was just impenetrable. I also wanted to save 5D image files easily, and started with Bio-Formats, but again have given up on that for similar reasons: huge, complex, does not play nice wit Java 11 (things like module conflicts), hence looking at ImajeJ1 to that for me. Is there a plan future plan for ImageJ1, I remember going from the NIH Image t ImageJ, and that was great. I wonder if anyone would like to take on an ImageJ rewrite in Python with an eye to the incredible promises on offer from Oracle GraalVM or any other way forward that keeps things simple, and attractive, making it seductive for scientist rather than heavy duty computer scientists? > On 15 Apr 2020, at 17:52, Michael Schmid <[hidden email]> wrote: > > Hi Michael > > maybe an incomplete answer, but better than no answer: > > - I guess that the 'info' String will remain there for as long as we have ImageJ. > - At least in ImageJ1, I am not aware of any convention to avoid duplicate keywords. > - The reason why other ImagePlus properties are not saved is probably that (i) the lack of a mechanism to save and read them (they can be any type of object; java serialization would not guarantee that they can be read at a later stage when the code of the class changes) and (ii) one might store objects for temporary use in the properties. > > > Michael > ________________________________________________________________ > On 15.04.20 15:58, Michael Ellis wrote: >> I’m using ImageJ 1.52 as a Java library. for my own Java application. >> I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. >> I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) >> The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? >> The code below does what I want, but is it future safe? >> Also why are not all ImagePlus properties persisted? >> Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? >> I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. >> /** >> * Adds a key-value pair to this ImagePlus's Info properties. The key is >> * removed from the properties table if value is null. >> * >> * @param imagePlus >> * @param key >> * @param value >> * @throws IOException >> * @see #getInfoProperties >> */ >> void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { >> Properties infoProperties = getInfoProperties(imagePlus); >> if (value == null) { >> infoProperties.remove(key); >> } else { >> infoProperties.setProperty(key, value); >> } >> StringWriter sw = new StringWriter(); >> infoProperties.store(sw, null); >> imagePlus.setProperty("Info", sw.toString()); >> } >> /** >> * Get a property from an ImagePlus's Info properties. >> * >> * @param imagePlus >> * @param key >> * @return the >> * @see #getInfoProperties >> */ >> String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { >> return getInfoProperties(imagePlus).getProperty(key); >> } >> /** >> * Get the specified ImagePlus's Info properties. The "Info" properties are >> * a list of properties nested within the ImagePlus's property indexed with >> * the key value "Info". ImagePlus's "Info" property is saved and restored >> * by the default ImagePlus save and open operations. >> * >> * @param imagePlus >> * @param key >> * @return the >> */ >> Properties getInfoProperties(ImagePlus imagePlus) throws IOException { >> Properties infoProps = new Properties(); >> infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); >> return infoProps; >> } >> Michael Ellis (Managing Director) >> Digital Scientific UK Ltd. >> http://www.dsuk.biz <http://www.dsuk.biz/> >> [hidden email] >> tel: +44(0)1223 911215 >> The Commercial Centre >> 6 Green End >> Cambridge >> CB23 7DY >> === END OF EMAIL === >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html Michael Ellis (Managing Director) Digital Scientific UK Ltd. http://www.dsuk.biz <http://www.dsuk.biz/> [hidden email] tel: +44(0)1223 911215 The Commercial Centre 6 Green End Cambridge CB23 7DY === END OF EMAIL === -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> On Apr 15, 2020, at 3:03 PM, Michael Ellis <[hidden email]> wrote:
> > Michael, > > Many thanks! > > Mindful of your reply, I think I will go forward with hijacking the “Info” property then, even though it seems like an awful hack. > > Just before I do though, is there any hope, or reason that ImageJ 1 could be enhanced to save and restore just the properties of type String? You can save and restore string properties using the “Info” property, stack slice labels and Roi properties. I do not see the need to add another way. The following Javascript demonstrates the three ways to save and restore string properties. img = IJ.createImage("Untitled", "8-bit black", 500, 500, 2); // Info properties img.setProperty("Info", "key1=Info prop 1\nkey2=Info prop 2"); // slice properties stack = img.getStack(); stack.setSliceLabel("Label 1", 1); stack.setSliceLabel("Label 2", 2); // roi properties roi = new Roi(0,0,10,10); roi.setProperty("roi1", "Property 1"); roi.setProperty("roi2", "Property 2"); img.setRoi(roi); path = IJ.getDir("home")+"Downloads/Untitled.tif"; IJ.saveAs(img, "Tiff", path); img2 = IJ.openImage(path); print("Info/key1: "+img2.getStringProperty("key1")); print("Info/key2: "+img2.getStringProperty("key2")); stack2 = img2.getStack(); print("Slice label 1: "+stack2.getSliceLabel(1)); print("Slice label 2: "+stack2.getSliceLabel(2)); roi2 = img2.getRoi(); print("ROI property 1: "+roi2.getProperty("roi1")); print("ROI property 2: "+roi2.getProperty("roi2")); This is the output: Info/key1: Info prop 1 Info/key2: Info prop 2 Slice label 1: Label 1 Slice label 2: Label 2 ROI property 1: Property 1 ROI property 2: Property 2 > > As far as I can see this would: > > - Have no compatibility issues. > - Offer the functionality of extensible persistent properties without any API changes. > - Arbitrary data could be saved as JSON or XML (as indeed the existing “Info” property does for native BioFormats OME.TIFF > > Would such a change be considered for inclusion, and if so how? > How would I find out if it would be included if I were to implement it? > > ALSO > > I have spent a lot of time trying to use ImageJ 2. In the end I gave up, for as wonderful as it might be, it managed to confound my every attempt to work with it. > > - I could not make it play nice with Java 11 and modules, the worked example just do not work with Java 11 > - The extensive use of advanced Java facilities confused my small brain: > - Generics, Annotations, Lambda’s to a lesser extent, all feel like layer language features. To me they make what was originally a simple language ugly. Whilst these features may well offer advantages for large scale development, they also crush my creativity and imagination and rob me of the will to live when attempting to do simple things. > - Maven seems like a dark art for but the simplest things, and trying to find the right dependencies sent me round in circles > - there seems even less documentation that there is for ImageJ 1 > > I do not mean to be criticising off ImageJ2, I am sure it is amazingly good, but for the uninitiated, it was just impenetrable. > > I also wanted to save 5D image files easily, and started with Bio-Formats, but again have given up on that for similar reasons: huge, complex, does not play nice wit Java 11 (things like module conflicts), hence looking at ImajeJ1 to that for me. > > Is there a plan future plan for ImageJ1, I remember going from the NIH Image t ImageJ, and that was great. I wonder if anyone would like to take on an ImageJ rewrite in Python with an eye to the incredible promises on offer from Oracle GraalVM or any other way forward that keeps things simple, and attractive, making it seductive for scientist rather than heavy duty computer scientists? > > > >> On 15 Apr 2020, at 17:52, Michael Schmid <[hidden email]> wrote: >> >> Hi Michael >> >> maybe an incomplete answer, but better than no answer: >> >> - I guess that the 'info' String will remain there for as long as we have ImageJ. >> - At least in ImageJ1, I am not aware of any convention to avoid duplicate keywords. >> - The reason why other ImagePlus properties are not saved is probably that (i) the lack of a mechanism to save and read them (they can be any type of object; java serialization would not guarantee that they can be read at a later stage when the code of the class changes) and (ii) one might store objects for temporary use in the properties. >> >> >> Michael >> ________________________________________________________________ >> On 15.04.20 15:58, Michael Ellis wrote: >>> I’m using ImageJ 1.52 as a Java library. for my own Java application. >>> I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. >>> I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) >>> The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? >>> The code below does what I want, but is it future safe? >>> Also why are not all ImagePlus properties persisted? >>> Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? >>> I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. >>> /** >>> * Adds a key-value pair to this ImagePlus's Info properties. The key is >>> * removed from the properties table if value is null. >>> * >>> * @param imagePlus >>> * @param key >>> * @param value >>> * @throws IOException >>> * @see #getInfoProperties >>> */ >>> void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { >>> Properties infoProperties = getInfoProperties(imagePlus); >>> if (value == null) { >>> infoProperties.remove(key); >>> } else { >>> infoProperties.setProperty(key, value); >>> } >>> StringWriter sw = new StringWriter(); >>> infoProperties.store(sw, null); >>> imagePlus.setProperty("Info", sw.toString()); >>> } >>> /** >>> * Get a property from an ImagePlus's Info properties. >>> * >>> * @param imagePlus >>> * @param key >>> * @return the >>> * @see #getInfoProperties >>> */ >>> String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { >>> return getInfoProperties(imagePlus).getProperty(key); >>> } >>> /** >>> * Get the specified ImagePlus's Info properties. The "Info" properties are >>> * a list of properties nested within the ImagePlus's property indexed with >>> * the key value "Info". ImagePlus's "Info" property is saved and restored >>> * by the default ImagePlus save and open operations. >>> * >>> * @param imagePlus >>> * @param key >>> * @return the >>> */ >>> Properties getInfoProperties(ImagePlus imagePlus) throws IOException { >>> Properties infoProps = new Properties(); >>> infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); >>> return infoProps; >>> } >>> Michael Ellis (Managing Director) >>> Digital Scientific UK Ltd. >>> http://www.dsuk.biz <http://www.dsuk.biz/> >>> [hidden email] >>> tel: +44(0)1223 911215 >>> The Commercial Centre >>> 6 Green End >>> Cambridge >>> CB23 7DY >>> === END OF EMAIL === >>> -- >>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > Michael Ellis (Managing Director) > Digital Scientific UK Ltd. > http://www.dsuk.biz <http://www.dsuk.biz/> > [hidden email] > tel: +44(0)1223 911215 > > The Commercial Centre > 6 Green End > Cambridge > CB23 7DY > > === END OF EMAIL === > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Wayne,
Thank you very much for your reply. I shall contibue with my approach to hijacking the Info property and hopefully I’ll not fall foul of other ImageJ plugins overwriting the properties I have placed there. > On 16 Apr 2020, at 02:38, Wayne Rasband <[hidden email]> wrote: > >> On Apr 15, 2020, at 3:03 PM, Michael Ellis <[hidden email]> wrote: >> >> Michael, >> >> Many thanks! >> >> Mindful of your reply, I think I will go forward with hijacking the “Info” property then, even though it seems like an awful hack. >> >> Just before I do though, is there any hope, or reason that ImageJ 1 could be enhanced to save and restore just the properties of type String? > > You can save and restore string properties using the “Info” property, stack slice labels and Roi properties. I do not see the need to add another way. The following Javascript demonstrates the three ways to save and restore string properties. > > img = IJ.createImage("Untitled", "8-bit black", 500, 500, 2); > // Info properties > img.setProperty("Info", "key1=Info prop 1\nkey2=Info prop 2"); > // slice properties > stack = img.getStack(); > stack.setSliceLabel("Label 1", 1); > stack.setSliceLabel("Label 2", 2); > // roi properties > roi = new Roi(0,0,10,10); > roi.setProperty("roi1", "Property 1"); > roi.setProperty("roi2", "Property 2"); > img.setRoi(roi); > path = IJ.getDir("home")+"Downloads/Untitled.tif"; > IJ.saveAs(img, "Tiff", path); > img2 = IJ.openImage(path); > print("Info/key1: "+img2.getStringProperty("key1")); > print("Info/key2: "+img2.getStringProperty("key2")); > stack2 = img2.getStack(); > print("Slice label 1: "+stack2.getSliceLabel(1)); > print("Slice label 2: "+stack2.getSliceLabel(2)); > roi2 = img2.getRoi(); > print("ROI property 1: "+roi2.getProperty("roi1")); > print("ROI property 2: "+roi2.getProperty("roi2")); > > This is the output: > > Info/key1: Info prop 1 > Info/key2: Info prop 2 > Slice label 1: Label 1 > Slice label 2: Label 2 > ROI property 1: Property 1 > ROI property 2: Property 2 > > > >> >> As far as I can see this would: >> >> - Have no compatibility issues. >> - Offer the functionality of extensible persistent properties without any API changes. >> - Arbitrary data could be saved as JSON or XML (as indeed the existing “Info” property does for native BioFormats OME.TIFF >> >> Would such a change be considered for inclusion, and if so how? >> How would I find out if it would be included if I were to implement it? >> >> ALSO >> >> I have spent a lot of time trying to use ImageJ 2. In the end I gave up, for as wonderful as it might be, it managed to confound my every attempt to work with it. >> >> - I could not make it play nice with Java 11 and modules, the worked example just do not work with Java 11 >> - The extensive use of advanced Java facilities confused my small brain: >> - Generics, Annotations, Lambda’s to a lesser extent, all feel like layer language features. To me they make what was originally a simple language ugly. Whilst these features may well offer advantages for large scale development, they also crush my creativity and imagination and rob me of the will to live when attempting to do simple things. >> - Maven seems like a dark art for but the simplest things, and trying to find the right dependencies sent me round in circles >> - there seems even less documentation that there is for ImageJ 1 >> >> I do not mean to be criticising off ImageJ2, I am sure it is amazingly good, but for the uninitiated, it was just impenetrable. >> >> I also wanted to save 5D image files easily, and started with Bio-Formats, but again have given up on that for similar reasons: huge, complex, does not play nice wit Java 11 (things like module conflicts), hence looking at ImajeJ1 to that for me. >> >> Is there a plan future plan for ImageJ1, I remember going from the NIH Image t ImageJ, and that was great. I wonder if anyone would like to take on an ImageJ rewrite in Python with an eye to the incredible promises on offer from Oracle GraalVM or any other way forward that keeps things simple, and attractive, making it seductive for scientist rather than heavy duty computer scientists? >> >> >> >>> On 15 Apr 2020, at 17:52, Michael Schmid <[hidden email]> wrote: >>> >>> Hi Michael >>> >>> maybe an incomplete answer, but better than no answer: >>> >>> - I guess that the 'info' String will remain there for as long as we have ImageJ. >>> - At least in ImageJ1, I am not aware of any convention to avoid duplicate keywords. >>> - The reason why other ImagePlus properties are not saved is probably that (i) the lack of a mechanism to save and read them (they can be any type of object; java serialization would not guarantee that they can be read at a later stage when the code of the class changes) and (ii) one might store objects for temporary use in the properties. >>> >>> >>> Michael >>> ________________________________________________________________ >>> On 15.04.20 15:58, Michael Ellis wrote: >>>> I’m using ImageJ 1.52 as a Java library. for my own Java application. >>>> I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. >>>> I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) >>>> The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? >>>> The code below does what I want, but is it future safe? >>>> Also why are not all ImagePlus properties persisted? >>>> Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? >>>> I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. >>>> /** >>>> * Adds a key-value pair to this ImagePlus's Info properties. The key is >>>> * removed from the properties table if value is null. >>>> * >>>> * @param imagePlus >>>> * @param key >>>> * @param value >>>> * @throws IOException >>>> * @see #getInfoProperties >>>> */ >>>> void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { >>>> Properties infoProperties = getInfoProperties(imagePlus); >>>> if (value == null) { >>>> infoProperties.remove(key); >>>> } else { >>>> infoProperties.setProperty(key, value); >>>> } >>>> StringWriter sw = new StringWriter(); >>>> infoProperties.store(sw, null); >>>> imagePlus.setProperty("Info", sw.toString()); >>>> } >>>> /** >>>> * Get a property from an ImagePlus's Info properties. >>>> * >>>> * @param imagePlus >>>> * @param key >>>> * @return the >>>> * @see #getInfoProperties >>>> */ >>>> String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { >>>> return getInfoProperties(imagePlus).getProperty(key); >>>> } >>>> /** >>>> * Get the specified ImagePlus's Info properties. The "Info" properties are >>>> * a list of properties nested within the ImagePlus's property indexed with >>>> * the key value "Info". ImagePlus's "Info" property is saved and restored >>>> * by the default ImagePlus save and open operations. >>>> * >>>> * @param imagePlus >>>> * @param key >>>> * @return the >>>> */ >>>> Properties getInfoProperties(ImagePlus imagePlus) throws IOException { >>>> Properties infoProps = new Properties(); >>>> infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); >>>> return infoProps; >>>> } >>>> Michael Ellis (Managing Director) >>>> Digital Scientific UK Ltd. >>>> http://www.dsuk.biz <http://www.dsuk.biz/> >>>> [hidden email] >>>> tel: +44(0)1223 911215 >>>> The Commercial Centre >>>> 6 Green End >>>> Cambridge >>>> CB23 7DY >>>> === END OF EMAIL === >>>> -- >>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >>> >>> -- >>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> >> Michael Ellis (Managing Director) >> Digital Scientific UK Ltd. >> http://www.dsuk.biz <http://www.dsuk.biz/> >> [hidden email] >> tel: +44(0)1223 911215 >> >> The Commercial Centre >> 6 Green End >> Cambridge >> CB23 7DY >> >> === END OF EMAIL === >> >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html Michael Ellis (Managing Director) Digital Scientific UK Ltd. http://www.dsuk.biz <http://www.dsuk.biz/> [hidden email] tel: +44(0)1223 911215 The Commercial Centre 6 Green End Cambridge CB23 7DY === END OF EMAIL === -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael P Ellis
> On Apr 15, 2020, at 3:03 PM, Michael Ellis <[hidden email]> wrote:
> > Michael, > > Many thanks! > > Mindful of your reply, I think I will go forward with hijacking the “Info” property then, even though it seems like an awful hack. > > Just before I do though, is there any hope, or reason that ImageJ 1 could be enhanced to save and restore just the properties of type String? The ImageJ 1.53a3 daily build adds setProp() and getProp() methods for saving and restoring string properties. The following JavaScript demonstrates how to use these new methods. Since they only work with strings, it also shows how to encode non-string objects, such images, into strings. -wayne img = IJ.createImage("Untitled", "8-bit black", 500, 500, 3); clown = IJ.openImage("http://wsr.imagej.net/images/clown.jpg"); bytes = new FileSaver(clown).serialize(); string = Base64.getEncoder().encodeToString(bytes); img.setProp("clown", string); text = "Clown.jpg was serialized, set as an image\n" + "property, the image was saved, re-opened,\n" + "and clown.jpg was deserialized and displayed."; img.setProp("text", text); path = IJ.getDir("home")+"Downloads/Untitled.tif"; IJ.saveAs(img, "Tiff", path); img2 = IJ.openImage(path); string2 = img2.getProp("clown"); bytes2 = Base64.getDecoder().decode(string2); clown2 = new Opener().deserialize(bytes2); clown2.show(); IJ.showMessage(img2.getProp("text")); > As far as I can see this would: > > - Have no compatibility issues. > - Offer the functionality of extensible persistent properties without any API changes. > - Arbitrary data could be saved as JSON or XML (as indeed the existing “Info” property does for native BioFormats OME.TIFF > > Would such a change be considered for inclusion, and if so how? > How would I find out if it would be included if I were to implement it? > > ALSO > > I have spent a lot of time trying to use ImageJ 2. In the end I gave up, for as wonderful as it might be, it managed to confound my every attempt to work with it. > > - I could not make it play nice with Java 11 and modules, the worked example just do not work with Java 11 > - The extensive use of advanced Java facilities confused my small brain: > - Generics, Annotations, Lambda’s to a lesser extent, all feel like layer language features. To me they make what was originally a simple language ugly. Whilst these features may well offer advantages for large scale development, they also crush my creativity and imagination and rob me of the will to live when attempting to do simple things. > - Maven seems like a dark art for but the simplest things, and trying to find the right dependencies sent me round in circles > - there seems even less documentation that there is for ImageJ 1 > > I do not mean to be criticising off ImageJ2, I am sure it is amazingly good, but for the uninitiated, it was just impenetrable. > > I also wanted to save 5D image files easily, and started with Bio-Formats, but again have given up on that for similar reasons: huge, complex, does not play nice wit Java 11 (things like module conflicts), hence looking at ImajeJ1 to that for me. > > Is there a plan future plan for ImageJ1, I remember going from the NIH Image t ImageJ, and that was great. I wonder if anyone would like to take on an ImageJ rewrite in Python with an eye to the incredible promises on offer from Oracle GraalVM or any other way forward that keeps things simple, and attractive, making it seductive for scientist rather than heavy duty computer scientists? > > > >> On 15 Apr 2020, at 17:52, Michael Schmid <[hidden email]> wrote: >> >> Hi Michael >> >> maybe an incomplete answer, but better than no answer: >> >> - I guess that the 'info' String will remain there for as long as we have ImageJ. >> - At least in ImageJ1, I am not aware of any convention to avoid duplicate keywords. >> - The reason why other ImagePlus properties are not saved is probably that (i) the lack of a mechanism to save and read them (they can be any type of object; java serialization would not guarantee that they can be read at a later stage when the code of the class changes) and (ii) one might store objects for temporary use in the properties. >> >> >> Michael >> ________________________________________________________________ >> On 15.04.20 15:58, Michael Ellis wrote: >>> I’m using ImageJ 1.52 as a Java library. for my own Java application. >>> I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. >>> I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) >>> The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? >>> The code below does what I want, but is it future safe? >>> Also why are not all ImagePlus properties persisted? >>> Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? >>> I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. >>> /** >>> * Adds a key-value pair to this ImagePlus's Info properties. The key is >>> * removed from the properties table if value is null. >>> * >>> * @param imagePlus >>> * @param key >>> * @param value >>> * @throws IOException >>> * @see #getInfoProperties >>> */ >>> void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { >>> Properties infoProperties = getInfoProperties(imagePlus); >>> if (value == null) { >>> infoProperties.remove(key); >>> } else { >>> infoProperties.setProperty(key, value); >>> } >>> StringWriter sw = new StringWriter(); >>> infoProperties.store(sw, null); >>> imagePlus.setProperty("Info", sw.toString()); >>> } >>> /** >>> * Get a property from an ImagePlus's Info properties. >>> * >>> * @param imagePlus >>> * @param key >>> * @return the >>> * @see #getInfoProperties >>> */ >>> String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { >>> return getInfoProperties(imagePlus).getProperty(key); >>> } >>> /** >>> * Get the specified ImagePlus's Info properties. The "Info" properties are >>> * a list of properties nested within the ImagePlus's property indexed with >>> * the key value "Info". ImagePlus's "Info" property is saved and restored >>> * by the default ImagePlus save and open operations. >>> * >>> * @param imagePlus >>> * @param key >>> * @return the >>> */ >>> Properties getInfoProperties(ImagePlus imagePlus) throws IOException { >>> Properties infoProps = new Properties(); >>> infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); >>> return infoProps; >>> } -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Wow! That has to go above and beyond the call of duty.
Wayne, thank you so much! Keep well and safe in these trying times. Regards — Michael Ellis > On 17 Apr 2020, at 18:07, Wayne Rasband <[hidden email]> wrote: > >> On Apr 15, 2020, at 3:03 PM, Michael Ellis <[hidden email]> wrote: >> >> Michael, >> >> Many thanks! >> >> Mindful of your reply, I think I will go forward with hijacking the “Info” property then, even though it seems like an awful hack. >> >> Just before I do though, is there any hope, or reason that ImageJ 1 could be enhanced to save and restore just the properties of type String? > > The ImageJ 1.53a3 daily build adds setProp() and getProp() methods for saving and restoring string properties. The following JavaScript demonstrates how to use these new methods. Since they only work with strings, it also shows how to encode non-string objects, such images, into strings. > > -wayne > > img = IJ.createImage("Untitled", "8-bit black", 500, 500, 3); > clown = IJ.openImage("http://wsr.imagej.net/images/clown.jpg"); > bytes = new FileSaver(clown).serialize(); > string = Base64.getEncoder().encodeToString(bytes); > img.setProp("clown", string); > text = "Clown.jpg was serialized, set as an image\n" > + "property, the image was saved, re-opened,\n" > + "and clown.jpg was deserialized and displayed."; > img.setProp("text", text); > path = IJ.getDir("home")+"Downloads/Untitled.tif"; > IJ.saveAs(img, "Tiff", path); > img2 = IJ.openImage(path); > string2 = img2.getProp("clown"); > bytes2 = Base64.getDecoder().decode(string2); > clown2 = new Opener().deserialize(bytes2); > clown2.show(); > IJ.showMessage(img2.getProp("text")); > > >> As far as I can see this would: >> >> - Have no compatibility issues. >> - Offer the functionality of extensible persistent properties without any API changes. >> - Arbitrary data could be saved as JSON or XML (as indeed the existing “Info” property does for native BioFormats OME.TIFF >> >> Would such a change be considered for inclusion, and if so how? >> How would I find out if it would be included if I were to implement it? >> >> ALSO >> >> I have spent a lot of time trying to use ImageJ 2. In the end I gave up, for as wonderful as it might be, it managed to confound my every attempt to work with it. >> >> - I could not make it play nice with Java 11 and modules, the worked example just do not work with Java 11 >> - The extensive use of advanced Java facilities confused my small brain: >> - Generics, Annotations, Lambda’s to a lesser extent, all feel like layer language features. To me they make what was originally a simple language ugly. Whilst these features may well offer advantages for large scale development, they also crush my creativity and imagination and rob me of the will to live when attempting to do simple things. >> - Maven seems like a dark art for but the simplest things, and trying to find the right dependencies sent me round in circles >> - there seems even less documentation that there is for ImageJ 1 >> >> I do not mean to be criticising off ImageJ2, I am sure it is amazingly good, but for the uninitiated, it was just impenetrable. >> >> I also wanted to save 5D image files easily, and started with Bio-Formats, but again have given up on that for similar reasons: huge, complex, does not play nice wit Java 11 (things like module conflicts), hence looking at ImajeJ1 to that for me. >> >> Is there a plan future plan for ImageJ1, I remember going from the NIH Image t ImageJ, and that was great. I wonder if anyone would like to take on an ImageJ rewrite in Python with an eye to the incredible promises on offer from Oracle GraalVM or any other way forward that keeps things simple, and attractive, making it seductive for scientist rather than heavy duty computer scientists? >> >> >> >>> On 15 Apr 2020, at 17:52, Michael Schmid <[hidden email]> wrote: >>> >>> Hi Michael >>> >>> maybe an incomplete answer, but better than no answer: >>> >>> - I guess that the 'info' String will remain there for as long as we have ImageJ. >>> - At least in ImageJ1, I am not aware of any convention to avoid duplicate keywords. >>> - The reason why other ImagePlus properties are not saved is probably that (i) the lack of a mechanism to save and read them (they can be any type of object; java serialization would not guarantee that they can be read at a later stage when the code of the class changes) and (ii) one might store objects for temporary use in the properties. >>> >>> >>> Michael >>> ________________________________________________________________ >>> On 15.04.20 15:58, Michael Ellis wrote: >>>> I’m using ImageJ 1.52 as a Java library. for my own Java application. >>>> I create images that are to be saved and restored. I want to attach extra information to an ImagePlus that will be persisted and restored using the standard ImageJ open and save operations. >>>> I’ve discovered that only some specific ImagePlus properties are persisted with the default ImageJ file operations (such as the “Info” property) >>>> The “Info”, appears itself to be a string formatted in a manor that is itself a list of properties. Can I safely append more (sub) properties to this “Info” property and expect them to be safel honoured by future versions of ImageJ 1.xx? >>>> The code below does what I want, but is it future safe? >>>> Also why are not all ImagePlus properties persisted? >>>> Is there some other mechanism for save augmenting an Image in ImageJ with extensible metadata that I am missing? >>>> I intend to add my extra properties with a reverse domain name notation key to avoid accidental clashes. >>>> /** >>>> * Adds a key-value pair to this ImagePlus's Info properties. The key is >>>> * removed from the properties table if value is null. >>>> * >>>> * @param imagePlus >>>> * @param key >>>> * @param value >>>> * @throws IOException >>>> * @see #getInfoProperties >>>> */ >>>> void setInfoProperty(ImagePlus imagePlus, String key, String value) throws IOException { >>>> Properties infoProperties = getInfoProperties(imagePlus); >>>> if (value == null) { >>>> infoProperties.remove(key); >>>> } else { >>>> infoProperties.setProperty(key, value); >>>> } >>>> StringWriter sw = new StringWriter(); >>>> infoProperties.store(sw, null); >>>> imagePlus.setProperty("Info", sw.toString()); >>>> } >>>> /** >>>> * Get a property from an ImagePlus's Info properties. >>>> * >>>> * @param imagePlus >>>> * @param key >>>> * @return the >>>> * @see #getInfoProperties >>>> */ >>>> String getInfoProperty(ImagePlus imagePlus, String key) throws IOException { >>>> return getInfoProperties(imagePlus).getProperty(key); >>>> } >>>> /** >>>> * Get the specified ImagePlus's Info properties. The "Info" properties are >>>> * a list of properties nested within the ImagePlus's property indexed with >>>> * the key value "Info". ImagePlus's "Info" property is saved and restored >>>> * by the default ImagePlus save and open operations. >>>> * >>>> * @param imagePlus >>>> * @param key >>>> * @return the >>>> */ >>>> Properties getInfoProperties(ImagePlus imagePlus) throws IOException { >>>> Properties infoProps = new Properties(); >>>> infoProps.load(new StringReader((String) imagePlus.getProperty("Info"))); >>>> return infoProps; >>>> } > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html Michael Ellis (Managing Director) Digital Scientific UK Ltd. http://www.dsuk.biz <http://www.dsuk.biz/> [hidden email] tel: +44(0)1223 911215 The Commercial Centre 6 Green End Cambridge CB23 7DY === END OF EMAIL === -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
This morning whilst walking the dog around the bay I stopped to stare into the sea, as I often do. It's so hypnotically beautiful. Here it is: http://ellisnet.uk/Rants/Water1080p.mov
Then I started to wonder. Is there an image processor that can remove the distorting effect of the water such that it produces an image of the sea bed as if the water were not there? Has this been done? The distortion has some randomness to it, but it's not totally random. I'm thinking that at any given instance t, every point source p(x, y) on the seabed undergoes a geometrical affine transform, but there are probably limits to what these transforms might be - translation looks to be the most significant - magnification - less so? - rotation - none? - skew ? Also whilst the ripples on the surface of the water don't break I assume: - The transformational effects of neighbouring points are similar. - The transformation effects for temporal neighbours are similar. Also there seems the lens affect of a waves produce a pattern of sharp bright edges on the seabed floor, but perhaps by virtue of being bright they could be threesholded out before feeding into an algoroithm to reverese the optical deformation. I have no idea if this could be of any use for anything. I have noo idea how to solved it. But it struck me as interesting and would remarkable cool to see. Happy Easter all or Χριστός Ανέστη (for my Greek friends) Michael Ellis (Managing Director) Digital Scientific UK Ltd. http://www.dsuk.biz <http://www.dsuk.biz/> [hidden email] tel: +44(0)1223 911215 The Commercial Centre 6 Green End Cambridge CB23 7DY === END OF EMAIL === -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> This morning whilst walking the dog around the bay I stopped to stare into
> the sea, as I often do. It's so hypnotically beautiful. > Here it is: http://ellisnet.uk/Rants/Water1080p.mov > Then I started to wonder. Is there an image processor that can remove the > distorting effect of the water such that it produces an image of the sea bed > as if the water were not there? Hi, Interesting question. It sounds similar to what astronomers do with adaptive optics/mirrors to get rid of the effects of observing through atmospheric turbulence. I wonder if by doing an average projection of the (registered) stack on a long enough sequence, could minimise the flucutations a bit. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Indeed, this is exactly what astronomers try to do, but with a big difference: they (usually) know that the underlying thing they're trying to image is something simple - usually a point source or several point sources. This makes the problem mathematically MUCH simpler. If you're trying to un-distort a complex image, there's still a method, but it's extremely complex, mathematically.
If you assume that the image is distorted by shifting alone - probably not too bad an approximation - you can use the a simple shift-and-add algorithm suggested by Gabriel. Amateur astronomer make fantastically detailed images of planets using video cameras on small telescopes using this assumption (after throwing out most of the images that are badly distorted). Here, you want to do much larger images, so for each sub-image (must be on a scale that is larger than the distortion variations in your image, here the wavelength of the waves), measure the 2-D shift of each image relative to an average image, correct for the shift, and then co-add. In order to combine the sub-images, you may have to dither by using overlapping sub-images. One effect you can't easily remove using this method is the presence of the dark and light bands, cause by the refraction of the sun's light by the waves themselves. Rick > On 19 Apr 2020, at 12:43, Gabriel Landini <[hidden email]> wrote: > >> This morning whilst walking the dog around the bay I stopped to stare into >> the sea, as I often do. It's so hypnotically beautiful. >> Here it is: http://ellisnet.uk/Rants/Water1080p.mov >> Then I started to wonder. Is there an image processor that can remove the >> distorting effect of the water such that it produces an image of the sea bed >> as if the water were not there? > > Hi, Interesting question. It sounds similar to what astronomers do with > adaptive optics/mirrors to get rid of the effects of observing through > atmospheric turbulence. > > I wonder if by doing an average projection of the (registered) stack on a long > enough sequence, could minimise the flucutations a bit. > > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael P Ellis
Hi Michael,
> I have spent a lot of time trying to use ImageJ 2. In the end I gave > up, for as wonderful as it might be, it managed to confound my every > attempt to work with it. You are not alone. > - I could not make it play nice with Java 11 and modules, the > worked example just do not work with Java 11 As mentioned in the other thread about this [1], JPMS modularization is non-trivial. It will be awhile before ImageJ2 fully works on the module path. But we did recently start working on it. In the meantime: all the libraries should work with Java 11 on the classpath, same as with Java 8. I advise you to stay away from the module path for now for large projects, since you will get stuck whenever one of your dependencies hasn't been JPMS modularized. > - The extensive use of advanced Java facilities confused my small brain: > - Generics, Annotations, Lambda’s to a lesser extent, all feel like > layer language features. To me they make what was originally a > simple language ugly. Whilst these features may well offer > advantages for large scale development, they also crush my > creativity and imagination and rob me of the will to live when > attempting to do simple things. Might I suggest you learn Python? The scientific community has migrated en masse, with many finding it more productive and more accessible than Java. Personally I love Java, but I acknowledge that Python is much simpler to learn and use than Java ever will be. > - Maven seems like a dark art for but the simplest things, and trying > to find the right dependencies sent me round in circles Dependency management can be tricky, but Maven does it very well. If you are stuck with Maven-related issues, I'd be happy to help troubleshoot if you post about it on forum.image.sc. That said, ImageJ1 is a single-module project with no explicit dependencies, which is one surefire way to keep things super simple. > - there seems even less documentation that there is for ImageJ 1 More detailed feedback on this would be helpful. What did you go looking for, what couldn't you find, what was too hard to understand, etc. We have poured many hours into documenting ImageJ2, but I still frequently hear complaints like this from people. Can you please be more specific. > I do not mean to be criticising off ImageJ2, I am sure it is amazingly > good, but for the uninitiated, it was just impenetrable. If you can recall which concepts really threw you, which parts of the design you found displeasing or too difficult, that feedback is helpful. We are just starting on the next major iteration of the design ("ImageJ3" if you will, although not a total from-scratch rewrite), and it would be good to know where to focus our efforts to improve the system. > I also wanted to save 5D image files easily, and started with > Bio-Formats, but again have given up on that for similar reasons: > huge, complex, does not play nice wit Java 11 (things like module > conflicts), hence looking at ImajeJ1 to that for me. That's fine, as long as ImageJ1 supports the formats you need. And if you need support for a format provided by Bio-Formats, I suggest you post about it on forum.image.sc with the bio-formats tag. > Is there a plan future plan for ImageJ1, I remember going from the NIH > Image t ImageJ, and that was great. I wonder if anyone would like to > take on an ImageJ rewrite in Python with an eye to the incredible > promises on offer from Oracle GraalVM or any other way forward that > keeps things simple, and attractive, making it seductive for scientist > rather than heavy duty computer scientists? Yes, someone did do a Python rewrite: https://github.com/Image-Py/imagepy ImagePy is a partner on the Image.sc Forum; see https://forum.image.sc/tag/imagepy There is also napari, an attempt to create a nice image viewer on top of the PyData stack (NumPy/SciPy/etc.): https://napari.org/ Tangentially, there is also PyImageJ, which enables access to ImageJ's API from Python: https://github.com/imagej/pyimagej Including headless access to some parts of ImageJ1 that normally do not work headless. But of course PyImageJ is not a GUI. Relatedly: I made a couple of posts about combining PyImageJ with napari [2, 3]. As for GraalVM: I am super enthusiastic about it, and plan to research shipping Fiji with it. Then we can start benefiting from its polyglot API, so that ImageJ scripts become much faster thanks to GraalVM's polyglot Just-in-Time compilation. But use of GraalVM strikes me as an orthogonal concern to keeping the design simple. If you have additional feedback or questions about ImageJ2, please post about it on forum.image.sc as a new topic. That is ImageJ2's official support channel, and most of the people who can help you best with it are there. Regards, Curtis [1] http://imagej.1557.x6.nabble.com/changing-the-LUT-alters-the-display-range-tt5023190.html#a5023193 [2] https://forum.image.sc/t/read-images-with-imagej-display-them-with-napari/32156 [3] https://forum.image.sc/t/displaying-imagej-and-napari-ui-simultaneously/32187 -- Curtis Rueden Software architect, LOCI/Eliceiri lab - https://loci.wisc.edu/software ImageJ2 lead, Fiji maintainer - https://imagej.net/User:Rueden Have you tried the Image.sc Forum? https://forum.image.sc/ On Wed, Apr 15, 2020 at 2:05 PM Michael Ellis <[hidden email]> wrote: > Michael, > > Many thanks! > > Mindful of your reply, I think I will go forward with hijacking the “Info” > property then, even though it seems like an awful hack. > > Just before I do though, is there any hope, or reason that ImageJ 1 could > be enhanced to save and restore just the properties of type String? > > As far as I can see this would: > > - Have no compatibility issues. > - Offer the functionality of extensible persistent properties without > any API changes. > - Arbitrary data could be saved as JSON or XML (as indeed the existing > “Info” property does for native BioFormats OME.TIFF > > Would such a change be considered for inclusion, and if so how? > How would I find out if it would be included if I were to implement it? > > ALSO > > I have spent a lot of time trying to use ImageJ 2. In the end I gave up, > for as wonderful as it might be, it managed to confound my every attempt to > work with it. > > - I could not make it play nice with Java 11 and modules, the worked > example just do not work with Java 11 > - The extensive use of advanced Java facilities confused my small brain: > - Generics, Annotations, Lambda’s to a lesser extent, all feel like > layer language features. To me they make what was originally a simple > language ugly. Whilst these features may well offer advantages for large > scale development, they also crush my creativity and imagination and rob me > of the will to live when attempting to do simple things. > - Maven seems like a dark art for but the simplest things, and trying > to find the right dependencies sent me round in circles > - there seems even less documentation that there is for ImageJ 1 > > I do not mean to be criticising off ImageJ2, I am sure it is amazingly > good, but for the uninitiated, it was just impenetrable. > > I also wanted to save 5D image files easily, and started with Bio-Formats, > but again have given up on that for similar reasons: huge, complex, does > not play nice wit Java 11 (things like module conflicts), hence looking at > ImajeJ1 to that for me. > > Is there a plan future plan for ImageJ1, I remember going from the NIH > Image t ImageJ, and that was great. I wonder if anyone would like to take > on an ImageJ rewrite in Python with an eye to the incredible promises on > offer from Oracle GraalVM or any other way forward that keeps things > simple, and attractive, making it seductive for scientist rather than heavy > duty computer scientists? > > > > > On 15 Apr 2020, at 17:52, Michael Schmid <[hidden email]> > wrote: > > > > Hi Michael > > > > maybe an incomplete answer, but better than no answer: > > > > - I guess that the 'info' String will remain there for as long as we > have ImageJ. > > - At least in ImageJ1, I am not aware of any convention to avoid > duplicate keywords. > > - The reason why other ImagePlus properties are not saved is probably > that (i) the lack of a mechanism to save and read them (they can be any > type of object; java serialization would not guarantee that they can be > read at a later stage when the code of the class changes) and (ii) one > might store objects for temporary use in the properties. > > > > > > Michael > > ________________________________________________________________ > > On 15.04.20 15:58, Michael Ellis wrote: > >> I’m using ImageJ 1.52 as a Java library. for my own Java application. > >> I create images that are to be saved and restored. I want to attach > extra information to an ImagePlus that will be persisted and restored using > the standard ImageJ open and save operations. > >> I’ve discovered that only some specific ImagePlus properties are > persisted with the default ImageJ file operations (such as the “Info” > property) > >> The “Info”, appears itself to be a string formatted in a manor that is > itself a list of properties. Can I safely append more (sub) properties to > this “Info” property and expect them to be safel honoured by future > versions of ImageJ 1.xx? > >> The code below does what I want, but is it future safe? > >> Also why are not all ImagePlus properties persisted? > >> Is there some other mechanism for save augmenting an Image in ImageJ > with extensible metadata that I am missing? > >> I intend to add my extra properties with a reverse domain name notation > key to avoid accidental clashes. > >> /** > >> * Adds a key-value pair to this ImagePlus's Info properties. The > key is > >> * removed from the properties table if value is null. > >> * > >> * @param imagePlus > >> * @param key > >> * @param value > >> * @throws IOException > >> * @see #getInfoProperties > >> */ > >> void setInfoProperty(ImagePlus imagePlus, String key, String value) > throws IOException { > >> Properties infoProperties = getInfoProperties(imagePlus); > >> if (value == null) { > >> infoProperties.remove(key); > >> } else { > >> infoProperties.setProperty(key, value); > >> } > >> StringWriter sw = new StringWriter(); > >> infoProperties.store(sw, null); > >> imagePlus.setProperty("Info", sw.toString()); > >> } > >> /** > >> * Get a property from an ImagePlus's Info properties. > >> * > >> * @param imagePlus > >> * @param key > >> * @return the > >> * @see #getInfoProperties > >> */ > >> String getInfoProperty(ImagePlus imagePlus, String key) throws > IOException { > >> return getInfoProperties(imagePlus).getProperty(key); > >> } > >> /** > >> * Get the specified ImagePlus's Info properties. The "Info" > properties are > >> * a list of properties nested within the ImagePlus's property > indexed with > >> * the key value "Info". ImagePlus's "Info" property is saved and > restored > >> * by the default ImagePlus save and open operations. > >> * > >> * @param imagePlus > >> * @param key > >> * @return the > >> */ > >> Properties getInfoProperties(ImagePlus imagePlus) throws > IOException { > >> Properties infoProps = new Properties(); > >> infoProps.load(new StringReader((String) > imagePlus.getProperty("Info"))); > >> return infoProps; > >> } > >> Michael Ellis (Managing Director) > >> Digital Scientific UK Ltd. > >> http://www.dsuk.biz <http://www.dsuk.biz/> > >> [hidden email] > >> tel: +44(0)1223 911215 > >> The Commercial Centre > >> 6 Green End > >> Cambridge > >> CB23 7DY > >> === END OF EMAIL === > >> -- > >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > > > -- > > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > Michael Ellis (Managing Director) > Digital Scientific UK Ltd. > http://www.dsuk.biz <http://www.dsuk.biz/> > [hidden email] > tel: +44(0)1223 911215 > > The Commercial Centre > 6 Green End > Cambridge > CB23 7DY > > === END OF EMAIL === > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael P Ellis
Wayne,
Many thanks for the new setProp()/getProp() functionality. I have however found it does not seem to work when I create my image with IJ.createHyperStack() or when I create a CompositImage from a Hyperstack // Does work //img = IJ.createImage("Untitled", "8-bit black", 500, 500, 3); // Does not work // img = new CompositeImage(IJ.createImage("Untitled", "8-bit black", 500, 500, 3)); // Does not work img = IJ.createHyperStack(“Untitled", 500, 500, 3, 1, 1, 16); img.setProp("Banana", "Yellow"); IJ.showMessage("Bananas are " + img.getProp("Banana") ); path = IJ.getDir("home")+"Downloads/Untitled.tif"; IJ.saveAs(img, "Tiff", path); img2 = IJ.openImage(path); IJ.showMessage("Bananas are " + img2.getProp("Banana") ); The the properties seem to be assignable to the hyperstack but are lost on save or restore. — Michael Ellis > On 17 Apr 2020, at 19:16, Michael Ellis <[hidden email]> wrote: > >> img = IJ.createImage("Untitled", "8-bit black", 500, 500, 3); >> clown = IJ.openImage("http://wsr.imagej.net/images/clown.jpg"); >> bytes = new FileSaver(clown).serialize(); >> string = Base64.getEncoder().encodeToString(bytes); >> img.setProp("clown", string); >> text = "Clown.jpg was serialized, set as an image\n" >> + "property, the image was saved, re-opened,\n" >> + "and clown.jpg was deserialized and displayed."; >> img.setProp("text", text); >> path = IJ.getDir("home")+"Downloads/Untitled.tif"; >> IJ.saveAs(img, "Tiff", path); >> img2 = IJ.openImage(path); >> string2 = img2.getProp("clown"); >> bytes2 = Base64.getDecoder().decode(string2); >> clown2 = new Opener().deserialize(bytes2); >> clown2.show(); >> IJ.showMessage(img2.getProp("text")); Michael Ellis (Managing Director) Digital Scientific UK Ltd. http://www.dsuk.biz [hidden email] tel: +44(0)1223 911215 The Commercial Centre 6 Green End Cambridge CB23 7DY === END OF EMAIL === -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> On Apr 25, 2020, at 8:30 AM, Michael Ellis <[hidden email]> wrote:
> > Wayne, > > Many thanks for the new setProp()/getProp() functionality. I have however found it does not seem to work when I create my > image with IJ.createHyperStack() or when I create a CompositImage from a Hyperstack These bugs are fixed in the 1.53a16 daily build. Source code changes are on the Git repository at https://github.com/imagej/imagej1/commit/7ef1684430547d84dcb508579e52a49ec1a7c568 -wayne > // Does work > //img = IJ.createImage("Untitled", "8-bit black", 500, 500, 3); > > // Does not work > // img = new CompositeImage(IJ.createImage("Untitled", "8-bit black", 500, 500, 3)); > > // Does not work > img = IJ.createHyperStack(“Untitled", 500, 500, 3, 1, 1, 16); > > img.setProp("Banana", "Yellow"); > IJ.showMessage("Bananas are " + img.getProp("Banana") ); > > path = IJ.getDir("home")+"Downloads/Untitled.tif"; > IJ.saveAs(img, "Tiff", path); > img2 = IJ.openImage(path); > > IJ.showMessage("Bananas are " + img2.getProp("Banana") ); > > > The the properties seem to be assignable to the hyperstack but are lost on save or restore. > > > — Michael Ellis > > >> On 17 Apr 2020, at 19:16, Michael Ellis <[hidden email]> wrote: >> >>> img = IJ.createImage("Untitled", "8-bit black", 500, 500, 3); >>> clown = IJ.openImage("http://wsr.imagej.net/images/clown.jpg"); >>> bytes = new FileSaver(clown).serialize(); >>> string = Base64.getEncoder().encodeToString(bytes); >>> img.setProp("clown", string); >>> text = "Clown.jpg was serialized, set as an image\n" >>> + "property, the image was saved, re-opened,\n" >>> + "and clown.jpg was deserialized and displayed."; >>> img.setProp("text", text); >>> path = IJ.getDir("home")+"Downloads/Untitled.tif"; >>> IJ.saveAs(img, "Tiff", path); >>> img2 = IJ.openImage(path); >>> string2 = img2.getProp("clown"); >>> bytes2 = Base64.getDecoder().decode(string2); >>> clown2 = new Opener().deserialize(bytes2); >>> clown2.show(); >>> IJ.showMessage(img2.getProp("text")); -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Wayne, hi
I have just found that whilst String properties are preserved when saved/restored with “.tif” format (ij.jar 1.53a15+), they are not preserved when saved as “.tif.zip” img = new CompositeImage(IJ.createImage("Untitled", "8-bit black", 500, 500, 3)); img.setProp("Banana", "Yellow"); IJ.showMessage("Bananas are " + img.getProp("Banana") ); path = IJ.getDir("home")+"Downloads/Untitled.tif"; IJ.saveAs(img, "Tiff", path); img2 = IJ.openImage(path); IJ.showMessage("From TIFF Bananas are " + img2.getProp("Banana") ); path = IJ.getDir("home")+"Downloads/Untitled.tif.zip"; IJ.saveAs(img, "Zip", path); img3 = IJ.openImage(path); IJ.showMessage("From Zipped TIFF Bananas are " + img3.getProp("Banana") ); This is quite surprising as I would have assumed that the .tif.zip is just a zipping/unzipping of the .tif stream/file? ALSO It turns out that the MacAdapter.class that is packaged with ImageJ prevents the ij.jar being loaded when using the Modular Java Platform. I *think* this is a matter of not being allowed any classes in the default package. I can, (as documented elsewhere) get around this by building the ImageJ ij.jar and omitting the line from the ant script that builds adds the MacAdapter class to the ij.jar. This however precludes a simple reliance on a maven dependency (as and when it becomes available). Can MacAdapter removed altogether or moved into a package? I was unsure about the MacAdapter class in any case since after removal, selecting “About Image” from the menu still seemed to work and I had assumed (mistakenly) that that was what it is for. Thanking you in anticipation of any help. Keep healthy - Keep safe — Michael Ellis -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> On Apr 28, 2020, at 9:09 AM, Michael Ellis <[hidden email]> wrote:
> > Dear Wayne, hi > > I have just found that whilst String properties are preserved when saved/restored with “.tif” format (ij.jar 1.53a15+), they are not preserved when saved as “.tif.zip” This bug is fixed in the latest ImageJ daily build (1.53a21). > img = new CompositeImage(IJ.createImage("Untitled", "8-bit black", 500, 500, 3)); > > img.setProp("Banana", "Yellow"); > IJ.showMessage("Bananas are " + img.getProp("Banana") ); > > path = IJ.getDir("home")+"Downloads/Untitled.tif"; > IJ.saveAs(img, "Tiff", path); > img2 = IJ.openImage(path); > IJ.showMessage("From TIFF Bananas are " + img2.getProp("Banana") ); > > path = IJ.getDir("home")+"Downloads/Untitled.tif.zip"; > IJ.saveAs(img, "Zip", path); > img3 = IJ.openImage(path); > IJ.showMessage("From Zipped TIFF Bananas are " + img3.getProp("Banana") ); > > This is quite surprising as I would have assumed that the .tif.zip is just a zipping/unzipping of the .tif stream/file? > > ALSO It turns out that the MacAdapter.class that is packaged with ImageJ prevents the ij.jar being loaded when using the Modular Java Platform. I *think* this is a matter of not being allowed any classes in the default package. I can, (as documented elsewhere) get around this by building the ImageJ ij.jar and omitting the line from the ant script that builds adds the MacAdapter class to the ij.jar. This sounds like a good solution. > This however precludes a simple reliance on a maven dependency (as and when it becomes available). Can MacAdapter removed altogether or moved into a package? There must be a way to tell maven that ImageJ is not dependent on the MacAdapter class. > I was unsure about the MacAdapter class in any case since after removal, selecting “About Image” from the menu still seemed to work and I had assumed (mistakenly) that that was what it is for. The MacAdapter plugin was designed to handle the “About ImageJ" and “Quit ImageJ" commands in the Apple menu and to open files dropped on the ImageJ app and double-clicked files with creator code "imgJ". It appears that with Java 8 the “About ImageJ" and “Quit ImageJ” commands work without MacAdapter. -wayne -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |