Skip to content

Commit

Permalink
feat: gumlet image provider (#489)
Browse files Browse the repository at this point in the history
Co-authored-by: Aditya Patadia <adityapatadia@users.noreply.github.com>
  • Loading branch information
pi0 and adityapatadia committed Feb 17, 2022
1 parent a12d4fe commit 8aaab14
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 0 deletions.
49 changes: 49 additions & 0 deletions docs/content/en/4.providers/gumlet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Gumlet Provider
description: 'Nuxt Image has first class integration with Gumlet'
navigation:
title: Gumlet
---

Integration between [Gumlet](https://docs.gumlet.com/) and the image module.

To use this provider you just need to specify the base url of your service in Gumlet.

```js{}[nuxt.config.js]
export default {
image: {
gumlet: {
baseURL: 'https://demo.gumlet.io'
}
}
}
```

## gumlet `mode` values

Gumlet supports all the [the standard values for `fit` property](/components/nuxt-img#fit) of Nuxt image and Nuxt picture.


## gumlet modifiers

Beside the [standard modifiers](/components/nuxt-img#modifiers), you can also pass all gumlet-specific render API parameters to the `modifiers` prop.

For a full list of these modifiers and their uses, check out [Gumlet's image Rendering API documentation](https://docs.gumlet.com/reference/image-transform-size#mode).

## gumlet best practices

Some common best practices when using Gumlet, would be to include our `format=auto` parameter, which will automatically apply the best format for an image and compress the image as well. Combine this with some top of intelligent cropping and resizing and you will have a great image!

```html
<nuxt-img
provider="gumlet"
src="/sea.jpeg"
width="300"
height="500"
fit="cover"
:modifiers="{ format: 'auto', compress: 'true' }"
/>
```

This will return a 300 x 500 image, which has been compressed, will display next-gen formats for a browser, and has been cropped intelligently to the face of the [woman in the hat](https://demo.gumlet.io/sea.jpeg?format=auto&w=300&h=500&compress=true).

3 changes: 3 additions & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export default <NuxtConfig> {
glide: {
baseURL: 'https://glide.herokuapp.com/1.0/'
},
gumlet: {
baseURL: 'https://demo.gumlet.io'
},
imgix: {
baseURL: 'https://assets.imgix.net'
},
Expand Down
12 changes: 12 additions & 0 deletions playground/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ export const providers: Provider[] = [
}
]
},
// gumlet
{
name: 'gumlet',
samples: [
{
src: '/sea.jpeg',
width: 300,
height: 300,
fit: 'cover'
}
]
},
// imgix
{
name: 'imgix',
Expand Down
1 change: 1 addition & 0 deletions src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const BuiltInProviders = [
'fastly',
'glide',
'imagekit',
'gumlet',
'imgix',
'ipx',
'netlify',
Expand Down
78 changes: 78 additions & 0 deletions src/runtime/providers/gumlet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { joinURL } from 'ufo'
import type { ProviderGetImage } from 'src'
import { createOperationsGenerator } from '~image'

export const operationsGenerator = createOperationsGenerator({
keyMap: {
width: 'w',
height: 'h',
format: 'format',
quality: 'q',
backgroundColor: 'bg',
rotate: 'rot',
mask: 'mask',
auto: 'auto',
crop: 'crop',
brightness: 'bri',
contrast: 'con',
exposure: 'exp',
gamma: 'gam',
highlight: 'high',
hueShift: 'hue',
invert: 'invert',
saturation: 'sat',
sharpen: 'sharp',
padding: 'pad',
paletteColorCount: 'colors',
colorPaletteExtraction: 'palette',
cssPrefix: 'prefix',
jsonFaceData: 'faces',
fillMode: 'fill',
fillColor: 'fill-color',
transparency: 'transparency',
focalPointDebug: 'fp-debug',
focalPointXPosition: 'fp-x',
focalPointYPosition: 'fp-y',
focalPointZoom: 'fp-z',
chromaSubsampling: 'chromasub',
colorQuantization: 'colorquant',
colorSpace: 'colorspace',
dotsPerInch: 'dpi',
pdfPageNumber: 'page',
pixelDensity: 'dpr',
aspectRatio: 'ar',
sourceRectangleRegion: 'rect',
monochrome: 'monochrome'
},
valueMap: {
fit: {
fill: 'scale',
inside: 'max',
outside: 'min',
cover: 'crop',
contain: 'fill',
clamp: 'clamp',
clip: 'clip',
facearea: 'facearea',
fillMax: 'fillmax'
},
format: {
gif: 'gif',
jpg: 'jpg',
json: 'json',
png: 'png',
avif: 'avif',
webp: 'webp',
auto: 'auto'
}
},
joinWith: '&',
formatter: (key, value) => `${key}=${value}`
})

export const getImage: ProviderGetImage = (src, { modifiers = {}, baseURL = '/' } = {}) => {
const operations = operationsGenerator(modifiers)
return {
url: joinURL(baseURL, src + (operations ? ('?' + operations) : ''))
}
}
1 change: 1 addition & 0 deletions src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface ImageProviders {
contentful?: any
fastly?: any
glide?: any
gumlet?: any
imagekit?: any
imgix?: any
prismic?: any
Expand Down
6 changes: 6 additions & 0 deletions test/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const images = [
twicpics: { url: '/test.png' },
fastly: { url: '/test.png' },
glide: { url: '/test.png' },
gumlet: { url: '/test.png' },
imgix: { url: '/test.png' },
imageengine: { url: '/test.png' },
unsplash: { url: '/test.png' },
Expand All @@ -22,6 +23,7 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/cover=200x-' },
fastly: { url: '/test.png?width=200' },
glide: { url: '/test.png?w=200' },
gumlet: { url: '/test.png?w=200' },
imgix: { url: '/test.png?w=200' },
imageengine: { url: '/test.png?imgeng=/w_200' },
unsplash: { url: '/test.png?w=200' },
Expand All @@ -38,6 +40,7 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/cover=-x200' },
fastly: { url: '/test.png?height=200' },
glide: { url: '/test.png?h=200' },
gumlet: { url: '/test.png?h=200' },
imgix: { url: '/test.png?h=200' },
imageengine: { url: '/test.png?imgeng=/h_200' },
unsplash: { url: '/test.png?h=200' },
Expand All @@ -54,6 +57,7 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/cover=200x200' },
fastly: { url: '/test.png?width=200&height=200' },
glide: { url: '/test.png?w=200&h=200' },
gumlet: { url: '/test.png?w=200&h=200' },
imgix: { url: '/test.png?w=200&h=200' },
imageengine: { url: '/test.png?imgeng=/w_200/h_200' },
unsplash: { url: '/test.png?w=200&h=200' },
Expand All @@ -70,6 +74,7 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/contain=200x200' },
fastly: { url: '/test.png?width=200&height=200&fit=bounds' },
glide: { url: '/test.png?w=200&h=200&fit=contain' },
gumlet: { url: '/test.png?w=200&h=200&fit=fill' },
imgix: { url: '/test.png?w=200&h=200&fit=fill' },
imageengine: { url: '/test.png?imgeng=/w_200/h_200/m_letterbox' },
unsplash: { url: '/test.png?w=200&h=200&fit=fill' },
Expand All @@ -86,6 +91,7 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/output=jpeg/contain=200x200' },
fastly: { url: '/test.png?width=200&height=200&fit=bounds&format=jpeg' },
glide: { url: '/test.png?w=200&h=200&fit=contain&fm=jpeg' },
gumlet: { url: '/test.png?w=200&h=200&fit=fill&format=jpeg' },
imgix: { url: '/test.png?w=200&h=200&fit=fill&fm=jpeg' },
imageengine: { url: '/test.png?imgeng=/w_200/h_200/m_letterbox/f_jpg' },
unsplash: { url: '/test.png?w=200&h=200&fit=fill&fm=jpeg' },
Expand Down
13 changes: 13 additions & 0 deletions test/unit/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as twicpics from '~/runtime/providers/twicpics'
import * as fastly from '~/runtime/providers/fastly'
import * as glide from '~/runtime/providers/glide'
import * as imgix from '~/runtime/providers/imgix'
import * as gumlet from '~/runtime/providers/gumlet'
import * as imageengine from '~/runtime/providers/imageengine'
import * as unsplash from '~/runtime/providers/unsplash'
import * as imagekit from '~/runtime/providers/imagekit'
Expand Down Expand Up @@ -126,6 +127,18 @@ describe('Providers', () => {
}
})

test('gumlet', () => {
const providerOptions = {
baseURL: ''
}

for (const image of images) {
const [src, modifiers] = image.args
const generated = gumlet.getImage(src, { modifiers, ...providerOptions }, emptyContext)
expect(generated).toMatchObject(image.gumlet)
}
})

test('imgix', () => {
const providerOptions = {
baseURL: ''
Expand Down

0 comments on commit 8aaab14

Please sign in to comment.