Working Python version for Commodore.
This commit is contained in:
commit
2a48f52979
51 changed files with 3095 additions and 0 deletions
81
c64view/convert/__init__.py
Normal file
81
c64view/convert/__init__.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
"""Conversion dispatch + preview rendering."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .. import imageprep, palette as pal
|
||||
from . import base, hires, mono, multicolor
|
||||
|
||||
# mode name -> module
|
||||
_MODULES = {
|
||||
"hires": hires,
|
||||
"multicolor": multicolor,
|
||||
"mono": mono,
|
||||
}
|
||||
|
||||
# Registered lazily so FLI/IFLI can be added without import cycles.
|
||||
try:
|
||||
from . import fli # noqa: E402
|
||||
_MODULES["fli"] = fli
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
from . import ifli # noqa: E402
|
||||
_MODULES["interlace"] = ifli
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
MODES = list(_MODULES.keys())
|
||||
|
||||
|
||||
def convert_image(path_or_img, mode="multicolor", palette_name="colodore",
|
||||
dither_mode="bayer", intensive=False,
|
||||
prep_opt: imageprep.PrepOptions | None = None,
|
||||
base_color=None) -> base.Conversion:
|
||||
"""Prepare an image for ``mode`` and convert it. ``mode='auto'`` tries every
|
||||
standard mode and returns the lowest-error result. ``base_color`` (palette
|
||||
index, or None for grayscale) only applies to the ``mono`` mode."""
|
||||
prep_opt = prep_opt or imageprep.PrepOptions()
|
||||
|
||||
if mode == "auto":
|
||||
best = None
|
||||
for m in ("multicolor", "hires"):
|
||||
c = convert_image(path_or_img, m, palette_name, dither_mode, intensive, prep_opt)
|
||||
if best is None or c.error < best.error:
|
||||
best = c
|
||||
return best
|
||||
|
||||
module = _MODULES[mode]
|
||||
border_rgb = pal.get_palette(palette_name)[prep_opt.border_index]
|
||||
img_rgb = imageprep.prepare(
|
||||
path_or_img, module.WIDTH, module.HEIGHT, module.PIXEL_ASPECT,
|
||||
prep_opt, border_rgb=border_rgb,
|
||||
)
|
||||
if mode == "mono":
|
||||
return module.convert(img_rgb, palette_name, dither_mode, intensive,
|
||||
base_color=base_color)
|
||||
return module.convert(img_rgb, palette_name, dither_mode, intensive)
|
||||
|
||||
|
||||
def render_preview(conv: base.Conversion, palette_name="colodore",
|
||||
scale: int = 2) -> np.ndarray:
|
||||
"""Render the conversion's index image to a displayed-resolution RGB array.
|
||||
|
||||
Logical pixels are widened by the mode's pixel aspect (so multicolor pixels
|
||||
are twice as wide), giving a uniform 320x200 base which is then integer-scaled.
|
||||
"""
|
||||
if conv.preview_rgb is not None:
|
||||
rgb = conv.preview_rgb
|
||||
if scale > 1:
|
||||
rgb = np.repeat(np.repeat(rgb, scale, axis=0), scale, axis=1)
|
||||
return rgb
|
||||
|
||||
prgb = pal.get_palette(palette_name).astype(np.uint8)
|
||||
rgb = prgb[conv.index_image] # (H, W, 3)
|
||||
xrep = int(round(conv.pixel_aspect))
|
||||
if xrep > 1:
|
||||
rgb = np.repeat(rgb, xrep, axis=1)
|
||||
if scale > 1:
|
||||
rgb = np.repeat(np.repeat(rgb, scale, axis=0), scale, axis=1)
|
||||
return rgb
|
||||
Loading…
Add table
Add a link
Reference in a new issue