Get updates via , Github, or RSS | About

Episode 27: Resize Images Mar 9, 2017

It is possible to resize images in the client’s web browser using the canvas API. This eliminates the need for your server to do the work, and allows the client to upload the correct file directly to S3. We use the same simonh1000/file-reader module as the last two weeks, which allows us to pass native File objects through ports to a canvas for drawing.

Examples

app.js

main.ports.crop.subscribe(function (options) {
  let img = new Image()
  img.src = options.imgSrc
  let canvas = document.createElement('canvas')
  canvas.width = options.dim
  canvas.height = options.dim
  canvas.getContext('2d').drawImage(img, options.x, options.y, options.dim, options.dim, 0, 0, options.dim, options.dim)
  canvas.toBlob(function (blob) {
    main.ports.incomingCroppedFile.send(new File([blob], "cropped.jpg"))
  })
})

Main.elm

update msg model =
    case msg of
        MouseUp ( upX, upY ) ->
            let
                -- …
                cmd =
                    case model.encodedFile of
                        Just imgSrc ->
                            crop { imgSrc = imgSrc, x = downX, y = downY, dim = dim }

                        Nothing ->
                            Cmd.none
            in
                model ! [ cmd ]

        IncomingCroppedFile blob ->
            let
                file =
                    JD.decodeValue nativeFileDecoder blob
                        |> Result.toMaybe
            in
                { model | fileToUpload = file } ! []


port crop : { imgSrc : String, x : Float, y : Float, dim : Float } -> Cmd msg


port incomingCroppedFile : (JD.Value -> msg) -> Sub msg