Clean up hgr conversion optionns

This commit is contained in:
kris 2023-02-02 23:35:28 +00:00
parent 36946f6ac7
commit f019823505
4 changed files with 56 additions and 74 deletions

View File

@ -44,70 +44,67 @@ def add_common_args(parser):
)
def add_dhr_hgr_args(parser):
parser.add_argument(
'--dither', type=str, choices=list(dither_pattern.PATTERNS.keys()),
default=dither_pattern.DEFAULT_PATTERN,
help="Error distribution pattern to apply when dithering (default: "
+ dither_pattern.DEFAULT_PATTERN + ")")
parser.add_argument(
'--palette', type=str, choices=list(set(palette_py.PALETTES.keys())),
default=palette_py.DEFAULT_PALETTE,
help='RGB colour palette to dither to. "ntsc" blends colours over 8 '
'pixels and gives better image quality on targets that '
'use/emulate NTSC, but can be substantially slower. Other '
'palettes determine colours based on 4 pixel sequences '
'(default: ' + palette_py.DEFAULT_PALETTE + ")")
parser.add_argument(
'--show-palette', type=str, choices=list(palette_py.PALETTES.keys()),
help="RGB colour palette to use when --show_output (default: "
"value of --palette)")
def validate_lookahead(arg: int) -> int:
try:
int_arg = int(arg)
except Exception:
raise argparse.ArgumentTypeError("--lookahead must be an integer")
if int_arg < 1:
raise argparse.ArgumentTypeError("--lookahead must be at least 1")
return int_arg
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(required=True)
# Hi-res
hgr_parser = subparsers.add_parser("hgr")
add_common_args(hgr_parser)
add_dhr_hgr_args(hgr_parser)
hgr_parser.add_argument(
'--dither', type=str, choices=list(dither_pattern.PATTERNS.keys()),
default=dither_pattern.DEFAULT_PATTERN,
help="Error distribution pattern to apply when dithering (default: "
+ dither_pattern.DEFAULT_PATTERN + ")")
hgr_parser.add_argument(
'--palette', type=str, choices=list(set(palette_py.PALETTES.keys())),
default=palette_py.DEFAULT_PALETTE,
help='RGB colour palette to dither to. "ntsc" blends colours over 8 '
'pixels and gives better image quality on targets that '
'use/emulate NTSC, but can be substantially slower. Other '
'palettes determine colours based on 4 pixel sequences '
'(default: ' + palette_py.DEFAULT_PALETTE + ")")
hgr_parser.add_argument(
'--show-palette', type=str, choices=list(palette_py.PALETTES.keys()),
help="RGB colour palette to use when --show_output (default: "
"value of --palette)")
'--error_fraction', type=float, default = 0.7,
help="Fraction of quantization error to distribute to neighbouring "
"pixels according to dither pattern"
)
hgr_parser.set_defaults(func=convert_hgr)
# Double Hi-res
dhr_parser = subparsers.add_parser("dhr")
add_common_args(dhr_parser)
def validate_lookahead(arg: int) -> int:
try:
int_arg = int(arg)
except Exception:
raise argparse.ArgumentTypeError("--lookahead must be an integer")
if int_arg < 1:
raise argparse.ArgumentTypeError("--lookahead must be at least 1")
return int_arg
add_dhr_hgr_args(dhr_parser)
dhr_parser.add_argument(
"--lookahead", type=validate_lookahead, default=8,
help=("How many pixels to look ahead to compensate for NTSC colour "
"artifacts (default: 8)"))
dhr_parser.add_argument(
'--dither', type=str, choices=list(dither_pattern.PATTERNS.keys()),
default=dither_pattern.DEFAULT_PATTERN,
help="Error distribution pattern to apply when dithering (default: "
+ dither_pattern.DEFAULT_PATTERN + ")")
dhr_parser.add_argument(
'--palette', type=str, choices=list(set(palette_py.PALETTES.keys())),
default=palette_py.DEFAULT_PALETTE,
help='RGB colour palette to dither to. "ntsc" blends colours over 8 '
'pixels and gives better image quality on targets that '
'use/emulate NTSC, but can be substantially slower. Other '
'palettes determine colours based on 4 pixel sequences '
'(default: ' + palette_py.DEFAULT_PALETTE + ")")
dhr_parser.add_argument(
'--show-palette', type=str, choices=list(palette_py.PALETTES.keys()),
help="RGB colour palette to use when --show_output (default: "
"value of --palette)")
dhr_parser.set_defaults(func=convert_dhr)
# Double Hi-Res mono
dhr_mono_parser = subparsers.add_parser("dhr_mono")
add_common_args(dhr_mono_parser)
dhr_mono_parser.set_defaults(func=convert_dhr_mono)
# Super Hi-Res 320x200
shr_parser = subparsers.add_parser("shr")
add_common_args(shr_parser)
shr_parser.add_argument(
@ -141,13 +138,6 @@ def prepare_image(image_filename: str, show_input: bool, screen,
gamma=gamma_correct)
def convert_dhr(args):
palette = palette_py.PALETTES[args.palette]()
screen = screen_py.DHGRNTSCScreen(palette)
image = prepare_image(args.input, args.show_input, screen,
args.gamma_correct)
convert_dhr_py.convert(screen, image, args)
def convert_hgr(args):
palette = palette_py.PALETTES[args.palette]()
screen = screen_py.HGRScreen(palette)
@ -156,6 +146,14 @@ def convert_hgr(args):
convert_hgr_py.convert(screen, image, args)
def convert_dhr(args):
palette = palette_py.PALETTES[args.palette]()
screen = screen_py.DHGRNTSCScreen(palette)
image = prepare_image(args.input, args.show_input, screen,
args.gamma_correct)
convert_dhr_py.convert(screen, image, args)
def convert_dhr_mono(args):
screen = screen_py.DHGRScreen()
image = prepare_image(args.input, args.show_input, screen,

View File

@ -28,6 +28,7 @@ def _write(screen: screen_py.DHGRScreen, bitmap: np.ndarray, args):
f.write(bytes(screen.main))
# TODO: unify with convert_hgr.convert()
def convert(screen: screen_py.DHGRNTSCScreen, image: Image, args):
rgb = np.array(image).astype(np.float32) / 255

View File

@ -15,7 +15,7 @@ def _output(out_image: Image, args):
out_image.show()
if args.save_preview:
# Save Double hi-res image
# Save Hi-res image
outfile = os.path.join(
os.path.splitext(args.output)[0] + "-preview.png")
out_image.save(outfile, "PNG")
@ -27,6 +27,7 @@ def _write(screen: screen_py.HGRScreen, linear_bytemap: np.ndarray, args):
f.write(bytes(screen.main))
# TODO: unify with convert_dhr.convert()
def convert(screen: screen_py.HGRScreen, image: Image, args):
rgb = np.array(image).astype(np.float32) / 255
@ -36,7 +37,8 @@ def convert(screen: screen_py.HGRScreen, image: Image, args):
rgb24_to_cam16ucs = np.load(
os.path.join(base_dir, "data/rgb24_to_cam16ucs.npy"))
dither = dither_pattern.PATTERNS[args.dither]()
dither = dither_pattern.PATTERNS[args.dither](
error_fraction = args.error_fraction)
bitmap, linear_bytemap = dither_dhr_pyx.dither_image(
screen, rgb, dither, 8, args.verbose, rgb24_to_cam16ucs)
@ -55,14 +57,3 @@ def convert(screen: screen_py.HGRScreen, image: Image, args):
_output(out_image, args)
_write(screen, linear_bytemap, args)
def convert_mono(screen: screen_py.DHGRScreen, image: Image, args):
image = image.convert("1")
out_image = Image.fromarray((np.array(image) * 255).astype(np.uint8))
out_image = image_py.resize(
out_image, screen.X_RES, screen.Y_RES * 2, srgb_output=True)
_output(out_image, args)
_write(screen, np.array(image).astype(bool), args)

View File

@ -7,6 +7,9 @@ class DitherPattern:
PATTERN = None
ORIGIN = None
def __init__(self, error_fraction=1.0):
self.PATTERN *= error_fraction
class NoDither(DitherPattern):
"""No dithering."""
@ -76,15 +79,6 @@ class JarvisModifiedDither(DitherPattern):
PATTERN /= np.sum(PATTERN)
ORIGIN = (0, 2)
class KrisDither(DitherPattern):
"""Default dither from bmp2dhr."""
# 0 * 7
# 3 5 1
PATTERN = np.array(((0, 0, 7), (3, 5, 1)),
dtype=np.float32).reshape(2, 3) / np.float32(24)
ORIGIN = (0, 1)
PATTERNS = {
'floyd': FloydSteinbergDither,
@ -94,8 +88,6 @@ PATTERNS = {
'jarvis': JarvisDither,
'jarvis-mod': JarvisModifiedDither,
'none': NoDither,
'kris': KrisDither,
}
DEFAULT_PATTERN = 'floyd'