Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

equivalent of ImageMagick.getimageproperty() #59

Open
bjarthur opened this issue Jul 28, 2021 · 9 comments
Open

equivalent of ImageMagick.getimageproperty() #59

bjarthur opened this issue Jul 28, 2021 · 9 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Milestone

Comments

@bjarthur
Copy link

is there a way to do this with TiffImages.jl?

using ImageMagick
wand = MagickWand()
readimage(wand, "filename.tif")
my_custom_metadata_value = ImageMagick.getimageproperty(wand, "my_custom_metadata_key")
@tlnagy
Copy link
Owner

tlnagy commented Aug 6, 2021

Could you give an example TIFF and/or key?

You can do something like

julia> img = TiffImages.load("/home/tlnagy/Downloads/example.tiff")
....
julia> img.ifds[1]
IFD, with tags: 
        Tag(IMAGEWIDTH, 1024)
        Tag(IMAGELENGTH, 768)
        Tag(BITSPERSAMPLE, UInt16[8, 8, 8, 8])
        Tag(COMPRESSION, COMPRESSION_NONE)
        Tag(PHOTOMETRIC, 2)
        Tag(FILLORDER, 1)
        Tag(STRIPOFFSETS, UInt32[8, 131080, 262152, 393224, 524296, ...])
        Tag(ORIENTATION, 1)
        Tag(SAMPLESPERPIXEL, 4)
        Tag(ROWSPERSTRIP, 32)
        Tag(STRIPBYTECOUNTS, UInt32[131072, 131072, 131072, 131072, 131072, ...])
        Tag(PLANARCONFIG, 1)
        Tag(RESOLUTIONUNIT, 2)
        Tag(EXTRASAMPLES, 1)
        Tag(SAMPLEFORMAT, UInt16[1, 1, 1, 1])
        Tag(ICCPROFILE, Any[0, 0, 2, 36, 97, ...])

Accessing existing tags:

julia> img.ifds[1][TiffImages.IMAGEWIDTH]
Tag(IMAGEWIDTH, 1024)

Creating new tags:

julia> img.ifds[1][TiffImages.IMAGEDESCRIPTION]
ERROR: KeyError: key 0x010e not found
Stacktrace:
 [1] getindex
   @ ~/.julia/packages/OrderedCollections/PRayh/src/ordered_dict.jl:380 [inlined]
 [2] getindex
   @ ~/.julia/dev/TiffImages/src/ifds.jl:30 [inlined]
 [3] getindex(ifd::TiffImages.IFD{UInt32}, key::TiffImages.TiffTag)
   @ TiffImages ~/.julia/dev/TiffImages/src/ifds.jl:29
 [4] top-level scope
   @ REPL[5]:1

julia> img.ifds[1][TiffImages.IMAGEDESCRIPTION] = "test"
"test"

And if using a non-standard tag, you can always refer to it by its UInt16 code. Say we make a new tag

julia> img.ifds[1][UInt16(5678)] = "test"
"test"

julia> img.ifds[1]
IFD, with tags: 
        ...other stuff...
        Tag(UNKNOWN(5678), "test")
        Tag(ICCPROFILE, Any[0, 0, 2, 36, 97, ...])

@tlnagy tlnagy added the question Further information is requested label Aug 6, 2021
@tlnagy
Copy link
Owner

tlnagy commented Aug 6, 2021

Also, the tag accessing API is not finalized so if you had any thoughts on how to improve the behavior, I'm open to suggestions!

@bjarthur
Copy link
Author

bjarthur commented Aug 6, 2021

excellent, thanks!

in my case, i had to take the additional step of printing the data field of the Tag:

julia> x = img.ifds[1][TiffImages.IMAGEDESCRIPTION]
Tag(IMAGEDESCRIPTION, "<MetaData>
<prop id=...")

julia> print(x.data)
<MetaData>
<prop id="Description" type="string" value="Acquired from Hamamatsu DCAM Camera&#13;&#10;Exposure: 5.5 msec&#13;&#10;Binning: 1 X 1&#13;&#10;Region: 1024 x 1024, offset at (512, 512)&#13;&#10;Sensor Mode: Normal&#13;&#10;Digitizer: High-speed&#13;&#10;Bit Depth: 16-bit&#13;&#10;Frames to Average: 1&#13;&#10;Electron Count Conversion Factor: 0.48&#13;&#10;Electron Count Conversion Offset: 100&#13;&#10;"/>
<prop id="MetaDataVersion" type="float" value="1"/>
<prop id="ApplicationName" type="string" value="MetaMorph"/>
<prop id="ApplicationVersion" type="string" value="7.10.4.407"/>
<PlaneInfo>
<prop id="plane-type" type="string" value="plane"/>
<prop id="pixel-size-x" type="int" value="1024"/>
<prop id="pixel-size-y" type="int" value="1024"/>
...

@bjarthur bjarthur closed this as completed Aug 6, 2021
@tlnagy
Copy link
Owner

tlnagy commented Aug 6, 2021

Yeah, currently I truncate the output when displaying long strings to just the first 20 bytes here:

_showdata(io::IO, t::Tag{<: AbstractString}) = print(io, "\"", first(t.data, 20), (length(t.data) > 20) ? "..." : "", "\"")

But I'm happy to consider alternative approaches.

@bjarthur bjarthur reopened this Aug 18, 2021
@bjarthur
Copy link
Author

re-opening with a suggestion: would be nice to get the tags as described above without having to read in the entire image. mmap is the suggested work-around i suppose? an API that provides a means to get the image size, bit depth, etc. would be better.

@tlnagy
Copy link
Owner

tlnagy commented Aug 18, 2021

Mmap would certainly work in a pinch:

TiffImages.load("path/to/file.tiff"; mmap = true)

but it should be possible to load the tag info separately from the image data. I already load the IFD tag info separately at the beginning:

for ifd in tf
load!(tf, ifd)
push!(ifds, ifd)
nplanes += 1
end

@tlnagy tlnagy added enhancement New feature or request and removed question Further information is requested labels Aug 18, 2021
@bjarthur
Copy link
Author

i'm not familiar enough with the internals of TIFF, but for an API, at a minimum, a method which returned the image dimensions given a filename would help. specifically, in my case each plane is stored in a separate file. so i need to preallocate a 3D array, and then loop over loading each image. and to do that i need the dimensions.

@tlnagy
Copy link
Owner

tlnagy commented Aug 18, 2021

What if you could access all the ifd info as in #59 (comment), but without loading the image?

We could call that function

TiffImages.loadtags()

or

TiffImages.loadifds()

Not sure which one I prefer. loadifds is more accurate, but perhaps overly specific?

@bjarthur
Copy link
Author

that'd be great! i'm not a TIFF expert so have no preference on your proposed alternatives.

@tlnagy tlnagy added help wanted Extra attention is needed good first issue Good for newcomers labels Jan 10, 2024
@tlnagy tlnagy added this to the v1.0 milestone Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants