@@ -332,6 +332,9 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas
332332
333333 $ mime_type = $ image ->entity ->getMimeType ();
334334 $ iiif_url = rtrim ($ iiif_address , '/ ' ) . '/ ' . urlencode ($ file_url );
335+ $ full_image_url = $ this ->buildFullImageUrl ($ iiif_url );
336+ $ thumbnail_url = $ this ->buildThumbnailUrl ($ iiif_url );
337+ $ iiif_service = $ this ->getImageServiceDescriptor ($ iiif_url );
335338
336339 // Create the necessary ID's for the canvas and annotation.
337340 $ canvas_id = $ iiif_base_id . '/canvas/ ' . $ entity ->id ();
@@ -357,20 +360,24 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas
357360 "@type " => "oa:Annotation " ,
358361 'motivation ' => 'sc:painting ' ,
359362 'resource ' => [
360- '@id ' => $ iiif_url . ' /full/full/0/default.jpg ' ,
363+ '@id ' => $ full_image_url ,
361364 "@type " => "dctypes:Image " ,
362- 'format ' => $ mime_type ,
365+ // The painted resource is the JPEG derivative, not the
366+ // original source MIME type.
367+ 'format ' => 'image/jpeg ' ,
363368 'height ' => $ height ,
364369 'width ' => $ width ,
365- 'service ' => [
366- '@id ' => $ iiif_url ,
367- '@context ' => 'http://iiif.io/api/image/2/context.json ' ,
368- 'profile ' => 'http://iiif.io/api/image/2/profiles/level2.json ' ,
369- ],
370+ 'service ' => $ iiif_service ,
370371 ],
371372 'on ' => $ canvas_id ,
372373 ],
373374 ],
375+ 'thumbnail ' => [
376+ '@id ' => $ thumbnail_url ,
377+ '@type ' => 'dctypes:Image ' ,
378+ 'format ' => 'image/jpeg ' ,
379+ 'service ' => $ iiif_service ,
380+ ],
374381 ];
375382
376383 // Canvas label field to override the default media label.
@@ -500,6 +507,58 @@ protected function getCanvasDimensions(string $iiif_url, MediaInterface $media,
500507 return [0 , 0 ];
501508 }
502509
510+ /**
511+ * Build a IIIF Image API service descriptor from the service URL.
512+ *
513+ * @param string $iiif_url
514+ * The IIIF image service URL.
515+ *
516+ * @return array
517+ * A service block for the manifest image resource.
518+ */
519+ protected function getImageServiceDescriptor (string $ iiif_url ): array {
520+ $ service = [
521+ '@id ' => $ iiif_url ,
522+ '@context ' => 'http://iiif.io/api/image/2/context.json ' ,
523+ 'profile ' => 'http://iiif.io/api/image/2/profiles/level2.json ' ,
524+ ];
525+
526+ if (str_contains ($ iiif_url , '/iiif/3/ ' )) {
527+ $ service ['@context ' ] = 'http://iiif.io/api/image/3/context.json ' ;
528+ $ service ['profile ' ] = 'level2 ' ;
529+ }
530+
531+ return $ service ;
532+ }
533+
534+ /**
535+ * Build the painted image URL from a IIIF image service URL.
536+ *
537+ * @param string $iiif_url
538+ * The IIIF image service URL.
539+ *
540+ * @return string
541+ * A full-size image request URL.
542+ */
543+ protected function buildFullImageUrl (string $ iiif_url ): string {
544+ return str_contains ($ iiif_url , '/iiif/3/ ' )
545+ ? $ iiif_url . '/full/max/0/default.jpg '
546+ : $ iiif_url . '/full/full/0/default.jpg ' ;
547+ }
548+
549+ /**
550+ * Build the thumbnail URL from a IIIF image service URL.
551+ *
552+ * @param string $iiif_url
553+ * The IIIF image service URL.
554+ *
555+ * @return string
556+ * A thumbnail image request URL.
557+ */
558+ protected function buildThumbnailUrl (string $ iiif_url ): string {
559+ return $ iiif_url . '/full/200,/0/default.jpg ' ;
560+ }
561+
503562 /**
504563 * Retrieves a URL text with positional data such as hOCR.
505564 *
0 commit comments