Mercurial > code > home > repos > light9
changeset 1961:f77dfa8e82b9
new 'image' effect for animating light colors
Ignore-this: 8df08111173bd96ff8d8093d4243c3ba
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Thu, 06 Jun 2019 11:59:44 +0000 |
parents | 8e2d456b3612 |
children | d6b7567e8d19 |
files | light9/effect/effecteval.py light9/effect/sequencer.py |
diffstat | 2 files changed, 36 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/effect/effecteval.py Thu Jun 06 11:59:07 2019 +0000 +++ b/light9/effect/effecteval.py Thu Jun 06 11:59:44 2019 +0000 @@ -8,6 +8,7 @@ from light9.effect.settings import DeviceSettings from light9.effect.scale import scale from typing import Dict, Tuple, Any +from PIL import Image import random random.seed(0) @@ -385,3 +386,27 @@ if n > .4: out[(dev, L9['color'])] = col return out + +def sample(img, x, y, repeat=False): + if 0 <= x < img.width: + return img.getpixel((x, y)) + elif not repeat: + return (0, 0, 0) + else: + return img.getpixel((x % img.width, y)) + +def effect_image(effectSettings, strength, songTime, noteTime): + out = {} + imgPath = f'cur/anim/{effectSettings[L9["image"]]}' + t_offset = effectSettings.get(L9['tOffset'], 0) + pxPerSec = effectSettings.get(L9['pxPerSec'], 30) + img = Image.open(imgPath) + x = (noteTime * pxPerSec) + + scl = effectSettings.get(L9['strength'], 1) + for dev, y in [(L9['theater/skyline/device/strip1'], 0), + (L9['theater/skyline/device/strip2'], 1), + (L9['theater/skyline/device/strip3'], 2)]: + color = sample(img, x, y, effectSettings.get(L9['repeat'], False)) + out[(dev, L9['color'])] = scale(rgb_to_hex(color), scl) + return out
--- a/light9/effect/sequencer.py Thu Jun 06 11:59:07 2019 +0000 +++ b/light9/effect/sequencer.py Thu Jun 06 11:59:44 2019 +0000 @@ -12,6 +12,7 @@ import cyclone.sse import logging, bisect, time import traceback +from decimal import Decimal from typing import Any, Callable, Dict, List, Tuple, cast, Union from light9.ascoltami.musictime_client import MusicTime @@ -47,6 +48,13 @@ ) +def pyType(n): + ret = n.toPython() + if isinstance(ret, Decimal): + return float(ret) + return ret + + class Note(object): def __init__(self, graph: SyncedGraph, uri: NoteUri, effectevalModule, @@ -59,7 +67,7 @@ for s in g.objects(uri, L9['setting']): settingValues = dict(g.predicate_objects(s)) ea = settingValues[L9['effectAttr']] - self.baseEffectSettings[ea] = settingValues[L9['value']] + self.baseEffectSettings[ea] = pyType(settingValues[L9['value']]) def floatVal(s, p): return float(g.value(s, p).toPython()) @@ -112,7 +120,7 @@ 'effectClass': self.effectEval.effect, } effectSettings: Dict[DeviceAttr, Union[float, str]] = dict( - (DeviceAttr(da), v.toPython()) + (DeviceAttr(da), v) for da, v in self.baseEffectSettings.items()) effectSettings[L9['strength']] = self.evalCurve(t) @@ -234,6 +242,7 @@ @updateStats.updateFps.rate() @inlineCallbacks def update(self) -> Deferred: + with updateStats.s0_getMusic.time(): musicState = self.music.getLatest() if not musicState.get('song') or not isinstance(