
I finally came up with a solution that suits my context. For those interested, I'm supplying it here. Safely get a surface containing your .png image (note that the surface has to be freed when you're done with it using surfaceFinish) imageSurfaceCreateFromPNG :: FilePath -> IO Surface imageSurfaceCreateFromPNG file = withImageSurfaceFromPNG file $ \png -> do w <- renderWith png $ imageSurfaceGetWidth png h <- renderWith png $ imageSurfaceGetHeight png surf <- createImageSurface FormatRGB24 w h renderWith surf $ do setSourceSurface png 0 0 paint return surf Now the unsafe part (hack until I have an associative list storing my images to pull into relevant pages for rendering): unsafeLoadPNG file = unsafePerformIO $ imageSurfaceCreateFromPNG file This allows drawing an image directly in a Render () context: paintImage :: FilePath -> Double -> Double -> Render () paintImage file x y = do surf <- return $ unsafeLoadPNG file setSourceSurface surf x y paint Looking at this irc log from 2005: http://www.cse.unsw.edu.au/~dons/code/irc-logs/05.11.20 someone's had this problem before, and although they did not show their solution, I think it might've been similar to mine. Hope this helps the next person to get stuck. Sincerely, Rafal Kolanski.