thomasin / elm-frontmatter / Content.Decode.Image

Copy and resize images. Use process to process an image once, or batchProcess to process an image multiple times with different manipulations applied.

Configuration ⸺ Configure copy and rewrite args

Decoders ⸺ Decode image file paths, process the images and rewrite the file paths

Manipulations ⸺ Change the image while copying (e.g. resize)

Configuration


type alias CopyArgs =
{ copyToDirectory : String
, publicDirectory : String 
}

Configure where images are copied to, and how their paths are rewritten. Passed in to the process and batchProcess functions.

imageCopyArgs : Content.Decode.Image.CopyArgs
imageCopyArgs =
    { copyToDirectory = "./static/image-gen/"
    , publicDirectory = "/image-gen/"
    }

will copy images to the ./static/image-gen/ folder, relative to the local package.json. Image URLs will be rewritten with the public directory as the root i.e. /image-gen/banner.jpg.

Images will be copied with directory structure intact, i.e.

.
└── content
    └── about
    |   ├── banner.jpg --> /static/image-gen/about/banner.jpg
    |   └── content.md --> /Content/About.elm
    └── hero.jpg --> /static/image-gen/hero.jpg

with the above imageCopyArgs, would result in

.
└── static
    └── image-gen
        └── about
        |   ├── banner.jpg
        └── hero.jpg

Decoders


type alias Decoder =
Content.Decode.Decoder ( ActionDetails
, List ActionDetails 
}

An image decoder. Can be used with any function that accepts a decoder

Content.Decode.frontmatterWithoutBody
    [ Content.Decode.attribute "photos"
        (Content.Decode.list (Content.Decode.Image.process imageCopyArgs []))
    ]


type alias ActionDetails =
Internal.ActionDetails

Image action details. An opaque type returned from the image decoder, used to define the manipulations to process on the image.


type alias Manipulation =
Internal.Manipulation

An image manipulation. See width (the only manipulation we currently have 🤭). Can be passed into process or batchProcess to be performed on referenced images.

process : CopyArgs -> List Manipulation -> Decoder

Copy and modify an image, with possible manipulations applied. Use Content.Decode.Image.process imageCopyArgs [] if you just want to copy the image, not apply any manipulations.

imageCopyArgs : Content.Decode.Image.CopyArgs
imageCopyArgs =
    { copyToDirectory = "../static/image-gen/"
    , publicDirectory = "/image-gen/"
    }

decoder : Content.Type.Path -> Content.Decode.QueryResult
decoder typePath =
    case typePath of
        Content.Type.Single [ "Content", "About" ] ->
            Content.Decode.decode
                [ Content.Decode.attribute "title" Content.Decode.string
                , Content.Decode.attribute "banner"
                    (Content.Decode.Image.process imageCopyArgs [ Content.Decode.Image.width 1600 ])
                ]

        _ ->
            Content.Decode.ignore

{- =>
   type alias Content =
       { title : String
       , banner : String
       }


   content : Content
   content =
       { title = "About"
       , banner = "/image-gen/banner.jpeg"
       }
-}

batchProcess : CopyArgs -> ( String, List Manipulation ) -> List ( String, List Manipulation ) -> Decoder

Make multiple copies of one image, with different manipulations applied.

imageCopyArgs : Content.Decode.Image.CopyArgs
imageCopyArgs =
    { copyToDirectory = "../static/image-gen/"
    , publicDirectory = "/image-gen/"
    }

decoder : Content.Type.Path -> Content.Decode.QueryResult
decoder typePath =
    case typePath of
        Content.Type.Collection [ "Content", "About", "People" ] ->
            Content.Decode.decodeWithoutBody
                [ Content.Decode.attribute "name" Content.Decode.string
                , Content.Decode.attribute "position" Content.Decode.string
                , Content.Decode.attribute "thumbnail"
                    (Content.Decode.Image.batchProcess imageCopyArgs
                        ( "300", [ Content.Decode.Image.width 300 ] )
                        [ ( "600", [ Content.Decode.Image.width 600 ] )
                        , ( "1200", [ Content.Decode.Image.width 1200 ] )
                        ]
                    )
                ]

        _ ->
            Content.Decode.ignore

{-
   type alias CollectionItem =
       { name : String
       , position : String
       , thumbnail : ( ( String, String ), List ( String, String ) )
       }

   person1 : CollectionItem
   person1 =
       { name = "Person 1", position = "Astronaut"
       , thumbnail =
           ( ( "300", "/image-gen/about/people/[person1]/banner-300.jpeg" )
           , [ ( "600", "/image-gen/about/people/[person1]/banner-600.jpeg" )
             , ( "1200", "/image-gen/about/people/[person1]/banner-1200.jpeg" )
             ]
           )
       }
-}

Manipulations

width : Basics.Int -> Manipulation

Resize the generated image to a specified width. The image will evenly scale.