Compare commits

...

12 Commits

Author SHA1 Message Date
Bauke 5a36bfb40b
Remove TypeScript files. 2024-02-29 14:09:11 +01:00
Bauke e3103fb8a3
Add 2022-03-29. 2024-02-29 14:07:49 +01:00
Bauke ab1442fd2b
Add 2022-03-15. 2024-02-29 14:05:09 +01:00
Bauke 745dfdc468
Add the Spiral operation and associated enums. 2024-02-29 14:00:09 +01:00
Bauke 5e160663e2
Add 2022-03-14. 2024-02-29 13:45:06 +01:00
Bauke 8958e49168
Add the Edge operation and associated enums. 2024-02-29 13:43:01 +01:00
Bauke 719c9c85e6
Add 2022-03-13. 2024-02-29 13:31:55 +01:00
Bauke 22e7987e26
Fix height -> width typo. 2024-02-26 18:46:04 +01:00
Bauke 121e26ece1
Add 2022-03-12. 2024-02-26 18:45:37 +01:00
Bauke 4100ce501a
Add the edge-neon operation. 2024-02-26 18:40:20 +01:00
Bauke 8c43dcc8be
Add 2022-03-11. 2024-02-26 18:34:04 +01:00
Bauke 8aea20c0f1
Add 2022-03-10. 2024-02-26 18:28:56 +01:00
43 changed files with 388 additions and 1610 deletions

View File

@ -2,6 +2,27 @@
use crate::gegl_enum;
gegl_enum!(
/// The abyss policy for various GEGL operations.
AbyssPolicy,
Black => "black",
Clamp => "clamp",
Loop => "loop",
None => "none",
White => "white",
);
gegl_enum!(
/// The detection algorithm for [`Edge`][super::Edge].
EdgeAlgorithm,
Differential => "differential",
Gradient => "gradient",
Laplace => "laplace",
PrewittCompass => "prewitt",
Roberts => "roberts",
Sobel => "sobel",
);
gegl_enum!(
/// The shape for [`FocusBlur`][super::FocusBlur].
FocusBlurShape,
@ -69,6 +90,20 @@ gegl_enum!(
WhiteOnBlack => "white-on-black",
);
gegl_enum!(
/// The spiral swirl direction for [`Spiral`][super::Spiral]
SpiralDirection,
Clockwise => "cw",
CounterClockwise => "ccw",
);
gegl_enum!(
/// The spiral type for [`Spiral`][super::Spiral]
SpiralType,
Linear => "linear",
Logarithmic => "logarithmic",
);
gegl_enum!(
/// The sampler type for [`StereographicProjection`][super::StereographicProjection].
StereographicProjectionSamplerType,

View File

@ -111,6 +111,32 @@ gegl_operation!(
),
);
gegl_operation!(
struct_name: Edge,
gegl_name: "edge",
append_crop: false,
values: (
/// The edge detection algorithm to use.
algorithm: EdgeAlgorithm, EdgeAlgorithm::Sobel,
/// The amount of edge detection to perform.
amount: f64, 2.0,
/// The edge detection border behavior.
border_behavior: AbyssPolicy, AbyssPolicy::Clamp,
),
);
gegl_operation!(
struct_name: EdgeNeon,
gegl_name: "edge-neon",
append_crop: false,
values: (
/// Strength of effect.
amount: f64, 0.0,
/// Radius of effect in pixels.
radius: f64, 5.0,
),
);
gegl_operation!(
struct_name: FocusBlur,
gegl_name: "focus-blur",
@ -389,6 +415,38 @@ gegl_operation!(
),
);
gegl_operation!(
struct_name: Spiral,
gegl_name: "spiral",
append_crop: true,
values: (
/// The area balance between the two colors.
balance: f64, 0.0,
/// The logarithmic spiral base.
base: f64, 2.0,
/// The primary color.
color1: String, "#000".to_string(),
/// The secondary color.
color2: String, "#fff".to_string(),
/// The spiral swirl direction.
direction: SpiralDirection, SpiralDirection::Clockwise,
/// The height of the generated buffer.
height: i64, 768,
/// The spiral radius.
radius: f64, 100.0,
/// The spiral rotation.
rotation: f64, 0.0,
/// The spiral type.
spiral_type: SpiralType, SpiralType::Linear,
/// The X origin coordinate.
x: f64, 0.5,
/// The Y origin coordinate.
y: f64, 0.5,
/// The width of the generated buffer.
width: i64, 1024,
),
);
gegl_operation!(
struct_name: StereographicProjection,
gegl_name: "stereographic-projection",

View File

@ -11,5 +11,12 @@ pub fn all_projects() -> Vec<Project> {
year_2022::day_2022_03_07(),
year_2022::day_2022_03_08(),
year_2022::day_2022_03_09(),
year_2022::day_2022_03_10(),
year_2022::day_2022_03_11(),
year_2022::day_2022_03_12(),
year_2022::day_2022_03_13(),
year_2022::day_2022_03_14(),
year_2022::day_2022_03_15(),
year_2022::day_2022_03_29(),
]
}

View File

@ -182,3 +182,291 @@ pub fn day_2022_03_09() -> Project {
turn_off_alpha: true,
}
}
/// The project made on 2022-03-10.
pub fn day_2022_03_10() -> Project {
Project {
create_input_image: false,
name: "2022-03-10".to_string(),
operations: vec![
CellNoise::default()
.with_scale(0.5)
.with_seed(2_762_328_325.0)
.boxed(),
Newsprint::default()
.with_angle4(75.85)
.with_color_model(NewsprintColorModel::Rgb)
.with_pattern2(NewsprintPattern::Circle)
.with_pattern4(NewsprintPattern::Cross)
.with_period2(42.38)
.with_period3(0.0)
.with_period4(135.1)
.with_turbulence(0.454)
.boxed(),
Waves::default()
.with_amplitude(67.6)
.with_clamp(true)
.with_period(514.8)
.with_phi(-0.529)
.with_sampler_type(WavesSamplerType::Cubic)
.with_x(-0.25)
.with_y(-0.75)
.boxed(),
Bloom::default()
.with_radius(20.0)
.with_softness(57.0)
.with_strength(90.0)
.with_threshold(10.0)
.boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}
/// The project made on 2022-03-11.
pub fn day_2022_03_11() -> Project {
Project {
create_input_image: true,
name: "2022-03-11".to_string(),
operations: vec![
Plasma::default()
.with_seed(168_139_081.0)
.with_turbulence(1.5)
.with_height(2160)
.with_width(3840)
.boxed(),
Cartoon::default()
.with_mask_radius(40.0)
.with_pct_black(0.2)
.boxed(),
Waterpixels::default().with_size(64).boxed(),
Cartoon::default()
.with_mask_radius(40.0)
.with_pct_black(0.2)
.boxed(),
Newsprint::default()
.with_color_model(NewsprintColorModel::Rgb)
.with_pattern2(NewsprintPattern::Circle)
.with_pattern3(NewsprintPattern::Cross)
.with_pattern4(NewsprintPattern::Circle)
.with_period2(15.0)
.with_period3(150.0)
.with_period4(30.0)
.with_turbulence(0.9)
.boxed(),
Bloom::default()
.with_radius(7.48)
.with_strength(115.29)
.with_threshold(65.88)
.boxed(),
NoisePick::default().with_repeat(5).with_seed(0.0).boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}
/// The project made on 2022-03-12.
pub fn day_2022_03_12() -> Project {
Project {
create_input_image: false,
name: "2022-03-12".to_string(),
operations: vec![
DiffractionPatterns::default()
.with_brightness(0.382)
.with_polarization(0.67)
.with_scattering(53.21)
.with_height(2160)
.with_width(3840)
.boxed(),
Waterpixels::default().with_smoothness(2.0).boxed(),
EdgeNeon::default()
.with_amount(0.5)
.with_radius(3.0)
.boxed(),
Mirrors::default()
.with_o_x(0.365)
.with_o_y(0.694)
.with_trim_x(0.375)
.with_trim_y(0.375)
.boxed(),
Newsprint::default().with_turbulence(0.996).boxed(),
MedianBlur::default()
.with_neighborhood(MedianBlurNeighborhood::Diamond)
.boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}
/// The project made on 2022-03-13.
pub fn day_2022_03_13() -> Project {
Project {
create_input_image: false,
name: "2022-03-13".to_string(),
operations: vec![
Plasma::default()
.with_seed(65_198_886.0)
.with_height(2160)
.with_width(3840)
.boxed(),
Cartoon::default()
.with_mask_radius(50.0)
.with_pct_black(1.0)
.boxed(),
Waterpixels::default().with_size(64).boxed(),
Oilify::default().with_mask_radius(8).boxed(),
Mirrors::default()
.with_n_segs(8)
.with_o_x(0.829)
.with_o_y(0.812)
.with_trim_x(0.325)
.with_trim_y(0.09)
.boxed(),
StereographicProjection::default().with_tilt(-73.42).boxed(),
Oilify::default().with_mask_radius(8).boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}
/// The project made on 2022-03-14.
pub fn day_2022_03_14() -> Project {
Project {
create_input_image: false,
name: "2022-03-14".to_string(),
operations: vec![
DiffractionPatterns::default()
.with_height(2160)
.with_width(3840)
.boxed(),
Mirrors::default()
.with_n_segs(7)
.with_o_x(0.347)
.with_o_y(0.1)
.with_r_angle(13.0)
.with_trim_x(0.051)
.with_trim_y(0.253)
.boxed(),
Cartoon::default()
.with_mask_radius(50.0)
.with_pct_black(1.0)
.boxed(),
MedianBlur::default().with_radius(5.0).boxed(),
Edge::default()
.with_algorithm(EdgeAlgorithm::PrewittCompass)
.with_amount(10.0)
.with_border_behavior(AbyssPolicy::Clamp)
.boxed(),
MedianBlur::default().with_radius(5.0).boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}
/// The project made on 2022-03-15.
pub fn day_2022_03_15() -> Project {
Project {
create_input_image: false,
name: "2022-03-15".to_string(),
operations: vec![
Spiral::default()
.with_balance(0.424)
.with_color1("#3078d2".to_string())
.with_color2("#ff00dc".to_string())
.with_direction(SpiralDirection::Clockwise)
.with_height(2160)
.with_radius(918.7)
.with_spiral_type(SpiralType::Linear)
.with_width(3840)
.with_x(0.307)
.with_y(0.542)
.boxed(),
Cartoon::default()
.with_mask_radius(50.0)
.with_pct_black(1.0)
.boxed(),
Newsprint::default()
.with_color_model(NewsprintColorModel::Rgb)
.with_pattern2(NewsprintPattern::Line)
.with_pattern3(NewsprintPattern::Diamond)
.with_pattern4(NewsprintPattern::Pssquare)
.with_period2(105.96)
.with_period3(30.46)
.with_period4(125.83)
.with_turbulence(0.182)
.boxed(),
Bloom::default()
.with_radius(2.08)
.with_softness(87.94)
.with_strength(165.29)
.boxed(),
Cartoon::default()
.with_mask_radius(50.0)
.with_pct_black(1.0)
.boxed(),
Waves::default()
.with_amplitude(65.0)
.with_clamp(true)
.with_period(500.0)
.with_phi(0.5)
.with_x(0.0)
.with_y(0.1)
.boxed(),
Mirrors::default()
.with_r_angle(30.0)
.with_n_segs(3)
.with_o_x(0.312)
.with_o_y(1.0)
.with_trim_x(0.162)
.with_trim_y(0.031)
.boxed(),
FocusBlur::default()
.with_blur_radius(5.4)
.with_blur_type(FocusBlurType::Lens)
.with_focus(0.154)
.with_highlight_factor(0.75)
.with_midpoint(0.38)
.with_radius(0.802)
.boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}
/// The project made on 2022-03-29.
pub fn day_2022_03_29() -> Project {
Project {
create_input_image: false,
name: "2022-03-29".to_string(),
operations: vec![
Plasma::default()
.with_seed(3_474_742_930.0)
.with_turbulence(2.0)
.with_height(2160)
.with_width(3840)
.boxed(),
Cartoon::default()
.with_mask_radius(50.0)
.with_pct_black(1.0)
.boxed(),
FocusBlur::default()
.with_blur_type(FocusBlurType::Lens)
.boxed(),
Mirrors::default().with_o_x(0.406).with_o_y(0.588).boxed(),
Oilify::default().with_mask_radius(8).boxed(),
Bloom::default()
.with_radius(2.08)
.with_softness(87.94)
.with_strength(165.29)
.boxed(),
],
resolution: (3840, 2160),
turn_off_alpha: false,
}
}

View File

@ -1,66 +0,0 @@
import {
FocusBlur,
Mirrors,
Newsprint,
SimplexNoise,
Softglow,
StereographicProjection,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [1920, 1080];
const project: Project = {
createInputImage: false,
name: '2022-03-06',
operations: [
new SimplexNoise({scale: 4, seed: 2_071_140_406}),
new Newsprint({
colorModel: 'rgb',
pattern2: 'line',
period2: 200,
angle2: 15,
pattern3: 'line',
period3: 200,
angle3: 45,
pattern4: 'line',
period4: 200,
angle4: 0,
}),
new Mirrors(),
new Softglow(),
new Newsprint(),
new StereographicProjection({tilt: 123}),
new FocusBlur({
blurType: 'gaussian',
blurRadius: 11.5,
radius: 0.9,
midpoint: 0.6,
}),
new Newsprint({
colorModel: 'rgb',
pattern2: 'diamond',
period2: 200,
angle2: 0,
pattern3: 'diamond',
period3: 200,
angle3: 35,
pattern4: 'diamond',
period4: 200,
angle4: 55,
}),
new FocusBlur({
blurType: 'gaussian',
blurRadius: 11.5,
radius: 0.9,
midpoint: 0.6,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,68 +0,0 @@
import {
Cartoon,
MedianBlur,
Mirrors,
Mosaic,
Plasma,
Waterpixels,
Waves,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [1920, 1080];
const project: Project = {
createInputImage: false,
name: '2022-03-07',
operations: [
new Plasma({
height,
seed: 2_000_111_903,
turbulence: 1,
width,
}),
new Mosaic({
colorVariation: 1,
tileHeight: 5,
tileNeatness: 1,
tileSize: 116.53,
tileSurface: true,
tileType: 'triangles',
}),
new Waves({
amplitude: 2.9,
clamp: true,
samplerType: 'cubic',
}),
new Waves({
amplitude: 17.3,
clamp: true,
samplerType: 'cubic',
}),
new Mirrors({
oX: 1,
oY: 0.353,
nSegs: 2,
}),
new Cartoon(),
new Waterpixels({
fill: 'average',
size: 32,
smoothness: 1,
}),
new Mirrors({
oX: 0.01,
oY: 0.01,
nSegs: 5,
rAngle: 342,
}),
new MedianBlur(),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,42 +0,0 @@
import {
DiffractionPatterns,
FocusBlur,
Newsprint,
StereographicProjection,
TileSeamless,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [1920, 1080];
const project: Project = {
createInputImage: false,
name: '2022-03-08',
operations: [
new DiffractionPatterns({
height,
width,
}),
new TileSeamless(),
new StereographicProjection(),
new Newsprint({
colorModel: 'cmyk',
period: 4,
}),
new FocusBlur({
blurRadius: 9.72,
blurType: 'lens',
focus: 0,
highlightFactor: 0.924,
radius: 1.173,
shape: 'circle',
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,60 +0,0 @@
import {
FocusBlur,
Maze,
MedianBlur,
Mirrors,
Newsprint,
Oilify,
TileGlass,
TileSeamless,
Waterpixels,
Waves,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [1920, 1080];
const project: Project = {
createInputImage: true,
name: '2022-03-09',
operations: [
new Maze(),
new TileGlass(),
new Waterpixels(),
new Newsprint({
angle2: -55.4,
angle3: 60.77,
angle4: 103.55,
colorModel: 'rgb',
}),
new Waves({
amplitude: 5.9,
clamp: true,
}),
new Oilify(),
new TileSeamless(),
new MedianBlur({
percentile: 2.35,
}),
new Mirrors({
nSegs: 3,
oX: 0.1,
oY: 0.2,
rAngle: 330,
}),
new FocusBlur({
blurRadius: 33.57,
blurType: 'lens',
focus: 0.111,
highlightFactor: 0.529,
radius: 1.173,
}),
],
resetAlpha: true,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,47 +0,0 @@
import {Bloom, CellNoise, Newsprint, Waves} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: false,
name: '2022-03-10',
operations: [
new CellNoise({
scale: 0.5,
seed: 2_762_328_325,
}),
new Newsprint({
angle4: 75.85,
colorModel: 'rgb',
pattern2: 'circle',
pattern4: 'cross',
period2: 42.38,
period3: 0,
period4: 135.1,
turbulence: 0.454,
}),
new Waves({
amplitude: 67.6,
clamp: true,
period: 514.8,
phi: -0.529,
samplerType: 'cubic',
x: -0.25,
y: -0.75,
}),
new Bloom({
radius: 20,
softness: 57,
strength: 90,
threshold: 10,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,61 +0,0 @@
import {
Bloom,
Cartoon,
Newsprint,
NoisePick,
Plasma,
Waterpixels,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: true,
name: '2022-03-11',
operations: [
new Plasma({
seed: 168_139_081,
turbulence: 1.5,
height,
width,
}),
new Cartoon({
maskRadius: 40,
pctBlack: 0.2,
}),
new Waterpixels({
size: 64,
}),
new Cartoon({
maskRadius: 40,
pctBlack: 0.2,
}),
new Newsprint({
colorModel: 'rgb',
pattern2: 'circle',
pattern3: 'cross',
pattern4: 'circle',
period2: 15,
period3: 150,
period4: 30,
turbulence: 0.9,
}),
new Bloom({
radius: 7.48,
strength: 115.29,
threshold: 65.88,
}),
new NoisePick({
repeat: 5,
seed: 0,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,51 +0,0 @@
import {
DiffractionPatterns,
Generic,
MedianBlur,
Mirrors,
Newsprint,
Waterpixels,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: false,
name: '2022-03-12',
operations: [
new DiffractionPatterns({
brightness: 0.382,
polarization: 0.67,
scattering: 53.21,
height,
width,
}),
new Waterpixels({
smoothness: 2,
}),
new Generic('gegl:edge-neon', {
amount: 0.5,
radius: 3,
}),
new Mirrors({
oX: 0.365,
oY: 0.694,
trimX: 0.375,
trimY: 0.375,
}),
new Newsprint({
turbulence: 0.996,
}),
new MedianBlur({
neighborhood: 'diamond',
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,53 +0,0 @@
import {
Cartoon,
Mirrors,
Oilify,
Plasma,
StereographicProjection,
Waterpixels,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: false,
name: '2022-03-13',
operations: [
new Plasma({
seed: 65_198_886,
height,
width,
}),
new Cartoon({
maskRadius: 50,
pctBlack: 1,
}),
new Waterpixels({
size: 64,
}),
new Oilify({
maskRadius: 8,
}),
new Mirrors({
nSegs: 8,
oX: 0.829,
oY: 0.812,
trimX: 0.325,
trimY: 0.09,
}),
new StereographicProjection({
tilt: -73.42,
}),
new Oilify({
maskRadius: 8,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,51 +0,0 @@
import {
Cartoon,
DiffractionPatterns,
Generic,
MedianBlur,
Mirrors,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: false,
name: '2022-03-14',
operations: [
new DiffractionPatterns({
height,
width,
}),
new Mirrors({
nSegs: 7,
oX: 0.347,
oY: 0.1,
rAngle: 13,
trimX: 0.051,
trimY: 0.253,
}),
new Cartoon({
maskRadius: 50,
pctBlack: 1,
}),
new MedianBlur({
radius: 5,
}),
new Generic('gegl:edge', {
algorithm: 'prewitt',
amount: 10,
borderBehavior: 'clamp',
}),
new MedianBlur({
radius: 5,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,90 +0,0 @@
import {
Bloom,
Cartoon,
Crop,
FocusBlur,
Generic,
Mirrors,
Newsprint,
Waves,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: false,
name: '2022-03-15',
operations: [
new Generic('gegl:spiral', {
balance: 0.424,
color1: '#3078d2',
color2: '#ff00dc',
direction: 'cw',
height,
radius: 918.7,
type: 'linear',
width,
x: 0.307,
y: 0.542,
}),
new Crop({
height,
width,
}),
new Cartoon({
maskRadius: 50,
pctBlack: 1,
}),
new Newsprint({
colorModel: 'rgb',
pattern2: 'line',
pattern3: 'diamond',
pattern4: 'pssquare',
period2: 105.96,
period3: 30.46,
period4: 125.83,
turbulence: 0.182,
}),
new Bloom({
radius: 2.08,
softness: 87.94,
strength: 165.29,
}),
new Cartoon({
maskRadius: 50,
pctBlack: 1,
}),
new Waves({
amplitude: 65,
clamp: true,
period: 500,
phi: 0.5,
x: 0,
y: 1,
}),
new Mirrors({
rAngle: 30,
nSegs: 3,
oX: 0.312,
oY: 1,
trimX: 0.162,
trimY: 0.031,
}),
new FocusBlur({
blurRadius: 5.4,
blurType: 'lens',
focus: 0.154,
highlightFactor: 0.75,
midpoint: 0.38,
radius: 0.802,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,50 +0,0 @@
import {
Bloom,
Cartoon,
FocusBlur,
Mirrors,
Oilify,
Plasma,
} from '../../gegl/exports.js';
import Project from '../../project.js';
const [width, height] = [3840, 2160];
const project: Project = {
createInputImage: false,
name: '2022-03-29',
operations: [
new Plasma({
height,
seed: 3_474_742_930,
turbulence: 2,
width,
}),
new Cartoon({
maskRadius: 50,
pctBlack: 1,
}),
new FocusBlur({
blurType: 'lens',
}),
new Mirrors({
oX: 0.406,
oY: 0.588,
}),
new Oilify({
maskRadius: 8,
}),
new Bloom({
radius: 2.08,
softness: 87.94,
strength: 165.29,
}),
],
resetAlpha: false,
resolution: {
width,
height,
},
};
export default project;

View File

@ -1,29 +0,0 @@
import Project from '../../project.js';
import p2022_03_06 from './2022-03-06.js';
import p2022_03_07 from './2022-03-07.js';
import p2022_03_08 from './2022-03-08.js';
import p2022_03_09 from './2022-03-09.js';
import p2022_03_10 from './2022-03-10.js';
import p2022_03_11 from './2022-03-11.js';
import p2022_03_12 from './2022-03-12.js';
import p2022_03_13 from './2022-03-13.js';
import p2022_03_14 from './2022-03-14.js';
import p2022_03_15 from './2022-03-15.js';
import p2022_03_29 from './2022-03-29.js';
const projects: Project[] = [
p2022_03_06,
p2022_03_07,
p2022_03_08,
p2022_03_09,
p2022_03_10,
p2022_03_11,
p2022_03_12,
p2022_03_13,
p2022_03_14,
p2022_03_15,
p2022_03_29,
];
export default projects;

View File

@ -1,6 +0,0 @@
import Project from '../project.js';
import p2022_03 from './03/projects.js';
const projects: Project[] = [...p2022_03];
export default projects;

View File

@ -1,39 +0,0 @@
export abstract class BaseOperation<P extends {}> {
public abstract get default(): P;
public parameters: P;
/**
* Some GEGL operations will run infinitely unless you limit the buffer in
* some way, so all operations must indicate whether or not they should be
* followed by a crop operation.
*/
public abstract appendCrop: boolean;
/** The GEGL operation name, starting with `gegl:`. */
public abstract name: string;
constructor(parameters: P) {
this.parameters = parameters;
}
public graph(includeDefaults = false): string[] {
const defaults = this.default;
const graph: string[] = [this.name];
for (const [key, value] of Object.entries(this.parameters)) {
if (
!includeDefaults &&
key in defaults &&
(defaults as Record<string, any>)[key] === value
) {
continue;
}
const kebabCasedKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
graph.push(`${kebabCasedKey}=${value as string}`);
}
return graph;
}
}

View File

@ -1,30 +0,0 @@
import {BaseOperation} from './base.js';
export interface BloomParameters {
limitExposure: boolean;
radius: number;
softness: number;
strength: number;
threshold: number;
}
export class Bloom extends BaseOperation<BloomParameters> {
public static default: BloomParameters = {
limitExposure: false,
radius: 10,
softness: 25,
strength: 50,
threshold: 50,
};
public get default() {
return Bloom.default;
}
public appendCrop = false;
public name = 'gegl:bloom';
constructor(parameters?: Partial<BloomParameters>) {
super({...Bloom.default, ...parameters});
}
}

View File

@ -1,24 +0,0 @@
import {BaseOperation} from './base.js';
export interface CartoonParameters {
maskRadius: number;
pctBlack: number;
}
export class Cartoon extends BaseOperation<CartoonParameters> {
public static default: CartoonParameters = {
maskRadius: 7,
pctBlack: 0.2,
};
public get default() {
return Cartoon.default;
}
public appendCrop = true;
public name = 'gegl:cartoon';
constructor(parameters?: Partial<CartoonParameters>) {
super({...Cartoon.default, ...parameters});
}
}

View File

@ -1,32 +0,0 @@
import {BaseOperation} from './base.js';
export interface CellNoiseParameters {
iterations: number;
palettize: boolean;
rank: number;
scale: number;
seed: number;
shape: number;
}
export class CellNoise extends BaseOperation<CellNoiseParameters> {
public static default: CellNoiseParameters = {
iterations: 1,
palettize: false,
rank: 1,
scale: 1,
seed: 0,
shape: 2,
};
public get default() {
return CellNoise.default;
}
public appendCrop = true;
public name = 'gegl:cell-noise';
constructor(parameters?: Partial<CellNoiseParameters>) {
super({...CellNoise.default, ...parameters});
}
}

View File

@ -1,30 +0,0 @@
import {BaseOperation} from './base.js';
export interface CropParameters {
height: number;
resetOrigin: boolean;
width: number;
x: number;
y: number;
}
export class Crop extends BaseOperation<CropParameters> {
public static default: CropParameters = {
height: 0,
resetOrigin: false,
width: 0,
x: 0,
y: 0,
};
public get default() {
return Crop.default;
}
public appendCrop = false;
public name = 'gegl:crop';
constructor(parameters?: Partial<CropParameters>) {
super({...Crop.default, ...parameters});
}
}

View File

@ -1,48 +0,0 @@
import {BaseOperation} from './base.js';
export interface DiffractionPatternsParameters {
blueContours: number;
blueFrequency: number;
blueSedges: number;
brightness: number;
greenContours: number;
greenFrequency: number;
greenSedges: number;
height: number;
polarization: number;
redContours: number;
redFrequency: number;
redSedges: number;
scattering: number;
width: number;
}
export class DiffractionPatterns extends BaseOperation<DiffractionPatternsParameters> {
public static default: DiffractionPatternsParameters = {
blueContours: 0.97,
blueFrequency: 1.12,
blueSedges: 0.64,
brightness: 0.07,
greenContours: 0.82,
greenFrequency: 1.22,
greenSedges: 0.68,
height: 200,
polarization: -0.47,
redContours: 0.82,
redFrequency: 0.81,
redSedges: 0.61,
scattering: 37.13,
width: 200,
};
public get default() {
return DiffractionPatterns.default;
}
public appendCrop = true;
public name = 'gegl:diffraction-patterns';
constructor(parameters?: Partial<DiffractionPatternsParameters>) {
super({...DiffractionPatterns.default, ...parameters});
}
}

View File

@ -1,23 +0,0 @@
export * from './base.js';
export * from './bloom.js';
export * from './cartoon.js';
export * from './cell-noise.js';
export * from './crop.js';
export * from './diffraction-patterns.js';
export * from './focus-blur.js';
export * from './generic.js';
export * from './maze.js';
export * from './median-blur.js';
export * from './mirrors.js';
export * from './mosaic.js';
export * from './newsprint.js';
export * from './noise-pick.js';
export * from './oilify.js';
export * from './plasma.js';
export * from './simplex-noise.js';
export * from './softglow.js';
export * from './stereographic-projection.js';
export * from './tile-glass.js';
export * from './tile-seamless.js';
export * from './waterpixels.js';
export * from './waves.js';

View File

@ -1,48 +0,0 @@
import {BaseOperation} from './base.js';
export interface FocusBlurParameters {
aspectRatio: number;
blurRadius: number;
blurType: 'gaussian' | 'lens';
focus: number;
highlightFactor: number;
highlightThresholdHigh: number;
highlightThresholdLow: number;
highQuality: boolean;
midpoint: number;
radius: number;
rotation: number;
shape: 'circle' | 'square' | 'diamond' | 'horizontal' | 'vertical';
x: number;
y: number;
}
export class FocusBlur extends BaseOperation<FocusBlurParameters> {
public static default: FocusBlurParameters = {
aspectRatio: 0,
blurRadius: 25,
blurType: 'gaussian',
focus: 0.25,
highlightFactor: 0,
highlightThresholdHigh: 1,
highlightThresholdLow: 0,
highQuality: false,
midpoint: 0.5,
radius: 0.75,
rotation: 0,
shape: 'circle',
x: 0.5,
y: 0.5,
};
public get default() {
return FocusBlur.default;
}
public appendCrop = false;
public name = 'gegl:focus-blur';
constructor(parameters?: Partial<FocusBlurParameters>) {
super({...FocusBlur.default, ...parameters});
}
}

View File

@ -1,22 +0,0 @@
import {BaseOperation} from './base.js';
export type GenericParameters = Record<string, number | string | boolean>;
export class Generic extends BaseOperation<GenericParameters> {
public get default() {
return {};
}
public appendCrop: boolean;
public name: string;
constructor(
name: string,
parameters?: GenericParameters,
appendCrop?: boolean,
) {
super(parameters ?? {});
this.name = name;
this.appendCrop = appendCrop ?? false;
}
}

View File

@ -1,34 +0,0 @@
import {BaseOperation} from './base.js';
export interface MazeParameters {
algorithmType: 'depth-first' | 'prim';
bgColor: string;
fgColor: string;
seed: number;
tileable: boolean;
x: number;
y: number;
}
export class Maze extends BaseOperation<MazeParameters> {
public static default: MazeParameters = {
algorithmType: 'depth-first',
bgColor: '#fff',
fgColor: '#000',
seed: 0,
tileable: false,
x: 16,
y: 16,
};
public get default() {
return Maze.default;
}
public appendCrop = false;
public name = 'gegl:maze';
constructor(parameters?: Partial<MazeParameters>) {
super({...Maze.default, ...parameters});
}
}

View File

@ -1,32 +0,0 @@
import {BaseOperation} from './base.js';
export interface MedianBlurParameters {
abyssPolicy: 'none' | 'clamp';
alphaPercentile: number;
highPrecision: boolean;
neighborhood: 'square' | 'circle' | 'diamond';
percentile: number;
radius: number;
}
export class MedianBlur extends BaseOperation<MedianBlurParameters> {
public static default: MedianBlurParameters = {
abyssPolicy: 'clamp',
alphaPercentile: 50,
highPrecision: false,
neighborhood: 'circle',
percentile: 50,
radius: 3,
};
public get default() {
return MedianBlur.default;
}
public appendCrop = false;
public name = 'gegl:median-blur';
constructor(parameters?: Partial<MedianBlurParameters>) {
super({...MedianBlur.default, ...parameters});
}
}

View File

@ -1,46 +0,0 @@
import {BaseOperation} from './base.js';
export interface MirrorsParameters {
clip: boolean;
cX: number;
cY: number;
inputScale: number;
mAngle: number;
nSegs: number;
outputScale: number;
oX: number;
oY: number;
rAngle: number;
trimX: number;
trimY: number;
warp: boolean;
}
export class Mirrors extends BaseOperation<MirrorsParameters> {
public static default: MirrorsParameters = {
clip: true,
cX: 0.5,
cY: 0.5,
inputScale: 100,
mAngle: 0,
nSegs: 6,
outputScale: 1,
oX: 0,
oY: 0,
rAngle: 0,
trimX: 0,
trimY: 0,
warp: true,
};
public get default() {
return Mirrors.default;
}
public appendCrop = false;
public name = 'gegl:mirrors';
constructor(parameters?: Partial<MirrorsParameters>) {
super({...Mirrors.default, ...parameters});
}
}

View File

@ -1,48 +0,0 @@
import {BaseOperation} from './base.js';
export interface MosaicParameters {
antialiasing: boolean;
colorAveraging: boolean;
colorVariation: number;
jointsColor: string;
lightColor: string;
lightDir: number;
seed: number;
tileAllowSplit: boolean;
tileHeight: number;
tileNeatness: number;
tileSize: number;
tileSpacing: number;
tileSurface: boolean;
tileType: 'squares' | 'hexagons' | 'octagons' | 'triangles';
}
export class Mosaic extends BaseOperation<MosaicParameters> {
public static default: MosaicParameters = {
antialiasing: true,
colorAveraging: true,
colorVariation: 0.2,
jointsColor: '#000',
lightColor: '#fff',
lightDir: 135,
seed: 0,
tileAllowSplit: true,
tileHeight: 4,
tileNeatness: 0.65,
tileSize: 15,
tileSpacing: 1,
tileSurface: false,
tileType: 'hexagons',
};
public get default() {
return Mosaic.default;
}
public appendCrop = false;
public name = 'gegl:mosaic';
constructor(parameters?: Partial<MosaicParameters>) {
super({...Mosaic.default, ...parameters});
}
}

View File

@ -1,58 +0,0 @@
import {BaseOperation} from './base.js';
type NewsprintPattern = 'line' | 'circle' | 'diamond' | 'pssquare' | 'cross';
export interface NewsprintParameters {
aaSamples: number;
angle: number;
angle2: number;
angle3: number;
angle4: number;
angleboost: number;
blackPullout: number;
blocksize: number;
colorModel: 'black-on-white' | 'cmyk' | 'rgb' | 'white-on-black';
pattern: NewsprintPattern;
pattern2: NewsprintPattern;
pattern3: NewsprintPattern;
pattern4: NewsprintPattern;
period: number;
period2: number;
period3: number;
period4: number;
turbulence: number;
}
export class Newsprint extends BaseOperation<NewsprintParameters> {
public static default: NewsprintParameters = {
aaSamples: 16,
angle: 75,
angle2: 15,
angle3: 45,
angle4: 0,
angleboost: 0,
blackPullout: 1,
blocksize: -1,
colorModel: 'black-on-white',
pattern: 'line',
pattern2: 'line',
pattern3: 'line',
pattern4: 'line',
period: 12,
period2: 12,
period3: 12,
period4: 12,
turbulence: 0,
};
public get default() {
return Newsprint.default;
}
public appendCrop = false;
public name = 'gegl:newsprint';
constructor(parameters?: Partial<NewsprintParameters>) {
super({...Newsprint.default, ...parameters});
}
}

View File

@ -1,26 +0,0 @@
import {BaseOperation} from './base.js';
export interface NoisePickParameters {
pctRandom: number;
repeat: number;
seed: number;
}
export class NoisePick extends BaseOperation<NoisePickParameters> {
public static default: NoisePickParameters = {
pctRandom: 50,
repeat: 1,
seed: 0,
};
public get default() {
return NoisePick.default;
}
public appendCrop = true;
public name = 'gegl:noise-pick';
constructor(parameters?: Partial<NoisePickParameters>) {
super({...NoisePick.default, ...parameters});
}
}

View File

@ -1,28 +0,0 @@
import {BaseOperation} from './base.js';
export interface OilifyParameters {
exponent: number;
intensities: number;
maskRadius: number;
useInten: boolean;
}
export class Oilify extends BaseOperation<OilifyParameters> {
public static default: OilifyParameters = {
exponent: 8,
intensities: 128,
maskRadius: 4,
useInten: true,
};
public get default() {
return Oilify.default;
}
public appendCrop = false;
public name = 'gegl:oilify';
constructor(parameters?: Partial<OilifyParameters>) {
super({...Oilify.default, ...parameters});
}
}

View File

@ -1,32 +0,0 @@
import {BaseOperation} from './base.js';
export interface PlasmaParameters {
height: number;
seed: number;
turbulence: number;
width: number;
x: number;
y: number;
}
export class Plasma extends BaseOperation<PlasmaParameters> {
public static default: PlasmaParameters = {
height: 768,
seed: 0,
turbulence: 1,
width: 1024,
x: 0,
y: 0,
};
public get default() {
return Plasma.default;
}
public appendCrop = false;
public name = 'gegl:plasma';
constructor(parameters?: Partial<PlasmaParameters>) {
super({...Plasma.default, ...parameters});
}
}

View File

@ -1,26 +0,0 @@
import {BaseOperation} from './base.js';
export interface SimplexNoiseParameters {
iterations: number;
scale: number;
seed: number;
}
export class SimplexNoise extends BaseOperation<SimplexNoiseParameters> {
public static default: SimplexNoiseParameters = {
iterations: 1,
scale: 1,
seed: 1,
};
public get default() {
return SimplexNoise.default;
}
public appendCrop = true;
public name = 'gegl:simplex-noise';
constructor(parameters?: Partial<SimplexNoiseParameters>) {
super({...SimplexNoise.default, ...parameters});
}
}

View File

@ -1,26 +0,0 @@
import {BaseOperation} from './base.js';
export interface SoftglowParameters {
brightness: number;
glowRadius: number;
sharpness: number;
}
export class Softglow extends BaseOperation<SoftglowParameters> {
public static default: SoftglowParameters = {
brightness: 0.3,
glowRadius: 10,
sharpness: 0.85,
};
public get default() {
return Softglow.default;
}
public appendCrop = false;
public name = 'gegl:softglow';
constructor(parameters?: Partial<SoftglowParameters>) {
super({...Softglow.default, ...parameters});
}
}

View File

@ -1,36 +0,0 @@
import {BaseOperation} from './base.js';
export interface StereographicProjectionParameters {
height: number;
inverse: boolean;
pan: number;
samplerType: 'nearest' | 'linear' | 'cubic' | 'nohalo' | 'lohalo';
spin: number;
tilt: number;
width: number;
zoom: number;
}
export class StereographicProjection extends BaseOperation<StereographicProjectionParameters> {
public static default: StereographicProjectionParameters = {
height: -1,
inverse: false,
pan: 0,
samplerType: 'nearest',
spin: 0,
tilt: 90,
width: -1,
zoom: 100,
};
public get default() {
return StereographicProjection.default;
}
public appendCrop = false;
public name = 'gegl:stereographic-projection';
constructor(parameters?: Partial<StereographicProjectionParameters>) {
super({...StereographicProjection.default, ...parameters});
}
}

View File

@ -1,24 +0,0 @@
import {BaseOperation} from './base.js';
export interface TileGlassParameters {
tileHeight: number;
tileWidth: number;
}
export class TileGlass extends BaseOperation<TileGlassParameters> {
public static default: TileGlassParameters = {
tileHeight: 25,
tileWidth: 25,
};
public get default() {
return TileGlass.default;
}
public appendCrop = false;
public name = 'gegl:tile-glass';
constructor(parameters?: Partial<TileGlassParameters>) {
super({...TileGlass.default, ...parameters});
}
}

View File

@ -1,16 +0,0 @@
import {BaseOperation} from './base.js';
export type TileSeamlessParameters = Record<string, unknown>;
export class TileSeamless extends BaseOperation<TileSeamlessParameters> {
public get default() {
return {};
}
public appendCrop = false;
public name = 'gegl:tile-seamless';
constructor() {
super({});
}
}

View File

@ -1,28 +0,0 @@
import {BaseOperation} from './base.js';
export interface WaterpixelsParameters {
fill: 'average' | 'random';
regularization: number;
size: number;
smoothness: number;
}
export class Waterpixels extends BaseOperation<WaterpixelsParameters> {
public static default: WaterpixelsParameters = {
fill: 'average',
regularization: 0,
size: 32,
smoothness: 1,
};
public get default() {
return Waterpixels.default;
}
public appendCrop = false;
public name = 'gegl:waterpixels';
constructor(parameters?: Partial<WaterpixelsParameters>) {
super({...Waterpixels.default, ...parameters});
}
}

View File

@ -1,36 +0,0 @@
import {BaseOperation} from './base.js';
export interface WavesParameters {
amplitude: number;
aspect: number;
clamp: boolean;
period: number;
phi: number;
samplerType: 'nearest' | 'linear' | 'cubic' | 'nohalo' | 'lohalo';
x: number;
y: number;
}
export class Waves extends BaseOperation<WavesParameters> {
public static default: WavesParameters = {
amplitude: 25,
aspect: 1,
clamp: false,
period: 100,
phi: 0,
samplerType: 'cubic',
x: 0.5,
y: 0.5,
};
public get default() {
return Waves.default;
}
public appendCrop = true;
public name = 'gegl:waves';
constructor(parameters?: Partial<WavesParameters>) {
super({...Waves.default, ...parameters});
}
}

View File

@ -1,132 +0,0 @@
import fsp from 'node:fs/promises';
import path from 'node:path';
import {performance} from 'node:perf_hooks';
import {execa} from 'execa';
import meow from 'meow';
import {Crop} from './gegl/exports.js';
import Project from './project.js';
import p2022 from './2022/projects.js';
async function main(): Promise<void> {
const cli = meow(
`
Options
--filter <name> Only render projects starting with <name>.
--include-defaults Include default GEGL operation parameters.
--no-render Don't render any images.
`,
{
flags: {
filter: {
default: '',
type: 'string',
},
includeDefaults: {
default: false,
type: 'boolean',
},
render: {
default: true,
type: 'boolean',
},
},
importMeta: import.meta,
},
);
const includeDefaults = cli.flags.includeDefaults;
const noRender = !cli.flags.render;
const projects: Project[] = [...p2022].filter((project) =>
project.name.startsWith(cli.flags.filter),
);
for (const {
createInputImage,
name,
operations,
resolution,
resetAlpha,
} of projects) {
const dataStart = performance.now();
const {width, height} = resolution;
const baseDir = path.resolve(`./output/${name}`);
await fsp.mkdir(baseDir, {recursive: true});
console.log(`# ${name}`);
console.log(`* ${width}x${height}`);
console.log(`* ${operations.length} operations`);
const graph = operations.flatMap((operation) => {
const graph = operation.graph(includeDefaults);
if (operation.appendCrop) {
graph.push(...new Crop({height, width}).graph(includeDefaults));
}
return graph;
});
const prettyGraph = graph.map((operation) =>
operation.startsWith('gegl:') ? `\n${operation}\n` : ` ${operation}\n`,
);
const graphFile = `${name}.txt`;
const outputFile = `${name}.png`;
const compressedFile = `${outputFile.slice(0, -4)}.jpeg`;
console.log(`* Writing ${graphFile}`);
await fsp.writeFile(
path.join(baseDir, graphFile),
prettyGraph.join('').trimStart(),
);
if (noRender) {
console.log(`* Skipped ${outputFile}`);
} else {
const fullOutputFile = path.join(baseDir, outputFile);
if (createInputImage) {
await execa('convert', [
'-size',
`${width}x${height}`,
'xc:white',
fullOutputFile,
]);
}
console.log(`* Writing ${outputFile}`);
await execa('gegl', [
...(createInputImage ? ['-i', fullOutputFile] : []),
'-o',
fullOutputFile,
'--',
...graph,
]);
if (resetAlpha) {
await execa('convert', [
fullOutputFile,
'-alpha',
'Off',
fullOutputFile,
]);
}
console.log(`* Writing ${compressedFile}`);
await execa('convert', [
fullOutputFile,
'-quality',
'92',
path.join(baseDir, compressedFile),
]);
}
const time = (performance.now() - dataStart).toFixed(2);
console.log(`* Generated in ${time}ms`);
}
}
void main();

View File

@ -1,12 +0,0 @@
import {BaseOperation} from './gegl/exports.js';
export default interface Project {
createInputImage: boolean;
name: string;
operations: Array<InstanceType<typeof BaseOperation>>;
resetAlpha: boolean;
resolution: {
height: number;
width: number;
};
}