Skip to content

Instantly share code, notes, and snippets.

@scruss
Created January 21, 2026 20:09
Show Gist options
  • Select an option

  • Save scruss/5ee5bf8c9623efd712cd506e448998b1 to your computer and use it in GitHub Desktop.

Select an option

Save scruss/5ee5bf8c9623efd712cd506e448998b1 to your computer and use it in GitHub Desktop.
shell scripts to convert to/from C64 "The Print Shop" graphics
#!/usr/bin/env bash
# c64ps_to_png.sh - convert a 44x45 bitmap from C64 "The Print Shop" to PNG
# scruss, 2026-01
# uses NetPBM
# usage: c64ps_to_png.sh infile outfile
# outfile will be overwritten
#
# NB: output resolution was chosen arbitarily
tmpdir=$(mktemp -d)
trap 'rm -rf ${tmpdir}' EXIT
affix=$(printf "%04x" "$RANDOM")
tmp1="$tmpdir/tmp1.$affix"
tmp2="$tmpdir/tmp2.$affix"
# usage
if
[ "$#" -lt 2 ]
then
echo usage: "$0" infile outfile
exit 1
fi
# netpbm check
which -s anytopnm
if
[ "$?" -eq 1 ]
then
echo "$0" needs NetPBM installed to work
exit 1
fi
# Print Shop C64 file format: 44 x 45 px bitmap, 272 bytes
# - two byte header: 0x00 0x58
# - 45 rows of six bytes each. Last four bits per row are zero and ignored
# (image is effectively 48 px wide, including ignored 4 px at RHS)
# create fake PBM header
echo -en "P4\n48 45\n" > "$tmp1"
# remove two byte header
dd if="$1" bs=1 skip=2 of="$tmp2" > /dev/null 2>&1
# create output if inputs are there
if
[ -f "$tmp1" ]
then
if
[ -f "$tmp2" ]
then
cat "$tmp1" "$tmp2" |\
pnmcut -top 0 -left 0 -width 44 -height 45 |\
pnmtopng -size='500 500 1' > "$2"
else
echo "$0" internal error working file "$tmp2" missing
exit 1
fi
else
echo "$0" internal error working file "$tmp1" missing
exit 1
fi
#!/usr/bin/env bash
# image_to_c64ps.sh - convert an image to 44x45 bitmap for C64 "The Print Shop"
# scruss, 2026-01
# uses NetPBM
# usage: image_to_c64ps.sh infile outfile
# outfile will be overwritten
#
# NB: will pad a smaller-than 44x45 image up to the right size, but makes
# no attempt to centre the image.
# If you want a white margin, put one in yourself.
tmpdir=$(mktemp -d)
trap 'rm -rf ${tmpdir}' EXIT
affix=$(printf "%04x" "$RANDOM")
tmp1="$tmpdir/tmp1.$affix"
tmp2="$tmpdir/tmp2.$affix"
tmp3="$tmpdir/tmp3.$affix"
tmp4="$tmpdir/tmp4.$affix"
# usage
if
[ "$#" -lt 2 ]
then
echo usage: "$0" infile outfile
exit 1
fi
# netpbm check
which -s anytopnm
if
[ "$?" -eq 1 ]
then
echo "$0" needs NetPBM installed to work
exit 1
fi
# Print Shop C64 file format: 44 x 45 px bitmap, 272 bytes
# - two byte header: 0x00 0x58
# - 45 rows of six bytes each. Last four bits per row are zero and ignored
# (image is effectively 48 px wide, including ignored 4 px at RHS)
# four bit padding strip
pbmmake -white 4 45 > "$tmp1"
# header bytes
echo -e -n '\x00\x58' > "$tmp3"
# image body is the same as a 48 x 45 PBM raw image, less 9 byte header
# ("P4\n48 45\n")
# and yes, the multiple calls to pamtopnm are necessary
anytopnm "$1" |\
ppmtopgm |\
pamthreshold -simple |\
pamtopnm |\
pnmmargin -white 45 |\
pamcut -top 45 -left 45 -width 44 -height 45 |\
pamcat -lr - "$tmp1" |\
pamtopnm > "$tmp2"
# remove PBM header (quietly)
dd if="$tmp2" bs=1 skip=9 of="$tmp4" > /dev/null 2>&1
# create output if inputs are there
if
[ -f "$tmp3" ]
then
if
[ -f "$tmp4" ]
then
cat "$tmp3" "$tmp4" > "$2"
else
echo "$0" internal error working file "$tmp4" missing
exit 1
fi
else
echo "$0" internal error working file "$tmp3" missing
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment