patternMinor
Converting image size from Maybe (Int, Int) to (Float, Float)
Viewed 0 times
imagefloatsizemaybeconvertingfromint
Problem
I have a function that returns size of an image
It would be nice to convert it to float tuple beautifully.
I am sure there must be a better way than what I currently have:
IO (Maybe (Int, Int))It would be nice to convert it to float tuple beautifully.
I am sure there must be a better way than what I currently have:
data Vec2D = Vec2D Float Float
getImageSize :: FilePath -> IO (Maybe (Int, Int))
getImageSize path = do
img return Nothing
Right img' -> return (go img')
where
go :: DynamicImage -> Maybe (Int, Int)
go (ImageRGB8 (Image w h _)) = Just (w, h)
go (ImageRGBA8 (Image w h _)) = Just (w, h)
go _ = Nothing
getImageSizeVec :: FilePath -> IO Vec2D
getImageSizeVec path = do
res <- getImageSize path
let dims = fromMaybe (0, 0) res
return $ Vec2D (fromIntegral (fst dims)) (fromIntegral (snd dims))Solution
- I do not understand what benefit you get from the conversion to float
- I would advise you to not mix -
IOwith the mostly pure calculation you have
so let us look at your code (minus the
IO)getImageSize :: DynamicImage -> Maybe (Int, Int)
getImageSize (ImageRGB8 (Image w h _)) = Just (w, h)
getImageSize (ImageRGBA8 (Image w h _)) = Just (w, h)
getImageSize _ = Nothingbut
readImage already has a more useful return type than Maybe it has an Either String which is giving you error messages instead of Nothing so we can adjust.getImageSize :: DynamicImage -> Either String (Int, Int)
getImageSize (ImageRGB8 (Image w h _)) = Right (w, h)
getImageSize (ImageRGBA8 (Image w h _)) = Right (w, h)
getImageSize _ = Left "Image type neither ImageRGB8 or ImageRGBA8"this section could be improved a bit - also working on pure data
sizeToVec :: (Int,Int) -> Vec2D
sizeToVec (x,y) = Vec2D (fromIntegral x) (fromIntegral y)you can then use those with the many mechanisms haskell provides you:
readImage path :: IO (Either String DynamicImage)
getImageSize :: DynamicImage -> Either String (Int, Int)
sizeToVec :: (Int,Int) -> Vec2Dthe last two you can combine à la
fmap sizeToVec (getImageSize img) -- or fmap sizeToVec . getImageSizeand the first two
doStuff = do eitherImg <- readImg mypathtoimg
return $ do size <- getImageSize
sizeToVec sizeor
doStuff = do eitherImg >= sizeToVec)or even shorter
doStuff = readImg mypathtoimg >>= (getImageSize >>= sizeToVec)doStuff = readImg path >>= fmap sizeToVec . getImageSizeif I am not mistaken (I have no haskell env on this machine, therefore this code is untested - sorry)
Code Snippets
getImageSize :: DynamicImage -> Maybe (Int, Int)
getImageSize (ImageRGB8 (Image w h _)) = Just (w, h)
getImageSize (ImageRGBA8 (Image w h _)) = Just (w, h)
getImageSize _ = NothinggetImageSize :: DynamicImage -> Either String (Int, Int)
getImageSize (ImageRGB8 (Image w h _)) = Right (w, h)
getImageSize (ImageRGBA8 (Image w h _)) = Right (w, h)
getImageSize _ = Left "Image type neither ImageRGB8 or ImageRGBA8"sizeToVec :: (Int,Int) -> Vec2D
sizeToVec (x,y) = Vec2D (fromIntegral x) (fromIntegral y)readImage path :: IO (Either String DynamicImage)
getImageSize :: DynamicImage -> Either String (Int, Int)
sizeToVec :: (Int,Int) -> Vec2Dfmap sizeToVec (getImageSize img) -- or fmap sizeToVec . getImageSizeContext
StackExchange Code Review Q#116590, answer score: 2
Revisions (0)
No revisions yet.