Open liamoc opened 8 years ago
Hi, do you have some code?
I already encountered the problem in #15 and the fix were to shift the position by 0.5px (as can be seen in the commit
Hi @Twinside
This topic came up again a few weeks ago in https://groups.google.com/g/diagrams-discuss/c/TRtnvrQaT-k/m/LPq6iqmTBAAJ?pli=1
The following code demonstrates the issue.
import Codec.Picture
import Graphics.Rasterific
main :: IO ()
main = do
i <- readPng "tiny-rectangle.png"
case i of
Left err -> error err
Right img -> do
let d = drawImage (convertRGBA8 img) 0.0 (V2 0 0)
let img2 = renderDrawing 4 5 (PixelRGBA8 0 0 0 0) d
writePng "tiny-rectangle-out.png" img2
With the following "tiny-rectangle.png" image: (a 4x5 image with a red box and a black line through it, it only appears blurry in the browser)
The following patch seems to fix the issue:
diff --git src/Graphics/Rasterific.hs src/Graphics/Rasterific.hs
index 088248d..e60e2ac 100644
--- src/Graphics/Rasterific.hs
+++ src/Graphics/Rasterific.hs
@@ -823,8 +823,8 @@ drawImageAtSize img@Image { imageWidth = w, imageHeight = h } borderSize ip
stroke (borderSize / 2) (JoinMiter 0)
(CapStraight 0, CapStraight 0) rect'
where
- p = ip ^-^ V2 0.5 0.5
- rect = rectangle (V2 0 0) rw rh
+ p = ip ^+^ V2 0.5 0.5
+ rect = rectangle (V2 (-0.5) (-0.5)) rw rh
rect' = rectangle p reqWidth reqHeight
My analysis was:
With the current code, in Graphics.Rasterific.Immediate.fillWithTexture
, if we print "els" (the shape of the image we want to render) we get:
[LinePrim Line (V2 (-0.5) (-0.5)) (V2 3.5 (-0.5))
,LinePrim Line (V2 3.5 (-0.5)) (V2 3.5 4.5)
,LinePrim Line (V2 3.5 4.5) (V2 (-0.5) 4.5)
,LinePrim Line (V2 (-0.5) 4.5) (V2 (-0.5) (-0.5))]
Notice the (-0.5,-0.5)
translation.
It then gets clipped to:
[LinePrim Line (V2 0.0 0.0) (V2 3.5 0.0)
,LinePrim Line (V2 3.5 0.0) (V2 3.5 0.0)
,LinePrim Line (V2 3.5 0.0) (V2 3.5 0.0)
,LinePrim Line (V2 3.5 0.0) (V2 3.5 0.125)
,LinePrim Line (V2 3.5 0.125) (V2 3.5 0.75)
,LinePrim Line (V2 3.5 0.75) (V2 3.5 2.0)
,LinePrim Line (V2 3.5 2.0) (V2 3.5 4.5)
,LinePrim Line (V2 3.5 4.5) (V2 1.5 4.5)
,LinePrim Line (V2 1.5 4.5) (V2 0.5 4.5)
,LinePrim Line (V2 0.5 4.5) (V2 0.0 4.5)
,LinePrim Line (V2 0.0 4.5) (V2 0.0 4.5)
,LinePrim Line (V2 0.0 4.5) (V2 0.0 0.0)]
My guess is that ^-^ V2 0.5 0.5
in drawImageAtSize
was added to compensate for line sampling (hence rectangle sampling) which adds (0.5,0.5) to every sample coordinate (probably to get at the center of the pixels).
Texture sampling seems to use final image coordinates according to the comment in Graphics.Rasterific.Texture
. So if we remove the correction:
- p = ip ^-^ V2 0.5 0.5
+ p = ip
We get the correct shape after clipping:
[LinePrim Line (V2 0.0 0.0) (V2 4.0 0.0)
,LinePrim Line (V2 4.0 0.0) (V2 4.0 5.0)
,LinePrim Line (V2 4.0 5.0) (V2 0.0 5.0)
,LinePrim Line (V2 0.0 5.0) (V2 0.0 0.0)]
But we don't compensate the (0.5,0.5) translation in samples anymore so the output is still bad.
We can also change:
- rect = rectangle (V2 0 0) rw rh
+ rect = rectangle (V2 (-0.5) (-0.5)) rw rh
to compensate, but then the coordinates are (-0.5,-0.5) off. So finally we also need to do:
- p = ip ^-^ V2 0.5 0.5
+ p = ip ^+^ V2 0.5 0.5
Hi,
I was hoping to use this library to render some pixel art for a game I'm making by composing various pre-drawn images and shapes together. The issue I've encountered is that if you use an image it isn't rendered pixel-perfect, even when it is not scaled. Here's an example, where I'm trying to render each letter of a bitmap font, next to each other. Two of the letters are shown below the output of my little program. You can see how the output is "fuzzy", whereas the input is crisp.