Search code examples
imagemagick

I want to scale the sprite 8x with padding between pixels


There is a small sprite:

# mario sprite in base64 writing to file:
magick 'inline:data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAA7EAAAO
xAGVKw4bAAAA00lEQVQ4ja1UwRGDMAyTe7zLJmWUzMoodBO6gHmkhsRWcukVvYID
kiKbiKoqbsTjTjIAmLq7IvXzwGHahJ5sUKBJKKhf3rcVAPB8pZ5BTihyEcxLomuD
Fxhqyryk06WtDZ93LSB+bMqYvBtPBsQYA2FP3YPl2XUIAIpcsCZ5eRM18slvALyL
CoFAu5EApCn7tsbx+hY0U55llmkYG7NefuhzKAVFUv1Mm8L+EgKWa5zDQbIWqiNn
riuvID8g1r4c2Hi6Ghvg6sg/mqEIDv+9v2+/sQ8vtmAvY/Wf0QAAAABJRU5ErkJg
gg==' mario.png

I want to scale it 8x:

convert -scale 800%  -quality 100 mario.png mario-big.png

But scale with padding between pixels. To have an indent of 1 pixel between four adjacent eight times larger pixels. Or overlay a grid over the enlarged image.

How can I do this, please tell me?

Example:

mario.png


Solution

  • Updated Answer

    I'm not sure how to change the 2px spacing to 1px in my original answer. Here's another method which we can probably speed up and improve if it gets the results you want. I'm using my image below as it's a an easier size to see, but you can adjust the numbers to match your own image. I am also using the "wrong" colours so you can see where each one ends up, but again, you can change my mad colours to white:

    • Chop into rows, each row being 50px tall

    • Iterate over rows, chopping each into 50px wide chunks and recombining with 1px yellow spacing

    • Smush the new rows together vertically with 1px cyan spacing

    The code looks like this:

    #!/bin/bash
    
    # Chop into rows, each row being 50px tall
    magick artistic-swirl.jpg -crop x50 row-%02d.png
    
    # Iterate over rows, chopping each into 50px wide chunks and recombining with 1px spacing
    for f in row-*png ; do
       echo $f
       magick "$f" -crop 50x -background yellow +smush 1 "$f"
    done
    
    # Smush the new rows together vertically with 1px spacing
    magick row-*png -background cyan -smush 1 result.png
    

    enter image description here


    Note that +smush N joins images side-by-side with N px spacing in the background colour, but that -smush N joins images above-and-below with N px spacing.


    Here's what I get applying that to your image:

    #!/bin/bash
    
    # Chop into rows, each row being 50px tall
    magick mario.png -scale 800%  -crop x8 row-%02d.png
    
    # Iterate over rows, chopping each into 50px wide chunks and recombining with 1px spacing
    for f in row-*png ; do
       echo $f
       magick "$f" -crop 8x -background yellow +smush 1 "$f"
    done
    
    # Smush the new rows together vertically with 1px spacing
    magick row-*png -background cyan -smush 1 -bordercolor blue -border 1 result.png
    

    enter image description here


    Original Answer

    Not at a computer to test, but if you scale your image up to the correct size as you are currently doing, you should then be able to crop the image into tens/hundreds of individual 8x8 images and pipe them to a montage command to lay them out on a white background with a 1px spacing between all the individual 8x8 blocks.

    Something like:

    magick 'inline:data:...' -scale 800% -crop 8x8 miff:- | magick montage -background white -geometry +1+1 -tile Nx miff:- result.png
    

    where N is the number of 8x8 blocks you want in each row.


    Note that miff:- is an ImageMagick internal lossless transmission format.


    Back at a computer, I'll do something similar with this image:

    enter image description here

    magick artistic-swirl.jpg -scale 500x500 -crop 50x50 miff:- | magick montage -background yellow -geometry +5+5 -tile 10x miff:- result.png
    

    enter image description here