I'd like to build a function that takes a given Unicode character and a given TrueType font and rasterises the corresponding glyph into a two-dimensional 1-bit-per-pixel bitmap.
Something similar to this:
rasterize :: Font -> Char -> Size -> Bitmap
rasterize font char size = ...
Requirements
The rasterize function should:
produce a bitmap of maximal width w and height h, such that w <= size and h <= size
rasterize the glyph so that it completely fills the bitmap, leaving no padding.
The Bitmap type should support the following operations (or similar):
width :: Bitmap -> Int
height :: Bitmap -> Int
bit :: Bitmap -> (Int, Int) -> Bool
where bit b (x, y) should evaluate to True if (and only if) the bit within Bitmap b at index position (x, y) is set.
Question
Are there any Haskell libraries that can already do this, or something similar?
Example
Evaluating the expression rasterize fontUtopiaStandard 'o' 64 would result in a Bitmap b that if rendered would look similar to the following image (viewed at 800% scale, with grid), where (width b, height b) = (60, 64):
Notes
I've already tried using the stb-truetype package, but any attempts to get at the pixel data seem to cause segmentation faults, even when compiling with version of GHC (6.12) similar to the version on which the package was tested. (I can provide more details of the segfaulting code if anyone's interested.)
I'm aware of the existence of libraries that render TrueType fonts within an OpenGL context, but I can't see how to get access to the pixel data.
Related
I'm very new to Haskell so I apologise if this is too basic, or if it makes very little sense. I'm trying to read an image; I can get it to a list of pixel data with the following code:
data Pixel = Pixel {
red :: Integer,
green :: Integer,
blue :: Integer,
alpha :: Integer
} deriving (Show)
getImagePixelArray :: FilePath -> IO (Codec.Picture.Repa.Img RGBA)
getImagePixelArray fp = do
img <- (either error return =<< readImageRGBA fp)
return img
getImagePixelData :: Codec.Picture.Repa.Img RGBA -> [(Word8,Word8,Word8,Word8)]
getImagePixelData img = R.toList (collapseColorChannel img)
rawPixelToPixel :: (Word8,Word8,Word8,Word8) -> Pixel
rawPixelToPixel (r, g, b, a) = Pixel {
red = (toInteger r),
green = (toInteger g),
blue = (toInteger b),
alpha = (toInteger a)
}
main = do
imageData <- getImagePixelArray "./images/image1.png"
let imageRawPixels = getImagePixelData imageData
let asPixels = Prelude.map rawPixelToPixel imageRawPixels
mapM print asPixels
I more or less follow what's going on, but my knowledge of Haskell is still limited, so when it comes to making sense of api documentation, I'm struggling a little.
I really want to be able to parse the positions of the pixels; I understand how to do that if I know the width and height of an image, but I can't figure out how to get the width/height of an image.
I'm making my way through a Haskell course, but I'm also trying to put it to some practical use along the way to help the concepts sink in.
Start with the documentation. None of what you're asking for is obviously available on Img, so where else could it be? There's a related Image type, mentioned in convertImage's documentation - I wonder what that is. As it turns out, it has a width and a height. How can we get an Image from our Img, then? imgToImage will give us a DynamicImage, which has several constructors each containing an Image. Figure out what kind of Image you have inside your DynamicImage, and then ask that Image its dimensions.
Perhaps there is something easier with the other lens-y stuff in that module, but it is not obvious to me, and this approach seems simple enough, if a hassle.
In the Haskell Gloss library, one draws text with the Text constructor of the Picture type. But how, then does one find the width (and height) of such a picture?
Here's how text is rendered in Gloss:
Text str
-> do
GL.blend $= GL.Disabled
GL.preservingMatrix $ GLUT.renderString GLUT.Roman str
GL.blend $= GL.Enabled
The important point here is that it calls renderString. Looking at the documentation for renderString, we immediately see two other useful functions: stringWidth and fontHeight. As such, you can get your width and height like this:
import Graphics.UI.GLUT.Fonts
do
width <- stringWidth Roman str
height <- fontHeight Roman
Does anyone know how to read a pixel from images using Haskell? I am now using a juicy pixel as a library.
Thanks for your help!
JuicyPixel provides the pixelAt function to get a pixel at a given coordinate.
pixelAt :: Image a -> Int -> Int -> a
Extract a pixel at a given position, (x, y), the origin is assumed to be at the corner top left, positive y to the bottom of the image
I am trying to write some test cases using HUnit in Haskell for a function using the Gloss Graphics library.
The function:
makePicture :: Color -> Picture
makePicture c = Color c $ Circle 80
If I display a call to this function with argument "black" in a console you see something like:
Color (RGBA 0.0 0.0 0.0 1.0) (Circle 80.0)
Which has the type of a Picture. My question is how do I properly write a test case for something like this?
The problem occurs if I try to write a test like:
test = TestCase $ assertEqual "makePicture" (Color (RGBA 0.0 0.0 0.0 1.0) (Circle 80.0)) (makePicture black)
It can't compile, because it says the following:
error: Data constructor not in scope: RGBA
Anyone have any ideas how I can write a test case for my function?
I don't know where you are getting the RGBA constructor, but looking at the haddocks there is no such constructor for a Color. You probably want the makeColor function:
makeColor :: Float -> Float -> Float -> Float -> Color
EDIT: And yes, user24...38 is right there exists an RGBA but in the version of Gloss I'm looking at it is part of an Internal module and not exported elsewhere. As a general rule, external users should not leverage Internal modules since the API might change or the interface can be somehow unsafe (ex: not maintaining invariants).
I want to create a type Pixel, and make it an instance of the Eq and Show class. However, i've been reading information from a lot of places, and got really confused with this.
Here's some info on the type i need to create:
I have to store two numbers (the position of the pixel and a value from 0 to 255).
Two pixels are equal if they have the same value, whatever their position is.
For the Show instance, i need to print the position and the value.
Here's my attempt at this:
type position = Float
type greyScale = Int
type Pixel = (position, greyScale)
instance Eq Pixel where
greyScale == greyScale = True
instance Show Pixel where
show position = position
show greyScale = greyScale
is this a correct way to do it ?
Type names have to start with a capital letter. So, your definitions actually should look like this, since you are only defining type synonyms:
type Position = Float
type GreyScale = Int
For Pixel: It looks like you wanted to define a data type, not just a synonym, so you should do something like this:
data Pixel = Pixel Position GreyScale
Next: The Eq instance compares two Pixels, so you have to represent them as such:
instance Eq Pixel where
Pixel pos1 greyScale1 == Pixel pos2 greyScale2 = greyScale1 == greyScale2
greyScale1 == greyScale2 just compares the two greyScales, which is what you want.
Also, I would not recommend overwriting Show instances to assure that read . show == id holds. (You can automatically derive specific instances by adding deriving (Instance1, Instance2, ..) after the datatype declaration). Rather than meddling with it I would define separate functions:
showPosition :: Pixel -> String
showPosition (Pixel position greyScale) = show position
and
showGreyscale :: Pixel -> String
showGreyscale (Pixel position greyScale) = show greyScale