npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@myrmidon/cadmus-img-gallery-iiif

v7.0.0

Published

Cadmus - minimalist image gallery.

Downloads

238

Readme

CadmusImgGalleryIiif

This library was generated with Angular CLI version 17.3.0.

Overview

The image gallery is a minimalist set of components used to:

  • show a gallery of images from some online source.
  • let users pick an image and annotate it.

These components are independent from any specific servicing technology; images could be served by IIIF, cloud stores, etc.; you are free to provide your own service to get a page of images, and a single image, with the desired sizes. Even the filters used to browse the list of images are totally open, so that you can define as many filters as you want, according to your own data.

The general idea behind these components is having a Cadmus part to create annotations on images. Its only tasks are (1) presenting a gallery of images to pick from, and (2) allowing users to create variously shaped regions on the selected image, each linked with a unique ID (a GUID), and optional note and tags.

Once you create these annotations, you will be able to use other parts to link them to any type of specialized data via their ID. So, all what the image annotator does is letting users delimit one or more regions with any geometric shape, associating each with an annotation having a globally unique ID (GUID), and eventually a body consisting of any number of text notes and tags. This way, each annotation (and consequently each region on the image) gets its own unique ID, which can be referenced from elsewhere in the context of the Cadmus database. This allows attaching to portions of images any kind of data and models, all edited in the same environment. Once they are in the database, we can eventually export them by creating W3C annotations, IIIF manifests, etc.

Also, as usual in Cadmus, annotation IDs are opaque (and so they are supposed to be), just like items or parts IDs; yet, at least in the context of the editor more user-friendly IDs are welcome. As explained here, in other Cadmus parts, user friendly IDs are got via EID's (entity IDs); these are either aliases of entities which already have their own global ID (a GUID), like items; or identifiers assigned to entities inside a part. In both cases, they can be referenced via a lookup UI, where you just type some characters belonging to the ID to get a list of the first matching IDs.

To apply the same approach in the context of image annotations, we just define a convention by which you can assign an EID to any annotation via a tag beginning with eid_. For instance, if you draw a rectangle around some region of an image, and assign it the tag eid_sample, by convention this means that the annotation linked to that region will get an EID equal to sample.

The annotation editor can also be embedded in a bigger component, like a custom part for annotating images while providing specialized models for each annotation. In this case, you can interact with the embedded component by setting custom actions for it, like in this example:

<cadmus-gallery-img-annotator
  [image]="image"
  [annotations]="annotations.value"
  [customActions]="actions"
  (annotationsChange)="onAnnotationsChange($any($event))"
  (actionRequest)="onActionRequest($event)"
></cadmus-gallery-img-annotator>

with a code like:

public onAnnotationsChange(annotations: ChgcImageAnnotation[]): void {
  // annotations has type FormControl<MyOwnImageAnnotation[]>,
  // which extends GalleryImageAnnotation
  this.annotations.setValue(annotations);
  this.annotations.updateValueAndValidity();
  this.annotations.markAsDirty();
}

public onActionRequest(action: BarCustomActionRequest): void {
  if (action.id === 'edit-meta') {
    const i = +action.payload;  // the action payload is the annotation index
    this.editAnnotation(this.annotations.value[i], i);
  }
}

Note that this library depends on @myrmidon/cadmus-img-annotator, which in turn requires the Annotorious package.

Services

A gallery image is any object implementing the GalleryImage interface, which provides the barely minimum properties of each image: a string ID, a URI, a title, and a short description.

Related services are:

  • gallery service, with its injection token. You will provide your own real-world service, which might draw images from IIIF services, cloud services, etc.
  • gallery options service, used as the singleton holding options for the gallery. Options are equal to or derive from GalleryOptions. You can access the options and change them by injecting this service.
  • a mock gallery service implementation, using an online mock images service. This is used during development as a convenient placeholder instead of your custom service.
  • lorem ipsum service, used by the mock gallery service to generate image descriptions.

A gallery service is any service implementing the GalleryService interface, having just two methods: one to retrieve a page of images, and another to retrieve a single image. In both cases, you can specify image options (first of all the size) via options, which implement interface GalleryOptions. The service is stateless, except for the fact that it caches the options when first used, and reacts to their change from usage to usage.

Also, the list of images in the gallery can be filtered using an implementation of GalleryFilter. This is just a set of key/value pairs, both represented by strings. Usually you will draw a set of keys to show in the filter UI from some thesaurus.

For instance, to filter images by title you will set a filter property with key=title and value equal to any portion of the title to match.

Components

  • gallery filter, to define any number of name=value pairs representing filters applied to the gallery images. The filter gets the gallery list repository injected, so it directly invokes its methods.

    • ➡️ input:
      • entries: ThesaurusEntry[] | undefined: the entries used to represent image gallery metadata filters. Each entry is a metadatum, with ID=metadatum name and value=label. If not set, users will be allowed to freely type a name rather than picking it from a list.
  • gallery images list, to browse a list of images via a gallery service implementation. The type of implementation used is defined by your consumer application (via DI as specified in app.module providers). Both the list and its filter depend on the same repository, which provides paged data to the UI.

    • ➡️ input:
    • entries: ThesaurusEntry[] | undefined: the entries used to represent image gallery metadata filters. Each entry is a metadatum, with ID=metadatum name and value=label. If not set, users will be allowed to freely type a name rather than picking it from a list.
    • ⬅️ output:
      • imagePick: EventEmitter<GalleryImage>
  • gallery image annotator, to annotate an image picked from a gallery by drawing rectangular or polygonal regions on it.

Setup

To use this brick in your Cadmus frontend app:

(1) install packages:

npm i @recogito/annotorious @myrmidon/cadmus-img-annotator @myrmidon/cadmus-img-gallery

(2) ensure to add Annotorious CSS styles to your angular.json like:

"styles": [
  "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
  "node_modules/@recogito/annotorious/dist/annotorious.min.css",
  "src/styles.css"
]

(3) import modules in your app.module.ts and inject the required image service and default options (you can then change them later via GalleryOptionsService):

import { CadmusImgAnnotatorModule } from '@myrmidon/cadmus-img-annotator';
import { CadmusImgGalleryModule } from '@myrmidon/cadmus-img-gallery';

@NgModule({
  // ...
  imports: [
    // ...
    CadmusImgAnnotatorModule,
    CadmusImgGalleryModule,
  ],
  providers: [
    // image gallery: TODO replace with your own
    {
      provide: IMAGE_GALLERY_SERVICE_KEY,
      useClass: MockGalleryService,
    },
    {
      provide: IMAGE_GALLERY_OPTIONS_KEY,
      useValue: {
        baseUri: '',
        count: 50,
        width: 300,
        height: 400,
      },
    },
  ]
  // ...
})
export class AppModule {}

(4) if you want to lookup annotations by their EID, be sure to include the corresponding lookup definition like:

import { IndexLookupDefinitions } from '@myrmidon/cadmus-core';
import {
  GALLERY_IMAGE_ANNOTATIONS_PART_TYPEID,
} from '@myrmidon/cadmus-part-general-ui';

export const INDEX_LOOKUP_DEFINITIONS: IndexLookupDefinitions = {
  // ...
  // gallery
  img_anno_eid: {
    typeId: GALLERY_IMAGE_ANNOTATIONS_PART_TYPEID,
    name: 'eid',
  },
};