{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Diagrams.TwoD.Input
( loadImageEmbedded
, loadImageExternal
) where
import Control.Monad (msum)
import Codec.Picture
import Codec.Picture.Types (dynamicMap)
import Data.Semigroup
import Data.Typeable (Typeable)
import Diagrams.Core
import Diagrams.TwoD.Image
import Diagrams.TwoD.Size
import Diagrams.TwoD.Types
import qualified Diagrams.TwoD.Text as TT
import Diagrams.SVG.ReadSVG (readSVGFile, InputConstraints)
import Diagrams.SVG.Tree (Place)
import Filesystem.Path.CurrentOS (decodeString)
loadImageEmbedded :: (InputConstraints b n, Renderable (TT.Text n) b, Read n, n ~ Place)
=> String -> IO (Either String (QDiagram b V2 n Any))
loadImageEmbedded :: String -> IO (Either String (QDiagram b V2 n Any))
loadImageEmbedded String
path = do
Either String DynamicImage
dImg <- String -> IO (Either String DynamicImage)
readImage String
path
Either String (QDiagram b V2 n Any)
svgImg <- FilePath -> IO (Either String (Diagram b))
forall b n.
(V b ~ V2, N b ~ n, RealFloat n, Renderable (Path V2 n) b,
Renderable (DImage n Embedded) b, Typeable b, Typeable n, Show n,
Read n, n ~ Place, Renderable (Text n) b) =>
FilePath -> IO (Either String (Diagram b))
readSVGFile (String -> FilePath
decodeString String
path)
Either String (QDiagram b V2 n Any)
-> IO (Either String (QDiagram b V2 n Any))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (QDiagram b V2 n Any)
-> IO (Either String (QDiagram b V2 n Any)))
-> Either String (QDiagram b V2 n Any)
-> IO (Either String (QDiagram b V2 n Any))
forall a b. (a -> b) -> a -> b
$ [Either String (QDiagram b V2 n Any)]
-> Either String (QDiagram b V2 n Any)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ Either String (QDiagram b V2 n Any)
svgImg,
(DynamicImage -> QDiagram b V2 n Any)
-> Either String DynamicImage
-> Either String (QDiagram b V2 n Any)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DImage n Embedded -> QDiagram b V2 n Any
forall n a b.
(TypeableFloat n, Typeable a, Renderable (DImage n a) b) =>
DImage n a -> QDiagram b V2 n Any
image(DImage n Embedded -> QDiagram b V2 n Any)
-> (DynamicImage -> DImage n Embedded)
-> DynamicImage
-> QDiagram b V2 n Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
.DynamicImage -> DImage n Embedded
forall a. Num a => DynamicImage -> DImage a Embedded
rasterImage) Either String DynamicImage
dImg ]
where
rasterImage :: DynamicImage -> DImage a Embedded
rasterImage DynamicImage
img = ImageData Embedded
-> Int -> Int -> Transformation V2 a -> DImage a Embedded
forall b a.
ImageData b -> Int -> Int -> Transformation V2 a -> DImage a b
DImage (DynamicImage -> ImageData Embedded
ImageRaster DynamicImage
img) ((forall pixel. Pixel pixel => Image pixel -> Int)
-> DynamicImage -> Int
forall a.
(forall pixel. Pixel pixel => Image pixel -> a)
-> DynamicImage -> a
dynamicMap forall a. Image a -> Int
forall pixel. Pixel pixel => Image pixel -> Int
imageWidth DynamicImage
img) ((forall pixel. Pixel pixel => Image pixel -> Int)
-> DynamicImage -> Int
forall a.
(forall pixel. Pixel pixel => Image pixel -> a)
-> DynamicImage -> a
dynamicMap forall a. Image a -> Int
forall pixel. Pixel pixel => Image pixel -> Int
imageHeight DynamicImage
img) Transformation V2 a
forall a. Monoid a => a
mempty
loadImageExternal :: (InputConstraints b n, Renderable (DImage n External) b)
=> FilePath -> IO (Either String (QDiagram b V2 n Any))
loadImageExternal :: String -> IO (Either String (QDiagram b V2 n Any))
loadImageExternal String
path = do
Either String DynamicImage
dImg <- String -> IO (Either String DynamicImage)
readImage String
path
Either String (QDiagram b V2 n Any)
-> IO (Either String (QDiagram b V2 n Any))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (QDiagram b V2 n Any)
-> IO (Either String (QDiagram b V2 n Any)))
-> Either String (QDiagram b V2 n Any)
-> IO (Either String (QDiagram b V2 n Any))
forall a b. (a -> b) -> a -> b
$ [Either String (QDiagram b V2 n Any)]
-> Either String (QDiagram b V2 n Any)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ (DynamicImage -> QDiagram b V2 n Any)
-> Either String DynamicImage
-> Either String (QDiagram b V2 n Any)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DImage n External -> QDiagram b V2 n Any
forall n a b.
(TypeableFloat n, Typeable a, Renderable (DImage n a) b) =>
DImage n a -> QDiagram b V2 n Any
image(DImage n External -> QDiagram b V2 n Any)
-> (DynamicImage -> DImage n External)
-> DynamicImage
-> QDiagram b V2 n Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
.DynamicImage -> DImage n External
rasterPath) Either String DynamicImage
dImg ]
where
rasterPath :: DynamicImage -> DImage n External
rasterPath DynamicImage
img = ImageData External
-> Int -> Int -> Transformation V2 n -> DImage n External
forall b a.
ImageData b -> Int -> Int -> Transformation V2 a -> DImage a b
DImage (String -> ImageData External
ImageRef String
path) ((forall pixel. Pixel pixel => Image pixel -> Int)
-> DynamicImage -> Int
forall a.
(forall pixel. Pixel pixel => Image pixel -> a)
-> DynamicImage -> a
dynamicMap forall a. Image a -> Int
forall pixel. Pixel pixel => Image pixel -> Int
imageWidth DynamicImage
img) ((forall pixel. Pixel pixel => Image pixel -> Int)
-> DynamicImage -> Int
forall a.
(forall pixel. Pixel pixel => Image pixel -> a)
-> DynamicImage -> a
dynamicMap forall a. Image a -> Int
forall pixel. Pixel pixel => Image pixel -> Int
imageHeight DynamicImage
img) Transformation V2 n
forall a. Monoid a => a
mempty