榆树:获取图像的大小

Ani*_*eit 7 image-scaling elm

我试图获取图像的宽度和高度,所以给出一个URL,该图像的宽度和高度是多少

Tyl*_*son 8

我不相信榆树有办法做到这一点.端口是一种可能的解决方案 你可以在这里阅读它们.我写了一个你的用例的小例子,你可以在ellie上运行你的自我.在此示例中,我使用您在注释中提供的JS示例,但还有其他可能的解决方案,例如事件侦听器或查询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
Run Code Online (Sandbox Code Playgroud)

的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>
Run Code Online (Sandbox Code Playgroud)

  • 正如 Slack 中的某人指出的那样,如果您打算在 dom 中显示图像,您可以在 elm 中附加一个 onload 处理程序并从中获取大小,这样您就不需要端口。但是,如果您不想在 dom 中显示图像,那么您提供的答案是迄今为止我找到的最佳答案。 (2认同)

Ani*_*eit 5

我在评论中提到,如果您显示图像,则无需端口即可执行此操作。这是我正在谈论的解决方案:

module Main exposing (main)

import Browser
import Debug exposing (toString)
import Html exposing (Html, div, img, text)
import Html.Attributes exposing (src)
import Html.Events exposing (on)
import Json.Decode as Decode


type alias Model =
    { imageDimensions : Maybe ImgDimensions }


initialModel : Model
initialModel =
    { imageDimensions = Nothing }


type Msg
    = ImgLoaded ImgDimensions


update : Msg -> Model -> Model
update msg model =
    case msg of
        ImgLoaded dimensions ->
            { model | imageDimensions = Just dimensions }


type alias ImgDimensions =
    { width : Int
    , height : Int
    }


decodeImgLoad msg =
    Decode.map msg <|
        Decode.field "target" <|
            Decode.map2 ImgDimensions
                (Decode.field "width" Decode.int)
                (Decode.field "height" Decode.int)


view : Model -> Html Msg
view model =
    div []
        [ text <| "Image Loaded = " ++ toString model.imageDimensions
        , img
            [ on "load" (decodeImgLoad ImgLoaded)
            , src "https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/bd07f82e-a30d-4e93-a2cf-0c16ea2b7f40/08-owl-opt.jpg"
            ]
            []
        ]


main : Program () Model Msg
main =
    Browser.sandbox
        { init = initialModel
        , view = view
        , update = update
        }
Run Code Online (Sandbox Code Playgroud)

https://ellie-app.com/3FCdcDqy4gqa1