Elm:获取图像的大小
Elm: Get the size of an image
我正在尝试获取图像的宽度和高度,所以给一个URL,该图像的宽度和高度是多少
我不相信有办法在 elm 中做到这一点。端口是一种可能的解决方案。您可以阅读它们 here. I've written a small example of your use case which you can run your self on 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>
我在评论中提到,如果你显示图像,你可以在没有端口的情况下做到这一点。这就是我所说的解决方案:
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
}
我正在尝试获取图像的宽度和高度,所以给一个URL,该图像的宽度和高度是多少
我不相信有办法在 elm 中做到这一点。端口是一种可能的解决方案。您可以阅读它们 here. I've written a small example of your use case which you can run your self on 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>
我在评论中提到,如果你显示图像,你可以在没有端口的情况下做到这一点。这就是我所说的解决方案:
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
}