Search code examples
elmimage-scaling

Elm: Get the size of an image


I am trying to get the width and height of an image, so give a URL, what is the width and height of that image


Solution

  • I don't believe that there is a way to do this in elm. Ports are one possible solution. You can read about them here. I've written a small example of your use case which you can run your self on ellie. In this example I use the JS example you gave in your comment, but there are other possible solutions such as event listeners or querying the DOM.

    Main.elm

    port module Main exposing (main)
    
    import Html exposing (..)
    import Html.Attributes exposing (..)
    
    
    main : Program Never Model Msg
    main =
        Html.program
            { init = init
            , update = update
            , view = view
            , subscriptions = subscriptions
            }
    
    
    type alias Model =
        { imageUrl : String
        , dim : Maybe ( Int, Int )
        }
    
    
    testImg : String
    testImg =
        "https://images-na.ssl-images-amazon.com/images/I/71TcaVWvBsL._SY355_.jpg"
    
    
    init : ( Model, Cmd msg )
    init =
        Model testImg Nothing
            ! [ getDim testImg ]
    
    
    type Msg
        = UpdateDim ( Int, Int )
    
    
    update : Msg -> Model -> ( Model, Cmd msg )
    update msg model =
        case msg of
            UpdateDim xy ->
                { model | dim = Just xy } ! []
    
    
    view : Model -> Html msg
    view model =
        case model.dim of
            Nothing ->
                div [] []
    
            Just dims ->
                div []
                    [ img [ src model.imageUrl ] []
                    , text <|
                        "size: "
                            ++ toString dims
                    ]
    
    
    subscriptions : Model -> Sub Msg
    subscriptions model =
        newDim UpdateDim
    
    -- this port handles our incomming height and width
    -- and passes it to a Msg constructor
    port newDim : (( Int, Int ) -> msg) -> Sub msg
    
    -- this port passes our string out of Elm and into
    -- js land
    port getDim : String -> Cmd msg
    

    index.html

    <html>
    <head>
      <style>
        /* you can style your program here */
      </style>
    </head>
    <body>
      <script>
        var app = Elm.Main.fullscreen()
        // you can use ports and stuff here
        app.ports.getDim.subscribe(function(url){
          // recieve the url for the image through
          // the `getDim` port in Main.elm
          let img = new Image()
          img.src = url
          img.onload = function() {
            // send the height and width back to elm through
            // the `newDim` port in Main.elm
            app.ports.newDim.send([img.height, img.width])
          }
        })
      </script>
    </body>
    </html>