#!/usr/bin/env python3 """GoBlue — curated Crusaders looks for sideline / blog edits. Keeps vortex / ink_press / cyan_punch, pulls proven combines from older pipelines (aichelberg, crusaders, orange, rezepttest) recolored to club blues, plus a set of new G'MIC mid-layer looks. """ from pathlib import Path from imagepipeline import Pipeline INPUT = Path( "/home/frank/pics/20260719_Biberach Beavers - Albershausen Crusaders/" "darktable_exported/png" ) OUTPUT_BASE = Path.home() / "pipeline_output" EXISTING_OUTPUTS: dict[str, Path] = {} CONTINUE_FROM: Path | None = None # Club blues (#GoBlue) COLOR1 = "#0064b0" # 0,100,176 COLOR2 = "#00badf" # 0,186,223 R1, G1, B1 = 0, 100, 176 R2, G2, B2 = 0, 186, 223 ALPHA1 = 160 ALPHA2 = 110 # --- shared / kept from previous goblue --- GMIC_TONE_MAPPING = "-fx_map_tones 0.5,0.7,0.1,30,0" GMIC_ANGULAR = "-fx_blur_angular 2.5,50,50,0,0,7,0" GMIC_INK_WASH = "-fx_ink_wash 0.14,23,0,0.5,0.54,2.25,0,0,0,0,0,0,0,0,0" GMIC_DROP_SHADOW = f"-fx_drop_shadow3d 0,0,0,10,1,1,2,0.5,{R2},{G2},{B2},200,0" # --- from aichelberg (on tone-mapped original) --- GMIC_CUTOUT = "-fx_cutout 4,0.5,4,1" GMIC_HUFFMAN_GLITCHES = "-fx_huffman_glitches 30,0,25,0,0,0,0,0,50,50" GMIC_LOCAL_SIMILARITY = "-local_similarity_mask 50,50,50,128,4,10" GMIC_LUMA_INVERT = "-Lylejk_Luma_Invert 1,0" GMIC_CRAYONGRAFFITI = "-fx_crayongraffiti2 300,50,1,0.4,12,1,2,2,0" # --- from crusaders (custom gradient B on rembg) --- GMIC_GRADIENT_B = ( f'-fx_custom_gradient 0,0,0,1,2,1,0,128,100,100,2,0,1,0,"",1,0,' f"{R2},{G2},{B2},255,{R1},{G1},{B1},255,255,255,0,255,255,255,255,255,0,255," f"255,255,0,255,0,255,0,0,255,255,128,128,128,255,255,0,255,255,0,0,0,0" ) # --- from rezepttest bokeh, crusaders colors --- GMIC_BOKEH = ( f"-fx_bokeh 3,5,0,30,8,4,0.3,0.2,{R1},{G1},{B1},{ALPHA1},0.7,30,20,20,1,2," f"{R2},{G2},{B2},{ALPHA2},0.15" ) # --- new mid-layer filters --- GMIC_LOOSE_PHOTOS = ( "-fx_loose_photos 60,40,50,100,50,360,0,2,255,255,255,50,25,0,0,0,0,0,0,50,1,1,1" ) GMIC_BLUR_LINEAR = "-fx_blur_linear 10,0.5,0,0,2,7,0" GMIC_TUNNEL = "-fx_tunnel 4,80,50,50,0.2,0" GMIC_BARBOUILLAGE = "-samj_Barbouillage_Paint_Daub 2,2,100,0.2,1,4,1,0,8" # Multi Thresholds with club-blue palette (dark → COLOR1 → COLOR2 → light → near-white) GMIC_MULTI_THRESHOLD = ( f"-tran_multi_threshold 50,100,150,200," f"0,20,40,{R1},{G1},{B1},{R2},{G2},{B2},126,200,227,232,244,252" ) GMIC_OLDSCHOOL_8BITS = "-fx_8bits 25,800,16" def main() -> None: with Pipeline( name="crusaders-goblue", input_dir=INPUT, output_base=OUTPUT_BASE, existing_outputs=EXISTING_OUTPUTS or None, continue_from=CONTINUE_FROM, ) as p: rembg_out = p.step("rembg", inputs="input", step_id="rembg_out") tone = p.step("gmic", inputs="input", command=GMIC_TONE_MAPPING, step_id="tone") # ========== kept from previous goblue ========== angular = p.step( "gmic", inputs="input", command=GMIC_ANGULAR, step_id="angular" ) vortex = p.step("composite", inputs=[angular, rembg_out], step_id="vortex") ink = p.step("gmic", inputs=tone, command=GMIC_INK_WASH, step_id="ink") ink_press = p.step("composite", inputs=[ink, rembg_out], step_id="ink_press") radial_bg = p.step( "imagemagick_fill", inputs="input", color1=COLOR1, color2=COLOR2, gradient=True, radial=True, step_id="radial_bg", ) rembg_shadow = p.step( "gmic", inputs=rembg_out, command=GMIC_DROP_SHADOW, step_id="rembg_shadow" ) punch_mid = p.step( "composite", inputs=[radial_bg, rembg_shadow], step_id="punch_mid" ) cyan_punch = p.step( "composite", inputs=[punch_mid, rembg_out], step_id="cyan_punch" ) # ========== from aichelberg (tone → filter → mid → rembg) ========== input_cutout = p.step( "gmic", inputs=tone, command=GMIC_CUTOUT, step_id="input_cutout" ) cutout_mid = p.step( "composite", inputs=[tone, input_cutout], step_id="cutout_mid" ) composite_cutout = p.step( "composite", inputs=[cutout_mid, rembg_out], step_id="composite_cutout" ) input_huffman = p.step( "gmic", inputs=tone, command=GMIC_HUFFMAN_GLITCHES, step_id="input_huffman_glitches", ) huffman_mid = p.step( "composite", inputs=[tone, input_huffman], step_id="huffman_glitches_mid", ) composite_huffman_glitches = p.step( "composite", inputs=[huffman_mid, rembg_out], step_id="composite_huffman_glitches", ) input_local_sim = p.step( "gmic", inputs=tone, command=GMIC_LOCAL_SIMILARITY, step_id="input_local_similarity", ) local_sim_mid = p.step( "composite", inputs=[tone, input_local_sim], step_id="local_similarity_mid", ) composite_local_similarity = p.step( "composite", inputs=[local_sim_mid, rembg_out], step_id="composite_local_similarity", ) input_luma_invert = p.step( "gmic", inputs=tone, command=GMIC_LUMA_INVERT, step_id="input_luma_invert" ) luma_invert_mid = p.step( "composite", inputs=[tone, input_luma_invert], step_id="luma_invert_mid", ) composite_luma_invert = p.step( "composite", inputs=[luma_invert_mid, rembg_out], step_id="composite_luma_invert", ) input_crayon = p.step( "gmic", inputs=tone, command=GMIC_CRAYONGRAFFITI, step_id="input_crayongraffiti", ) crayon_mid = p.step( "composite", inputs=[tone, input_crayon], step_id="crayongraffiti_mid", ) composite_crayongraffiti = p.step( "composite", inputs=[crayon_mid, rembg_out], step_id="composite_crayongraffiti", ) # ========== from crusaders ========== # composite_04: radial club-blue gradient + rembg composite_04 = p.step( "composite", inputs=[radial_bg, rembg_out], step_id="composite_04" ) # composite_12: rembg custom gradient B + rembg rembg_gradient_b = p.step( "gmic", inputs=rembg_out, command=GMIC_GRADIENT_B, step_id="rembg_gradient_b" ) composite_12 = p.step( "composite", inputs=[rembg_gradient_b, rembg_out], step_id="composite_12" ) # ========== from orange (composite_02: original + drop shadow + rembg) ========== shadow_mid = p.step( "composite", inputs=["input", rembg_shadow], step_id="shadow_mid" ) composite_02 = p.step( "composite", inputs=[shadow_mid, rembg_out], step_id="composite_02" ) # ========== from rezepttest (composite_bokeh, club blues) ========== input_bokeh = p.step( "gmic", inputs="input", command=GMIC_BOKEH, step_id="input_bokeh" ) bokeh_mid = p.step( "composite", inputs=["input", input_bokeh], step_id="bokeh_mid" ) composite_bokeh = p.step( "composite", inputs=[bokeh_mid, rembg_out], step_id="composite_bokeh" ) # ========== new compositions ========== # original / loose photos (linearburn 50%) / rembg loose = p.step( "gmic", inputs="input", command=GMIC_LOOSE_PHOTOS, step_id="loose_photos" ) loose_mid = p.step( "composite", inputs=["input", loose], mode="linearburn", foreground_opacity=0.5, step_id="loose_photos_mid", ) composite_loose_photos = p.step( "composite", inputs=[loose_mid, rembg_out], step_id="composite_loose_photos", ) # original with blur linear / rembg blur_linear = p.step( "gmic", inputs="input", command=GMIC_BLUR_LINEAR, step_id="blur_linear" ) composite_blur_linear = p.step( "composite", inputs=[blur_linear, rembg_out], step_id="composite_blur_linear", ) # original with tunnel / rembg tunnel = p.step("gmic", inputs="input", command=GMIC_TUNNEL, step_id="tunnel") composite_tunnel = p.step( "composite", inputs=[tunnel, rembg_out], step_id="composite_tunnel" ) # original with barbouillage / rembg barbouillage = p.step( "gmic", inputs="input", command=GMIC_BARBOUILLAGE, step_id="barbouillage", ) composite_barbouillage = p.step( "composite", inputs=[barbouillage, rembg_out], step_id="composite_barbouillage", ) # original / luma invert (multiply 50%) / rembg luma_on_input = p.step( "gmic", inputs="input", command=GMIC_LUMA_INVERT, step_id="luma_invert_on_input", ) luma_mul_mid = p.step( "composite", inputs=["input", luma_on_input], mode="multiply", foreground_opacity=0.5, step_id="luma_invert_multiply_mid", ) composite_luma_invert_multiply = p.step( "composite", inputs=[luma_mul_mid, rembg_out], step_id="composite_luma_invert_multiply", ) # original / multi thresholds (hardmix 50%) / rembg multi_threshold = p.step( "gmic", inputs="input", command=GMIC_MULTI_THRESHOLD, step_id="multi_threshold", ) multi_mid = p.step( "composite", inputs=["input", multi_threshold], mode="hardmix", foreground_opacity=0.5, step_id="multi_threshold_mid", ) composite_multi_threshold = p.step( "composite", inputs=[multi_mid, rembg_out], step_id="composite_multi_threshold", ) # original / oldschool 8bits (screen) / rembg oldschool = p.step( "gmic", inputs="input", command=GMIC_OLDSCHOOL_8BITS, step_id="oldschool_8bits", ) oldschool_mid = p.step( "composite", inputs=["input", oldschool], mode="screen", step_id="oldschool_8bits_mid", ) composite_oldschool_8bits = p.step( "composite", inputs=[oldschool_mid, rembg_out], step_id="composite_oldschool_8bits", ) p.step( "xcf_stack", inputs=[ "input", rembg_out, vortex, ink_press, cyan_punch, composite_cutout, composite_huffman_glitches, composite_local_similarity, composite_luma_invert, composite_crayongraffiti, composite_04, composite_12, composite_02, composite_bokeh, composite_loose_photos, composite_blur_linear, composite_tunnel, composite_barbouillage, composite_luma_invert_multiply, composite_multi_threshold, composite_oldschool_8bits, ], step_id="xcf_looks", ) output_root = p.run() print(f"Pipeline finished. Output: {output_root}") if __name__ == "__main__": main()