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

chore(storage-image-processing-api): initial extension build #2

Merged
merged 62 commits into from Jul 14, 2021

Conversation

Salakar
Copy link
Member

@Salakar Salakar commented Jun 17, 2021

Introducing a Storage image processing extension which provides an extensive image processing API with 30+ image mutation operations from resizing and colour manipulation to overlaying text and compositing images.

The core image processing logic in the implementation is portable and therefore can be used in a variety of ways, e.g.,

  • reacting to a storage event to automatically process an image (operations could be defined via a metadata key)
  • adding image operations to Firestore and listening to a Firestore collection that would trigger these operations to be applied and output
  • etc

but for this implementation, initially, interfacing with the image processing is provided as a URL safe HTTP GET API via a Cloud Function (and could be used for embedding e.g., <img src="<extensionFunctionUrl/process/...ops />).

Accessing GCS bucket objects is done via tokenated download urls, e.g., getDownloadUrl() on Firebase SDKs or providing a path to a public object on the bucket, e.g., /foo/bar.png. URLs & paths must be URL encoded.

Process Image URL Schema

The URL schema to apply operations is built into url parts separated by /, each segment is then in the following format;

/<operationName>~<optionName>:<optionValue>/
  • A single operation and it's options are defined per url segment. Multiple options are separated by ~.
  • Option values are automatically coerced into their appropriate types, e.g. '5' as a string would become 5 as a number, or '[1,2,3,4]' as a string would result in a JS array of numbers.
  • Truthy boolean options can just specify the <optionName> only to have the value default to true (think flags).
  • Operations that have no options or only have optional options can just specify the operation without options, e.g./negate/.
  • An input operation must be the first operation specified and is required.
  • An output operation must be the last operation specified and is required.

Having the URL schema as url segments vs query parameters allows us to easily have operation ordering and support using multiple operations of the same type in a chain of operations. Additionally makes options clearer that they are for a specific operation.

Example

URL:

/process/input~type:gcs~source:%2Fassets%2Fhexagons.jpeg/resize~width:500~height:500~fit:cover~position:left%20bottom/extend~all:20~background:tomato/extend~all:20~background:lightgreen/composite~top:20~left:26~tile~blend:screen~input:%2Fassets%2Finvertase.png/text~strokeWidth:4~top:75~left:75~font:95px%20tahoma~strokeColor:SeaGreen~textAlign:center~value:Hello%0DWorld~gravity:northwest~backgroundColor:pink~textColor:MediumSpringGreen~padding:15~borderWidth:5~borderColor:black/output~format:png

Output:

image

Supported operations

Operations pending implementation

Not blocked or difficult by any means, just needs time invested to implement. These will be added in a future PR.

  • removeAlpha
  • ensureAlpha
  • extractChannel
  • joinChannel
  • bandbool

TODO

@Salakar

This comment has been minimized.

@Salakar

This comment has been minimized.

This allows us to use commas for list values, e.g. the arg value in `matrix:[[1,2,3,4,5],[1,2,3,4,5]]` could easily be extracted via a `JSON.parse(argValue)``
Includes support to create images without a base image, e.g., `http://localhost:3001/process/input~type:create~width:200~height:100/flatten~background:orange/text~value:Extensions/output~format:png`
@Salakar
Copy link
Member Author

Salakar commented Jun 21, 2021

Example of me mutating our Melos logo;

Original:
logo

Mutated:

/process/input~type:url~url:https%3A%2F%2Fraw.githubusercontent.com%2Finvertase%2Fmelos%2Fmaster%2Fdocs%2Fassets%2Flogo-dark.png/flip/flop/median~size:55/extend~right:300~top:100~left:100/text~value:elos~top:350~left:475~font:110px%20arial/output~format:jpeg

image

@Salakar Salakar changed the title [WIP] chore(storage-image-processing-api): initial extension build chore(storage-image-processing-api): initial extension build Jun 21, 2021
@Salakar Salakar force-pushed the storage-image-processing-api branch 5 times, most recently from db6179f to 2fd9479 Compare July 8, 2021 12:31
@Salakar Salakar force-pushed the storage-image-processing-api branch from 2fd9479 to 2653f7b Compare July 8, 2021 12:46
@Salakar Salakar marked this pull request as ready for review July 14, 2021 10:03
@Salakar Salakar merged commit 7fc119e into main Jul 14, 2021
@Salakar Salakar deleted the storage-image-processing-api branch July 14, 2021 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants