我使用[email protected]和[email protected]。我想畫一個SVG圖像,但SDL2圖像不支持此格式(見https://www.libsdl.org/projects/SDL_image/):如何將SVG柵格化爲Haskell中的SDL.Surface?
SDL_image是圖像文件加載庫。
它加載圖像作爲SDL表面和紋理,並支持以下格式:BMP,GIF,JPEG,LBM,PCX,PNG,PNM,TGA,TIFF,WEBP,XCF,XPM,XV
如何我加載一個SVG,縮放/調整它的大小並將其光柵化爲SDL.Surface
或SDL.Texture
?
編輯:
在C++中,你可以使用nanosvg庫:
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)
);
您必須對您傳遞給SDL_CreateRGBSurfaceFrom
圖像數據做了static_cast<void *>
。 Haskell的SDL.createRGBSurfaceFrom
(sdl2版本2.2.0)預計Data.Vector.Storable.Mutable.VectorIO Word8
作爲圖像數據。
我找到了一個有希望的庫rasterific-svg
該軟件包可以使SVG圖像或將其轉換爲PDF。
您可以使用drawingOfSvgDocument
或renderSvgDocument
進行渲染。但是,我不知道如何將結果轉換爲Data.Vector.Storable.Mutable.VectorIO Word8
。
編輯2:
我已經運行example現在。但是,渲染結果還不正確。
這SVG
呈現爲
{-# 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
你有什麼試過? 「sdl2-image不支持這種格式」是什麼意思?如果你認爲應該可以使用這些庫,我猜你可以編寫相應的C程序 - 如果有的話,可以隨意包含該程序。 – user2407038
我已經添加了一個使用nanosvg的C++解決方案,並引用了SDL2 Image支持的圖像格式。 – maiermic
因爲這是一個圖書館推薦問題而關閉的原因,這是SO的主題。只需谷歌「Haskell SVG渲染器」,你應該找到一些選擇。 – Cubic