【问题标题】:Elm: Get the size of an imageElm:获取图像的大小
【发布时间】:2018-07-11 03:08:16
【问题描述】:

我正在尝试获取图像的宽度和高度,所以给一个网址,该图像的宽度和高度是多少

【问题讨论】:

  • 试试如何?你有minimal reproducible example 可以添加到问题中吗?
  • 我不太确定如何开始,我想也许我的问题更多的是如何在 elm 中获取图像的大小。 Javascript 我可以创建一个 Image() 元素并设置它的 url,然后 onload 读取它的宽度和高度。如何在不移植到 js 的情况下在 elm 中做这样的事情
  • 您是否使用 Elm 来定位浏览器内的目标?如果是这样,也许能够以某种方式使用/适应这种技术(我是 Elm 新手):stackoverflow.com/questions/623172/…

标签: elm image-scaling


【解决方案1】:

我不相信 elm 有办法做到这一点。端口是一种可能的解决方案。你可以阅读他们here。我已经为您的用例编写了一个小示例,您可以在 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

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>

【讨论】:

  • 正如 slack 中的某个人指出的那样,如果您打算在 dom 中显示图像,您可以在 elm 中附加一个 onload 处理程序并从中获取大小,因此您不需要端口.但是,如果您不想在 dom 中显示图像,那么您提供的答案是迄今为止我找到的最佳答案。
  • @AnisJonischkeit 将有关该方法的一些详细信息作为另一个答案会很有帮助。或者至少是到松弛线程存档的某种链接。
  • @CoderDennis,我已经发布了这个解决方案的另一个答案。
【解决方案2】:

我在评论中提到,如果您显示图像,则可以在没有端口的情况下执行此操作。这就是我所说的解决方案:

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
        }

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

【讨论】:

    猜你喜欢
    • 2012-07-20
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 2011-12-15
    • 2012-01-21
    • 2023-03-28
    相关资源
    最近更新 更多