* @amory/image

#+begin_quote
Simply a different approach than [[https://github.com/gatsbyjs/gatsby/tree/v2/packages/gatsby-image][gatsby-image]] for responsive high-quality optimized images.
#+end_quote

** Overview

=@amory/image= is an image processing plugin and React component for Gatsby v2.

Currently macOS-only, however pull requests for other platforms are appreciated.

Key differences from =gatsby-image=:
- Complete processing pipeline and all dependencies are included
- Attempts to balance between reasonable file size with maximum quality
- Multiple compression tools with all configurable options available
- SQIP and prominent colors proxy images are available as options
- Multiple images with media query support built-in to React component
- No intersection observer support, try [[https://www.npmjs.com/package/@researchgate/react-intersection-observer][@researchgate/react-intersection-observer]]?
- No support for image filters, such as grayscale, duotone, rotate, etc.
- Output destination and filenames are completely configurable

** Install

#+begin_src sh
npm install --save @amory/image
#+end_src

** Example

#+begin_src sh
yarn init -y
yarn add gatsby@next react react-dom @amory/image
mkdir -p src/pages src/images
curl -o "src/images/sun.png" \
  "http://www.clker.com/cliparts/3/b/1/2/11971486551534036964ivak_Decorative_Sun.svg.hi.png"
#+end_src

**** =gatsby-config.js=
#+begin_src js
module.exports = {
  "plugins": [
    "@amory/styletron",
    "@amory/image"
  ]
}
#+end_src

or

#+begin_src js
module.exports = {
  "plugins": [
    "@amory/styletron",
    {
      "options": {
        "src": "src/images"
      },
      "resolve": "@amory/image"
    }
  ]
}
#+end_src

**** =src/pages/index.js=

#+begin_src js
import Img from "@amory/image"
import React from "react"

export default ({ data }) =>
  <Img images={data.sun} title="Sun"/>

export const query = graphql `
  query indexQuery {
    sun: image(name: {eq: "sun"}) {
      xs: resize(aspectRatio: "1.618" width: 300) { ... ImageXs }
      md: resize(aspectRatio: "1.618" width: 600) { ... ImageMd }
    }
  }
`
#+end_src

** =Image= Methods

*** =resize=

**** Arguments

- =aspectRatio= (string, examples: "=1.618=", "=16/9=", or "=21:9=")
- =cropFocus= (enum, default: =center=)
- =devicePixelRatios= (array of ints or floats, default: =[1, 2]=)
- =height= (int, default: original file height in pixels)
- =saveDir= (array of strings or variables, default =["/" "img" "relDir" "initName"]=)
  - =initName= (original filename without extension)
  - =saveDppx= (output device pixel ratio, e.g. "2x")
  - =relDir= (subdirectories containing original file)
  - Any other string is passed as-is
- =saveName= (array of strings or variables, default =["initName" "@" "saveDppx" "-" "saveOpts" "." "saveExt"]=)
  - =initHash= (original file content digest hash)
  - =initName=
  - =quality= (=quality= argument on some file types)
  - =saveDppx=
  - =saveExt= (output file default extension)
  - =saveHeight= (output file height in pixels)
  - =saveOpts= (unique hash of query arguments)
  - =saveWidth= (output file width in pixels)
  - Any other string is passed as-is
- =width= (int, default: original file width in pixels)

Original aspect ratio is maintained unless =aspectRatio=, =cropFocus=, =height=, and/or =width= is defined)

**** Fields

- =height=
- =width=

**** Fragments

- =... ImageXl=

#+begin_src graphql
fragment ImageXl on ImageResize {
  height
  width
  media(mq: xl)
  proxy(style: sqip) {
    srcset
    type
  }
  jpg {
    srcset
    type
  }
  webp {
    srcset
    type
  }
}
#+end_src

- =... ImageLg=

#+begin_src graphql
fragment ImageLg on ImageResize {
  height
  width
  media(mq: lg)
  proxy(style: sqip) {
    srcset
    type
  }
  jpg {
    srcset
    type
  }
  webp {
    srcset
    type
  }
}
#+end_src

- =... ImageMd=

#+begin_src graphql
fragment ImageMd on ImageResize {
  height
  width
  media(mq: md)
  proxy(style: sqip) {
    srcset
    type
  }
  jpg {
    srcset
    type
  }
  webp {
    srcset
    type
  }
}
#+end_src

- =... ImageSm=

#+begin_src graphql
fragment ImageSm on ImageResize {
  height
  width
  media(mq: sm)
  proxy(style: sqip) {
    srcset
    type
  }
  jpg {
    srcset
    type
  }
  webp {
    srcset
    type
  }
}
#+end_src

- =... ImageXs=

#+begin_src graphql
fragment ImageXs on ImageResize {
  height
  width
  media(mq: xs)
  proxy(style: sqip) {
    srcset
    type
  }
  jpg {
    srcset
    type
  }
  webp {
    srcset
    type
  }
}
#+end_src

*** =jpg=

**** Arguments

- =actions= (array of tools used to process JPEG output, default: =[jpegrecompress]=)
  - =jpegoptim=
  - =jpegRecompress=
  - =jpegtran=
- =algorithm= (enum, =jpegrecompress= only: default: =SSIM=)
  - =MPE=
  - =MS_SSIM=
  - =SmallFry=
  - =SSIM=

  Visit https://github.com/danielgtaylor/jpeg-archive#image-comparison-metrics for details.

- =lossless= (boolean, =jpegoptim= only: default: =true=)
- =metadata= (boolean, keep metadata from original file, default: =false=)
- =progressive= (boolean, progressive JPEG encoding, default: =true=)
- =quality= (integer, maximum JPEG quality, default: =80=)
- =subsample= (boolean, =jpegrecompress= only)

  Visit https://github.com/danielgtaylor/jpeg-archive#subsampling for details.

**** Fields

- =srcset=
- =type=

*** =media=

**** Arguments

- =mq= (enum, media query breakpoint, default: =xs=)
  - =xs= (Fallback image for pages of any width, value: =null=)
  - =sm= (Small image for pages 576px wide and up, value: =(min-width: 576px)=)
  - =md= (Medium image for pages 768px wide and up, value: =(min-width: 768px)=)
  - =lg= (Large image for pages 992px wide and up, value: =(min-width: 992px)=)
  - =xl= (Extra-large image for pages 1200px wide and up, value: =(min-width: 1200px)=)

  Visit 'https://getbootstrap.com/docs/4.1/layout/overview/#responsive-breakpoints' for details.

*** =png=

**** Arguments

- =actions= (array of tools used to process PNG output, default =[zopflipng]=)
  - =AdvPNG=
  - =OptiPNG=
  - =Pngcrush=
  - =PNGOUT=
  - =pngquant= (lossy compression tool)
  - =zopflipng=
- =metadata= (boolean, keep metadata from original file, default: =false=)
- =quality= (integer, maximum PNG quality, default: =95=)

**** Fields

- =srcset=
- =type=

*** =proxy=

**** Arguments

- =blur= (integer, =sqip= only: GaussianBlur SVG filter value, default: =5=)
- =mode= (enum, =sqip= only, style of primitives to use, default: =combo=)
- =numberOfPrimitives= (integer, =sqip= only: number of shapes to use, default: =40=)
- =palette= (enum, =color= only: array of prominent colors, =[Vibrant, Muted]=)
- =style= (enum, default: =lqip=)
  - =color= (extracted prominent color from image)
  - =lqip= (Low Quality Image Placeholder: Blurry bitmap thumbnail image)
  - =sqip= (SVG Image Placeholder: Blurry vector shape-based image)
- =thumb= (integer, =lqip= only: percentage size of output file, default: =20=)

**** Fields

- =srcset= (data URI of proxy image)
- =type= (mime-type of proxy image)

*** =webp=

**** Arguments

- =lossless= (boolean, encode WebP image losslessly, default: =false=)
- =metadata= (boolean, keep metadata from original file, default: =false=)
- =quality= (integer, maximum WebP quality, default: =80=)

**** Fields

- =srcset=
- =type=
