openseadragon / openseadragon

An open-source, web-based viewer for zoomable images, implemented in pure JavaScript.
http://openseadragon.github.io/
BSD 3-Clause "New" or "Revised" License
2.99k stars 594 forks source link

IIIF images from manifest URL #2390

Open TomDijkema opened 1 year ago

TomDijkema commented 1 year ago

Hi,

I am trying to display IIIF images in my React application using OpenSeaDragon (OSD). All works well, untill I actually try to read in the images from the source.

First off, I followed the example from the OSD website: https://openseadragon.github.io/examples/tilesource-iiif/. After ignoring the TypeScript errors, this example works as expected and displays the image in the canvas. Now I went and replaced the static @id property with the value I get returned from one of our source APIs (we want to support multiple). The manifest (info.json) url: https://iiif-manifest.oxalis.br.fgov.be/specimen/BR0000025668070V/manifest. This tries to fetch the image from the source API, but fails to find so because the url is formatted incorrectly.

Generated url by OSD: https://iiif-manifest.oxalis.br.fgov.be/specimen/BR0000025668070V/manifest/full/328,/0/default.jpg

Correct url provided by source: https://iiif-image.oxalis.br.fgov.be/V/BR0/000/025/668/070/BR0000025668070V.jpg/full/full/0/default.jpg

As you can see the url provided by the source does make use of the IIIF API specification, but uses a different path for the manifest file and the actual images that OSD specifies.

How can I adapt the OpenSeaDragon configuration to correctly format the urls? My expectation was this is going to be defined in the manifest file, but whatever I try, the path does not change and keeps on appending: '/full/328,/0/.default.jpg' at the end of the manifest url.

My OpenSeaDragon config:

OpenSeaDragon({
 id: "openSeaDragon",
   preserveViewport: true,
     visibilityRatio: 1,
     defaultZoomLevel: 0,
     sequenceMode: true,
     tileSources: {
          "@context": manifest['@context'],
          "@id": manifest['@id'],
          "height": 7200,
          "width": 5233,
          "profile": ["http://iiif.io/api/image/2/level2.json"],
          "protocol": "http://iiif.io/api/image",
          "tiles": [{
               "scaleFactors": [1, 2, 4, 8, 16, 32],
               "width": 1024
          }]
     },
     showFullPageControl: false,
     showHomeControl: false,
     prefixUrl: "https://cdn.jsdelivr.net/npm/openseadragon@2.4/build/openseadragon/images/"
})

Where @id = "https://iiif-manifest.oxalis.br.fgov.be/specimen/BR0000025668070V/manifest" and @context = ["http://www.w3.org/ns/anno.jsonld", "http://iiif.io/api/presentation/2/context.json"]

Thanks in advance! ~ Tom

iangilman commented 1 year ago

I don't know enough about IIIF to know the answer. Any pointers, @glenrobson @azaroth42 @ruven @ahankinson @tomcrane (also let me know if you don't want me tagging you for issues like this).

ahankinson commented 1 year ago

Happy to be tagged.

@TomDijkema you need to pass the image's info.json response to OpenSeadragon:

https://iiif-image.oxalis.br.fgov.be/V/BR0/000/025/668/070/BR0000025668070V.jpg/info.json

You can read more about the various ways of requesting images and image info in the Image API Spec (version 2 here: https://iiif.io/api/image/2.1/#uri-syntax)

TomDijkema commented 1 year ago

Thanks! Taking the @id from the info.json file as a static string works and loads the image into OSD!

I have one remaining question, how would I get from the manifest.json file to the info.json file? On inspecting (and after reading the API docs) I do not see a direct reference to the file. You could pull the base url from the thumbnail images or images array itself I guess, but the manifest format is somewhat different in every case, making this unreliable.

Three examples:

Hope this makes sense :)

ahankinson commented 1 year ago

TL;DR: Just change the URL for the image and it should always give you the info response. Read below for the details.

If you have this manifest:

https://iiif-manifest.oxalis.br.fgov.be/specimen/BR0000025668070V/manifest

The only image in this manifest is referenced as an annotation on the first canvas:

https://iiif-image.oxalis.br.fgov.be/V/BR0/000/025/668/070/BR0000025668070V.jpg/full/full/0/default.jpg

If you plug this into a browser directly this gives you the full image file. However, if you remove the "full/full/0/default.jpg" bit and replace it with "info.json" then you will return the image info. This is standard; if you find a URL that ends in "full/[max|full]/0/default.jpg" you can always get the info.json if you remove that bit and add "info.json".

The reference to the image is always given as the id/@id field on the image resource. The location of this within the canvas structure can vary depending on whether the manifest is a version 2 or a version 3 manifest.

TomDijkema commented 1 year ago

Ok, got it working for the version 3 manifests. Digging down the manifest file to the image id and providing that url to OSD. Kept out the /info.json part and instead used: https://iiif.rbge.org.uk/herb/iiif/E00545205, otherwise it gave an error.

For version 2 manifests, it seems to be different per source I use. At least, I could not find the info.json file for the following: https://pictures.bgbm.org/digilib/digilib.html?fn=B/10/03/32/88/B_10_0332888.jpg. But that might be due to the image viewer they use to display the images. Any clues?

The earlier example of version 2 manifest: https://iiif-image.oxalis.br.fgov.be/V/BR0/000/025/668/070/BR0000025668070V.jpg/info.json, does work with this method!

Really appreciate your help!

ahankinson commented 1 year ago

https://iiif.rbge.org.uk/herb/iiif/E00545205/info.json seems to work for me?

That one is a level0 implementation, which is the absolute minimal level. That server is also not fully compliant, since this does not work:

https://iiif.rbge.org.uk/herb/iiif/E00545205/full/max/0/default.jpg

A list of requirements for image servers to support at given profiles is available here: https://iiif.io/api/image/3.0/compliance/. As you can see, "full", "max", "0", and "default.jpg" are all required parameters.

ahankinson commented 1 year ago

The Botanical Garden Berlin link in your last message is not a IIIF link. It uses digilib, but not as a IIIF server.

However, you included a link to the manifest in a previous message. From there I see that they do give the link to the info.json in the "service" block on the image:

https://pictures.bgbm.org/digilib/Scaler/IIIF/B!10!01!41!97!B_10_0141979.jpg

Turning this into:

https://pictures.bgbm.org/digilib/Scaler/IIIF/B!10!01!41!97!B_10_0141979.jpg/info.json

should give you your response. (This is OK, but isn't really great... they shouldn't be linking to an HTML page of a viewer as the id field of the image!)

iangilman commented 1 year ago

@ahankinson Thank you so much for all this great info! It seems to me it might be good to add an answer to "I have a IIIF manifest, how do I load it into OpenSeadragon?" to https://github.com/openseadragon/openseadragon/wiki/FAQ, with the answer being "You can't, but here's how you get the images out of the manifest, and you can load those into OSD." What do you think?

glenrobson commented 1 year ago

Sorry jumping in late to this issue but trying to find image ids from a manifest comes up in the IIIF training often and I've created a small web app where you can paste your Manifest URL and it will give you the Image ids which work in OpenSeadragon:

https://glenrobson.github.io/CanvasFinder/

It would be great to also have a FAQ question.

TomDijkema commented 1 year ago

Yes! That is a pretty logical explanation, the other link does work indeed. I presume there will be multiple cases like these. We do not control the IIIF servers themselves, but rather collect and harmonise all the data from the institutions to create a pan European infrastructure. We will try to inform the institutions about the best practices of the IIIF standards, since handling an exception for everyone would be madness :).

Good to know that the method you suggested by the normal IIIF standards, should function fine. This would answer my base question of this issue :+1:

TomDijkema commented 1 year ago

Sorry jumping in late to this issue but trying to find image ids from a manifest comes up in the IIIF training often and I've created a small web app where you can paste your Manifest URL and it will give you the Image ids which work in OpenSeadragon:

https://glenrobson.github.io/CanvasFinder/

It would be great to also have a FAQ question.

I found your tool sometime ago, it is very useful! I raised this issue because I wanted to implement this behavior also within our own application. Would appreciate it if the FAQ gets expanded with manifests in mind :+1:

iangilman commented 1 year ago

Great! I feel I don't know enough about the matter to write a good FAQ entry. Would you be up for doing it @glenrobson or @ahankinson ? Feel free to edit the wiki page directly, or propose wording here.