Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate PNG output resolution from internal coordinate system #326

Open
adrhill opened this issue Nov 11, 2024 · 3 comments
Open

Separate PNG output resolution from internal coordinate system #326

adrhill opened this issue Nov 11, 2024 · 3 comments

Comments

@adrhill
Copy link

adrhill commented Nov 11, 2024

First of all, thanks for the awesome package, it's a joy to work with! The documentation is stellar as well.

I've created a few SVG illustrations that I'm very happy with. However, after modifying the output format to PNG (by changing @svg to @png), I've noticed that the resolution of the PNG corresponds to Luxor's internal coordinate system.

I find it rather bothersome to work around this, since I would have to scale all "internal" dimensions of my shape primitives just to obtain the output resolution I desire.
As a workaround, I currently output SVGs and convert them to PNG using Inkscape (e.g. inkscape -w 2000 input.png -o output.png). Is there a way to avoid this manual step and set DPI / scale PNGs internally?

@cormullion
Copy link
Member

A good question! I'm not too knowledgeable about this area - for me, PNGs are done in pixels/points, whereas SVGs are resolution-independent, to be scaled later if necessary. So I've not encountered your scenario.

These (https://www.cairographics.org/manual/cairo-Transformations.html#cairo-user-to-device) are the Cairo scaling functions; if you can work out how/when to call these to meet your requirements, I wonder if it could be integrated somehow... ?

@cormullion
Copy link
Member

cormullion commented Nov 12, 2024

Thinking about a workflow: does this encapsulate the problem:

function master()
    Drawing(500, 500, :svg)
    origin()
    background("blue")
    ngon(O, 100, 4, 0, :stroke)
    finish()
    return svgstring()
end

function main(;PPI=72)
    svgdrawing = readsvg(master())
    w = svgdrawing.width
    h = svgdrawing.height 
    Drawing(w, h, "/tmp/output.svg")
    origin()
    placeimage(svgdrawing, centered=true)
    finish()

    w = svgdrawing.width * PPI / 72
    h = svgdrawing.height * PPI / 72
    Drawing(w, h, "/tmp/output.png")
    origin()
    @layer begin
        scale(PPI/72)
        placeimage(svgdrawing, centered=true)
    end 
    finish()
    preview()
end

main(PPI=144)

@adrhill
Copy link
Author

adrhill commented Nov 12, 2024

These (https://www.cairographics.org/manual/cairo-Transformations.html#cairo-user-to-device) are the Cairo scaling functions; if you can work out how/when to call these to meet your requirements, I wonder if it could be integrated somehow... ?

The current transformation matrix, ctm, is a two-dimensional affine transformation that maps all coordinates and other drawing instruments from the user space into the surface's canonical coordinate system, also known as the device space.

I guess if ctm is the identity matrix by default, calling cairo_scale would do what I need?
A scaling between "user space" and "device space" might indeed be what I'm asking for here.

Thinking about a workflow: does this encapsulate the problem?

That would indeed fulfill my needs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants