Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Haskell中将SVG光栅化为SDL.Surface?_Haskell_Svg_Sdl 2_Haskell Stack_Haskell Sdl - Fatal编程技术网

如何在Haskell中将SVG光栅化为SDL.Surface?

如何在Haskell中将SVG光栅化为SDL.Surface?,haskell,svg,sdl-2,haskell-stack,haskell-sdl,Haskell,Svg,Sdl 2,Haskell Stack,Haskell Sdl,我正在使用和。我想绘制SVG图像,但sdl2图像不支持此格式(请参阅): SDL_图像是一个图像文件加载库。 它将图像加载为SDL曲面和纹理,并支持以下格式:BMP、GIF、JPEG、LBM、PCX、PNG、PNM、TGA、TIFF、WEBP、XCF、XPM、XV 如何加载SVG、缩放/调整SVG大小并将其栅格化为SDL.Surface或SDL.Texture 编辑: 在C++中你可以使用库: 我还没有用真正的代码对此进行测试,但希望它在正确的轨道上: 获取一个IO(图像像素RGBA8),其中结

我正在使用和。我想绘制SVG图像,但sdl2图像不支持此格式(请参阅):

SDL_图像是一个图像文件加载库。
它将图像加载为SDL曲面和纹理,并支持以下格式:BMP、GIF、JPEG、LBM、PCX、PNG、PNM、TGA、TIFF、WEBP、XCF、XPM、XV

如何加载SVG、缩放/调整SVG大小并将其栅格化为
SDL.Surface
SDL.Texture

编辑:

在C++中你可以使用库:


我还没有用真正的代码对此进行测试,但希望它在正确的轨道上:

获取一个
IO(图像像素RGBA8)
,其中结果类型来自JuicyPixels图像库

获取一个(
Storable
向量(PixelBaseComponent PixelRGBA8)
,在跟踪所有类型后,我猜它是一个
向量字8


或者(阅读文档了解重要的安全信息)为您获取不可变的
向量的可变副本(或视图,用于不安全的变体)

您尝试了什么?“sdl2图像不支持此格式”是什么意思?如果你相信这些LIBS可能是可行的,我猜你可以编写相应的C程序——如果是的话,请随意加入这个程序。我添加了一个C++解决方案,使用NANOSVG并引用SDL2图像的支持图像格式。这是离题的。只需谷歌“Haskell SVG渲染器”,您应该可以找到一些选项。我的例子是C++,需要另一个库NANOSVG。您必须对图像数据执行
静态\u cast
。Haskell的
SDL.createRGBSurfaceFrom
期望
Data.Vector.Storable.Mutable.VectorIO Word8
作为图像数据。我不知道如何在有库或没有库的情况下获取这种类型的图像数据。根据您的建议,我在问题中添加了一个运行示例。但是,它没有呈现正确的结果。我想我必须要转换像素数据。@ MaiMIC我想你可能需要把音高设置为宽度的4倍,就像你的C++例子一样。我忽略了这一点。我还忽略了使用
abgr888
而不是
rgba888
@maiermit SDL/OpenGL和Rasterific.Svg(rgba888 vs abgr888)中的像素格式不匹配的原因是什么?我不确定,我理解你的问题。您对我的跑步示例的固定版本感兴趣吗?
NSVGimage * svg_image = nsvgParseFromFile(filepath.c_str(), "px", 96.0);
std::vector<Uint8> img_data;
img_data.resize(width * height * 4);

NSVGrasterizer * rasterizer = nsvgCreateRasterizer()
nsvgRasterize(rasterizer,
              svg_image, 0,0,1,
              img_data.data(),
              width, height,
              width * 4);

SDL_Surface * surface = SDL_CreateRGBSurfaceFrom(
                          static_cast<void *>(img_data.data()),
                          width, height,
                          32,         // depth
                          4 * width,  // pitch
                          0x000000FF, // red mask
                          0x0000FF00, // green mask
                          0x00FF0000, // blue mask
                          0xFF000000  // alpha mask (alpha in this format)
                        );
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Codec.Picture
import Codec.Picture.Types
import Data.Vector.Storable.Mutable (IOVector)
import Data.Vector.Generic (thaw)
import Graphics.Rasterific.Svg
       (loadCreateFontCache, renderSvgDocument)
import Graphics.Svg (loadSvgFile)

import Data.Function (fix)
import Data.Word (Word8)

import Control.Monad as CM
import qualified Data.Vector.Generic.Mutable as GM
import Data.Vector.Storable (Vector)
import qualified Data.Vector.Storable as V

import Foreign.C.Types (CInt)
import qualified SDL
import SDL.Vect (Point(P), V2(V2), V4(V4))

import Control.Concurrent (threadDelay)
import SDL (($=))

import Paths_render_svg_in_sdl2_haskell (getDataFileName)

screenWidth, screenHeight :: CInt
(screenWidth, screenHeight) = (1280, 720)

-- SDL dependency: sudo apt-get install libsdl2-dev
main :: IO ()
main = do
  SDL.initialize [SDL.InitVideo, SDL.InitTimer, SDL.InitEvents]
    -- ensure render quality
  SDL.HintRenderScaleQuality $= SDL.ScaleLinear
  do renderQuality <- SDL.get SDL.HintRenderScaleQuality
     CM.when (renderQuality /= SDL.ScaleLinear) $
       putStrLn "Warning: Linear texture filtering not enabled!"
  window <-
    SDL.createWindow
      "Load and render SVG"
      SDL.defaultWindow
      { SDL.windowPosition = SDL.Centered
      , SDL.windowInitialSize = V2 screenWidth screenHeight
      }
  SDL.showWindow window
  renderer <-
    SDL.createRenderer
      window
      (-1)
      SDL.RendererConfig
      { SDL.rendererType = SDL.AcceleratedVSyncRenderer
      , SDL.rendererTargetTexture = True
      }
  SDL.rendererDrawColor renderer $= V4 maxBound maxBound maxBound maxBound
  SDL.clear renderer
  renderSvgExample renderer
  SDL.present renderer
  threadDelay 2000000
  SDL.destroyRenderer renderer
  SDL.destroyWindow window
  SDL.quit

renderSvgExample :: SDL.Renderer -> IO ()
renderSvgExample renderer = do
  mimage <- getDataFileName "thumbs-up.svg" >>= loadSVGImage
  case mimage of
    Nothing -> putStrLn "Image convertion failed."
    (Just image) -> do
      let surfaceSize :: V2 CInt
          surfaceSize = V2 screenWidth screenHeight
      surface <- createSurfaceFromSVG image surfaceSize
      texture <- SDL.createTextureFromSurface renderer surface
      SDL.freeSurface surface
      let source = SDL.Rectangle (P $ V2 0 0) surfaceSize
          dest = SDL.Rectangle (P $ V2 0 0) surfaceSize
          angle = 0.0
          center = Nothing
          flipNone = V2 False False
      SDL.copyEx
        renderer
        texture
        (Just source)
        (Just dest)
        angle
        center
        flipNone
      SDL.destroyTexture texture

createSurfaceFromSVG :: Image PixelRGBA8 -> V2 CInt -> IO SDL.Surface
createSurfaceFromSVG image surfaceSize = do
  let rawImageData :: Vector Word8
      rawImageData = imageData image
      imWidth :: Int
      imWidth = imageWidth image
      pitch :: CInt
      pitch = fromIntegral imWidth
  mutableVector <- convertToMutableVector rawImageData
  SDL.createRGBSurfaceFrom mutableVector surfaceSize pitch SDL.RGBA8888

convertToMutableVector :: Vector Word8 -> IO (IOVector Word8)
convertToMutableVector= thaw

loadSVGImage :: FilePath -> IO (Maybe (Image PixelRGBA8))
loadSVGImage filepath = do
  mdoc <- loadSvgFile filepath
  case mdoc of
    Nothing -> return Nothing
    Just doc -> do
      cache <- loadCreateFontCache "fonty-texture-cache"
      (finalImage, _) <- renderSvgDocument cache Nothing 96 doc
      return $ Just finalImage