mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
G2: Effect › Artistic › Rough Pastels raster filter
Squashed from #3044 onto main.
This commit is contained in:
@@ -406,6 +406,21 @@ pub fn effect_catalog() -> Vec<EffectInfo> {
|
||||
"{edgeThickness: 0..10 (2; wider lines), edgeIntensity: 0..10 (1; darker lines, on fainter edges too), posterization: 0..6 (2; posterization + 2 levels per colour channel)} reduces the object's colours and draws black lines on its edges, keeping its coverage. Original visual approximation; chosen VectorCraft defaults.",
|
||||
json!({"edgeThickness": 2.0, "edgeIntensity": 1.0, "posterization": 2.0}),
|
||||
),
|
||||
r(
|
||||
"artistic.roughPastels",
|
||||
"Rough Pastels…",
|
||||
ARTISTIC,
|
||||
"{strokeLength: 0..40 (6; longer pastel strokes), strokeDetail: 1..20 (10; bristle texture along the strokes), texture: \"brick\"|\"burlap\"|\"canvas\"|\"sandstone\" (\"canvas\"), scaling: % 50..200 (100), relief: 0..50 (4), lightDirection: \"bottom\"|\"bottomLeft\"|\"left\"|\"topLeft\"|\"top\"|\"topRight\"|\"right\"|\"bottomRight\" (\"top\"), invert: bool (false)} repaints the object in soft diagonal pastel strokes over a textured surface, keeping its coverage. Slider ranges follow the documented controls; numeric defaults are chosen for VectorCraft and are not verified against proprietary defaults.",
|
||||
json!({
|
||||
"strokeLength": 6.0,
|
||||
"strokeDetail": 10.0,
|
||||
"texture": "canvas",
|
||||
"scaling": 100.0,
|
||||
"relief": 4.0,
|
||||
"lightDirection": "top",
|
||||
"invert": false
|
||||
}),
|
||||
),
|
||||
r(
|
||||
"artistic.smudgeStick",
|
||||
"Smudge Stick…",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Effect › Artistic (Cutout, Dry Brush, Film Grain, Neon Glow, Paint Daubs, Palette Knife, Plastic Wrap, Poster
|
||||
//! Edges, Smudge Stick, Sponge, Underpainting and Watercolor). Original filters built from
|
||||
//! Edges, Rough Pastels, Smudge Stick, Sponge, Underpainting and Watercolor). Original filters built from
|
||||
//! public behaviour documentation:
|
||||
//! <https://helpx.adobe.com/illustrator/using/summary-effects.html> and
|
||||
//! <https://helpx.adobe.com/photoshop-elements/using/artistic-filters.html>.
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
use std::f64::consts::TAU;
|
||||
|
||||
use super::brushstrokes::{Smear, mix, stroke_reach, unit, unpremultiply};
|
||||
use super::brushstrokes::{LEFT, RIGHT, Smear, TONE_SOFTNESS, mix, streak, stroke_reach, unit, unpremultiply};
|
||||
use super::edges::sobel;
|
||||
use super::pixelate::{Around, Place, Soft, cell, point_in, rand, value_noise};
|
||||
use super::texture::{self, Light, Texture, luma, premultiply, straight};
|
||||
use super::texture::{self, Light, Texture, Tones, luma, premultiply, straight, texturizer};
|
||||
use super::{PixelSpace, blur_plane, pick};
|
||||
use vectorcraft_geom::{Point, Vec2};
|
||||
|
||||
@@ -18,6 +18,8 @@ const SALT_DRY: u64 = 264;
|
||||
const MARGIN: f64 = 1.0;
|
||||
const SALT_PLASTIC: u64 = 512;
|
||||
|
||||
const SALT_PASTEL: u64 = 200;
|
||||
|
||||
const SALT_FILM: u64 = 256;
|
||||
const SALT_DAUB: u64 = 272;
|
||||
|
||||
@@ -526,6 +528,65 @@ pub(super) fn underpainting(
|
||||
}
|
||||
}
|
||||
|
||||
/// How far (document units) Rough Pastels reaches with strokes `len` long.
|
||||
pub(super) fn rough_pastels_reach(len: f64) -> f64 {
|
||||
super::brushstrokes::stroke_reach(len).max(super::brushstrokes::TONE_REACH)
|
||||
}
|
||||
|
||||
/// Rough Pastels: soft diagonal pastel strokes `length` (0..40) long with bristle `detail` (1..20),
|
||||
/// then the shared Texturizer surface (`texture`, `scaling`, `relief`, `light`, `invert`).
|
||||
/// Coverage is kept.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn rough_pastels(
|
||||
px: &mut [[u8; 4]],
|
||||
w: usize,
|
||||
h: usize,
|
||||
space: &PixelSpace,
|
||||
length: f64,
|
||||
detail: f64,
|
||||
texture: &Texture,
|
||||
scaling: f64,
|
||||
relief: f64,
|
||||
light: Light,
|
||||
invert: bool,
|
||||
) {
|
||||
if !([length, detail, scaling, relief].iter().all(|v| v.is_finite()) && space.px.is_finite() && space.px > 0.0) {
|
||||
return;
|
||||
}
|
||||
let length = length.clamp(0.0, 40.0);
|
||||
let detail = detail.clamp(1.0, 20.0);
|
||||
if length > 0.0 {
|
||||
let Some(place) = Place::new(space, w, h) else { return };
|
||||
let smear = Smear::new(px, w, h, &place, length.max(1.0));
|
||||
let tones = Tones::new(px, w, h, TONE_SOFTNESS / place.px);
|
||||
let row = (0.18 * smear.len).max(1.0);
|
||||
let stroke_mix = (0.35 + 0.0225 * detail).clamp(0.35, 0.8) as f32;
|
||||
let bristle = (0.015 + 0.0035 * detail) as f32;
|
||||
let src = px.to_vec();
|
||||
place.each(px, |x, y, p| {
|
||||
if p[3] == 0 {
|
||||
return;
|
||||
}
|
||||
let q = place.at(x, y);
|
||||
let pm = mix(smear.stroke(SALT_PASTEL, q, RIGHT, row), smear.stroke(SALT_PASTEL + 1, q, LEFT, row), 0.5);
|
||||
let orig = unit(src.get(y * w + x).copied().unwrap_or([0; 4]));
|
||||
let pm = mix(orig, pm, stroke_mix);
|
||||
let (mut c, a) = unpremultiply(pm);
|
||||
if a <= 0.0 {
|
||||
*p = [0; 4];
|
||||
return;
|
||||
}
|
||||
let dir = if tones.get(x, y) > 0.52 { RIGHT } else { LEFT };
|
||||
let n = bristle * streak(SALT_PASTEL + 2, q, dir, smear.len.max(1.0), row) as f32;
|
||||
c = c.map(|v| (v + n).clamp(0.0, 1.0));
|
||||
*p = premultiply(c, orig[3]);
|
||||
});
|
||||
}
|
||||
if relief > 0.0 {
|
||||
texturizer(px, w, h, space, texture, scaling, relief, light, invert);
|
||||
}
|
||||
}
|
||||
|
||||
/// Neon Glow: the object in dimmed greys, lit by `colour` glowing from its light areas (`size`
|
||||
/// above 0) or from its dark areas (below 0), spread as far as |`size`| (0..24) says and as
|
||||
/// strong as `brightness` (0..50). Coverage is kept.
|
||||
|
||||
@@ -231,7 +231,7 @@ fn frame(q: Point, dir: Vec2) -> (f64, f64) {
|
||||
/// How far along `dir` the stroke through `q` is shifted: strokes `len` long lie in rows `width`
|
||||
/// apart across `dir`, each row starting at random, each stroke shifted by up to [`JITTER`] ×
|
||||
/// `len`.
|
||||
fn stroke_shift(salt: u64, q: Point, dir: Vec2, len: f64, width: f64) -> f64 {
|
||||
pub(super) fn stroke_shift(salt: u64, q: Point, dir: Vec2, len: f64, width: f64) -> f64 {
|
||||
if !(len > 0.0 && width > 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Photoshop-style raster effects (Effect › Artistic › Cutout, Dry Brush, Film Grain, Neon Glow, Paint Daubs, Plastic Wrap and
|
||||
//! Poster Edges, Smudge Stick, Sponge and Watercolor, Blur › Radial Blur and Smart Blur, Brush Strokes › Accented Edges, Angled Strokes,
|
||||
//! Poster Edges, Rough Pastels, Smudge Stick, Sponge and Watercolor, Blur › Radial Blur and Smart Blur, Brush Strokes › Accented Edges, Angled Strokes,
|
||||
//! Crosshatch, Dark Strokes, Ink Outlines, Spatter, Sprayed Strokes and Sumi-e, Distort › Diffuse
|
||||
//! Glow, Glass and Ocean Ripple, Pixelate › Color Halftone, Crystallize, Mezzotint and Pointillize,
|
||||
//! Sharpen › Unsharp Mask, Sketch › Bas Relief, Chalk & Charcoal, Charcoal, Graphic Pen, Halftone Pattern, Note Paper, Photocopy, Plaster,
|
||||
@@ -44,7 +44,7 @@ pub use sketch::{HALFTONE_TYPES, HalftonePattern};
|
||||
pub use texture::{GRAIN_TYPES, Grain, LIGHT_DIRECTIONS, Light, TEXTURES, TEXTURES_LOADED, Texture};
|
||||
|
||||
/// The Photoshop-style effect ids (all raster effects, see [`crate::is_raster`]).
|
||||
pub const PIXEL_EFFECTS: [&str; 51] = [
|
||||
pub const PIXEL_EFFECTS: [&str; 52] = [
|
||||
"artistic.cutout",
|
||||
"artistic.dryBrush",
|
||||
"artistic.filmGrain",
|
||||
@@ -53,6 +53,7 @@ pub const PIXEL_EFFECTS: [&str; 51] = [
|
||||
"artistic.paletteKnife",
|
||||
"artistic.plasticWrap",
|
||||
"artistic.posterEdges",
|
||||
"artistic.roughPastels",
|
||||
"artistic.smudgeStick",
|
||||
"artistic.sponge",
|
||||
"artistic.underpainting",
|
||||
@@ -143,6 +144,10 @@ pub enum PixelFx {
|
||||
/// `texture` surface (`scaling`, `relief`, `light`, `invert`) blended in as strongly as
|
||||
/// `texture_coverage` (0..40) says.
|
||||
Underpainting { brush_size: f64, texture_coverage: f64, texture: Texture, scaling: f64, relief: f64, light: Light, invert: bool },
|
||||
/// Artistic › Rough Pastels: diagonal pastel strokes `length` (0..40) long, bristle detail
|
||||
/// (1..20), then a [`Texture`] surface scaled by `scaling` (0.5..2), in relief as strong as
|
||||
/// `relief` (0..50) and lit from `light`; `invert` turns the surface's heights over.
|
||||
RoughPastels { length: f64, detail: f64, texture: Texture, scaling: f64, relief: f64, light: Light, invert: bool },
|
||||
/// Blur › Radial Blur around the object's centre: along arcs (spin, an arc of `amount`°) or
|
||||
/// along rays (zoom, the content scaled by up to about ±`amount`/2 %), averaging 2^`passes` samples.
|
||||
RadialBlur { amount: f64, zoom: bool, passes: u32 },
|
||||
@@ -346,6 +351,15 @@ pub(crate) fn parse(id: &str, p: &Value) -> Option<PixelFx> {
|
||||
light: Light::parse(text(p, "lightDirection", "top")),
|
||||
invert: flag(p, "invert", false),
|
||||
},
|
||||
"artistic.roughPastels" => PixelFx::RoughPastels {
|
||||
length: num(p, "strokeLength", 6.0).clamp(0.0, 40.0),
|
||||
detail: num(p, "strokeDetail", 10.0).clamp(1.0, 20.0),
|
||||
texture: Texture::parse(text(p, "texture", "canvas")),
|
||||
scaling: num(p, "scaling", 100.0).clamp(50.0, 200.0) / 100.0,
|
||||
relief: num(p, "relief", 4.0).clamp(0.0, 50.0),
|
||||
light: Light::parse(text(p, "lightDirection", "top")),
|
||||
invert: flag(p, "invert", false),
|
||||
},
|
||||
"artistic.smudgeStick" => PixelFx::SmudgeStick {
|
||||
stroke: num(p, "strokeLength", 2.0).clamp(0.0, 10.0),
|
||||
highlight: num(p, "highlightArea", 12.0).clamp(0.0, 20.0),
|
||||
@@ -558,9 +572,10 @@ impl PixelFx {
|
||||
PixelFx::AccentedEdges { .. } => 0.0,
|
||||
// Strokes reach out of the object as far as they reach into it.
|
||||
PixelFx::PaletteKnife { stroke_size, softness, .. } => artistic::palette_knife_reach(stroke_size, softness),
|
||||
PixelFx::AngledStrokes { length, .. } | PixelFx::GraphicPen { length, .. } | PixelFx::InkOutlines { length, .. } => {
|
||||
brushstrokes::stroke_reach(length)
|
||||
}
|
||||
PixelFx::AngledStrokes { length, .. }
|
||||
| PixelFx::GraphicPen { length, .. }
|
||||
| PixelFx::InkOutlines { length, .. }
|
||||
| PixelFx::RoughPastels { length, .. } => brushstrokes::stroke_reach(length),
|
||||
PixelFx::Crosshatch { length, .. } => brushstrokes::stroke_reach(length) + brushstrokes::rough(length),
|
||||
PixelFx::DarkStrokes { .. } => brushstrokes::stroke_reach(brushstrokes::LIGHT_LENGTH),
|
||||
PixelFx::Spatter { radius, .. } => brushstrokes::spatter_shift(radius),
|
||||
@@ -622,6 +637,7 @@ impl PixelFx {
|
||||
PixelFx::AngledStrokes { length, .. } | PixelFx::GraphicPen { length, .. } => {
|
||||
Some(brushstrokes::stroke_reach(length).max(brushstrokes::TONE_REACH))
|
||||
}
|
||||
PixelFx::RoughPastels { length, .. } => Some(artistic::rough_pastels_reach(length)),
|
||||
PixelFx::Crosshatch { length, .. } => {
|
||||
Some((brushstrokes::stroke_reach(length) + brushstrokes::rough(length)).max(brushstrokes::TONE_REACH))
|
||||
}
|
||||
@@ -701,6 +717,9 @@ impl PixelFx {
|
||||
PixelFx::Underpainting { brush_size, texture_coverage, ref texture, scaling, relief, light, invert } => {
|
||||
artistic::underpainting(px, w, h, space, brush_size, texture_coverage, texture, scaling, relief, light, invert)
|
||||
}
|
||||
PixelFx::RoughPastels { length, detail, ref texture, scaling, relief, light, invert } => {
|
||||
artistic::rough_pastels(px, w, h, space, length, detail, texture, scaling, relief, light, invert)
|
||||
}
|
||||
PixelFx::RadialBlur { amount, zoom, passes } => blur::radial(px, w, h, space, amount, zoom, passes),
|
||||
PixelFx::SmartBlur { radius, threshold, samples, mode: SmartBlurMode::Normal } => {
|
||||
blur::smart(px, w, h, to_px(radius), threshold, samples)
|
||||
|
||||
@@ -1222,6 +1222,8 @@ fn texture_params_take_defaults_and_stay_in_range() {
|
||||
("texture.grain", "grainType", GRAIN_TYPES.as_slice()),
|
||||
("texture.texturizer", "texture", TEXTURES.as_slice()),
|
||||
("texture.texturizer", "lightDirection", LIGHT_DIRECTIONS.as_slice()),
|
||||
("artistic.roughPastels", "texture", TEXTURES.as_slice()),
|
||||
("artistic.roughPastels", "lightDirection", LIGHT_DIRECTIONS.as_slice()),
|
||||
] {
|
||||
let doc = crate::effect_info(id).unwrap().params;
|
||||
let parsed: Vec<PixelFx> = table.iter().map(|(_, v)| fx(id, json!({ key: v }))).collect();
|
||||
@@ -2466,6 +2468,17 @@ fn artistic_params_take_defaults_and_stay_in_range() {
|
||||
invert: true,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
fx("artistic.roughPastels", json!({})),
|
||||
PixelFx::RoughPastels { length: 6.0, detail: 10.0, texture: Texture::Canvas, scaling: 1.0, relief: 4.0, light: Light::Top, invert: false }
|
||||
);
|
||||
assert_eq!(
|
||||
fx(
|
||||
"artistic.roughPastels",
|
||||
json!({"strokeLength": 0, "strokeDetail": 99, "texture": -3, "scaling": 10, "relief": 60, "lightDirection": "up", "invert": true})
|
||||
),
|
||||
PixelFx::RoughPastels { length: 0.0, detail: 20.0, texture: Texture::Canvas, scaling: 0.5, relief: 50.0, light: Light::Top, invert: true }
|
||||
);
|
||||
assert_eq!(fx("artistic.plasticWrap", json!({})), PixelFx::PlasticWrap { highlight: 20.0, detail: 12.0, smoothness: 15.0 });
|
||||
assert_eq!(
|
||||
fx("artistic.plasticWrap", json!({"highlightStrength": -1, "detail": 99, "smoothness": 0})),
|
||||
@@ -2493,6 +2506,7 @@ fn artistic_params_take_defaults_and_stay_in_range() {
|
||||
assert!(parsed.iter().skip(i + 1).all(|p| *p != parsed[i]), "{id} {v}");
|
||||
}
|
||||
}
|
||||
assert!(fx("artistic.roughPastels", json!({})).outset(Rect::new(0.0, 0.0, 40.0, 30.0)) > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2520,6 +2534,7 @@ fn artistic_filters_leave_invalid_coordinate_spaces_alone() {
|
||||
light: Light::Top,
|
||||
invert: false,
|
||||
},
|
||||
PixelFx::RoughPastels { length: 6.0, detail: 10.0, texture: Texture::Canvas, scaling: 1.0, relief: 4.0, light: Light::Top, invert: false },
|
||||
];
|
||||
for f in &filters {
|
||||
assert_ne!(run(f, &space(w, h)), src, "{f:?} changes the art in a valid space");
|
||||
@@ -2622,6 +2637,20 @@ fn cutout_paints_a_few_flat_colours_and_keeps_coverage() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rough_pastels_keeps_coverage_and_longer_strokes_smear_more() {
|
||||
let (w, h) = (48, 48);
|
||||
let src = ramp(w, h);
|
||||
let mut short = src.clone();
|
||||
let mut long = src.clone();
|
||||
fx("artistic.roughPastels", json!({"strokeLength": 8, "strokeDetail": 18, "relief": 12})).apply(&mut short, w, h, &space(w, h));
|
||||
fx("artistic.roughPastels", json!({"strokeLength": 32, "strokeDetail": 18, "relief": 12})).apply(&mut long, w, h, &space(w, h));
|
||||
assert!(short.as_chunks::<4>().0.iter().zip(src.as_chunks::<4>().0).all(|(o, s)| o[3] == s[3]));
|
||||
let changed = |a: &Vec<u8>, b: &Vec<u8>| a.as_chunks::<4>().0.iter().zip(b.as_chunks::<4>().0).filter(|(o, s)| o != s).count();
|
||||
assert!(changed(&short, &src) > w * h / 8, "short strokes repaint many pixels");
|
||||
assert!(changed(&long, &short) > w * h / 16, "longer strokes smear differently");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cutout_simplicity_smooths_the_pieces_edges() {
|
||||
// A noisy grey: simpler edges join the speckles into fewer changes between neighbours.
|
||||
@@ -2747,6 +2776,7 @@ fn artistic_filters_look_the_same_at_any_resolution() {
|
||||
("artistic.neonGlow", json!({"glowSize": 12, "glowBrightness": 30})),
|
||||
("artistic.posterEdges", json!({"edgeThickness": 6, "edgeIntensity": 6})),
|
||||
("artistic.underpainting", json!({"brushSize": 12, "textureCoverage": 20, "relief": 10})),
|
||||
("artistic.roughPastels", json!({"strokeLength": 12, "strokeDetail": 15, "texture": "burlap", "relief": 10})),
|
||||
] {
|
||||
let (mut a, mut b) = (coarse.clone(), fine.clone());
|
||||
fx(id, p.clone()).apply(&mut a, w, h, &space(w, h));
|
||||
|
||||
@@ -31,7 +31,7 @@ const BRUSH_STROKES: [(&str, &str); 8] = [
|
||||
];
|
||||
|
||||
/// Effect › Artistic, at their defaults.
|
||||
const ARTISTIC: [(&str, &str); 12] = [
|
||||
const ARTISTIC: [(&str, &str); 13] = [
|
||||
("artistic.cutout", "{}"),
|
||||
("artistic.dryBrush", "{}"),
|
||||
("artistic.filmGrain", "{}"),
|
||||
@@ -42,6 +42,7 @@ const ARTISTIC: [(&str, &str); 12] = [
|
||||
("artistic.plasticWrap", "{}"),
|
||||
("artistic.posterEdges", "{}"),
|
||||
("artistic.underpainting", "{}"),
|
||||
("artistic.roughPastels", "{}"),
|
||||
("artistic.smudgeStick", "{}"),
|
||||
("artistic.sponge", "{}"),
|
||||
("artistic.watercolor", "{}"),
|
||||
@@ -227,6 +228,19 @@ fn artistic_settings_survive_a_save_and_open() {
|
||||
json!({"highlightStrength": 18.0, "detail": 10.0, "smoothness": 8.0}),
|
||||
[json!({"highlightStrength": 5.0}), json!({"highlightStrength": 0.0})],
|
||||
),
|
||||
(
|
||||
"artistic.roughPastels",
|
||||
json!({
|
||||
"strokeLength": 8.0,
|
||||
"strokeDetail": 12.0,
|
||||
"texture": "sandstone",
|
||||
"scaling": 100.0,
|
||||
"relief": 8.0,
|
||||
"lightDirection": "topLeft",
|
||||
"invert": false
|
||||
}),
|
||||
[json!({"strokeLength": 20.0}), json!({"relief": 0.0})],
|
||||
),
|
||||
] {
|
||||
let (mut s, g) = striped();
|
||||
// Black and a grey beside the reds: Cutout puts the grey with black at 2 levels and apart
|
||||
|
||||
@@ -373,6 +373,10 @@ fn structured_junk() {
|
||||
("effect.apply", json!({"effect": "artistic.dryBrush", "params": {"brushSize": -1e308, "brushDetail": "NaN", "texture": 1e308}})),
|
||||
("effect.apply", json!({"effect": "artistic.neonGlow", "params": {"glowSize": -1e308, "glowBrightness": "1e999", "color": [1]}})),
|
||||
("effect.apply", json!({"effect": "artistic.posterEdges", "params": {"edgeThickness": 1e308, "edgeIntensity": [], "posterization": -7}})),
|
||||
(
|
||||
"effect.apply",
|
||||
json!({"effect": "artistic.roughPastels", "params": {"strokeLength": 1e308, "strokeDetail": "NaN", "texture": -1e308, "scaling": "bad", "lightDirection": "nope"}}),
|
||||
),
|
||||
("effect.apply", json!({"effect": "sketch.chrome", "params": {"detail": -1e308, "smoothness": "NaN"}})),
|
||||
("effect.apply", json!({"effect": "sketch.graphicPen", "params": {"strokeLength": -1e308, "lightDarkBalance": "NaN", "strokeDirection": 3}})),
|
||||
("effect.apply", json!({"effect": "sketch.halftonePattern", "params": {"size": -1e308, "contrast": "NaN", "patternType": 3}})),
|
||||
|
||||
@@ -4568,7 +4568,9 @@ lighting Light Светлина
|
||||
Paint Daubs Мазки с боя
|
||||
Palette Knife Нож за палитра
|
||||
Poster Edges… Плакатни ръбове…
|
||||
Rough Pastels… Груби пастели…
|
||||
Poster Edges Плакатни ръбове
|
||||
Rough Pastels Груби пастели
|
||||
Underpainting… Подбоя…
|
||||
Underpainting Подбоя
|
||||
Levels Нива
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5067,7 +5067,9 @@ imageTrace Outline Obrys
|
||||
Paint Daubs Malířské tahy
|
||||
Palette Knife Špachtle
|
||||
Poster Edges… Plakátové okraje…
|
||||
Rough Pastels… Hrubé pastely…
|
||||
Poster Edges Plakátové okraje
|
||||
Rough Pastels Hrubé pastely
|
||||
Underpainting… Podmalba…
|
||||
Underpainting Podmalba
|
||||
Levels Úrovně
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5187,6 +5187,7 @@ swatch Bright Violet Kraftig violet
|
||||
Neon Glow… Neonglød…
|
||||
Palette Knife… Paletkniv…
|
||||
Poster Edges… Plakatkanter…
|
||||
Rough Pastels… Grove pasteller…
|
||||
Cutout Udklip
|
||||
Dry Brush Tør pensel
|
||||
Neon Glow Neonglød
|
||||
@@ -5194,6 +5195,7 @@ swatch Bright Violet Kraftig violet
|
||||
Paint Daubs Malerklatter
|
||||
Palette Knife Paletkniv
|
||||
Poster Edges Plakatkanter
|
||||
Rough Pastels Grove pasteller
|
||||
Underpainting… Undermaling…
|
||||
Underpainting Undermaling
|
||||
Apply Data Set Anvend datasæt
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4654,7 +4654,9 @@ lighting Light Licht
|
||||
Paint Daubs Tupfer
|
||||
Palette Knife Palettenmesser
|
||||
Poster Edges… Posterkanten…
|
||||
Rough Pastels… Pastellkreide…
|
||||
Poster Edges Posterkanten
|
||||
Rough Pastels Pastellkreide
|
||||
Underpainting… Untermalung…
|
||||
Underpainting Untermalung
|
||||
Levels Stufen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2277,7 +2277,9 @@ lighting Light Φως
|
||||
Paint Daubs Πινελιές βαφής
|
||||
Palette Knife Μαχαίρι παλέτας
|
||||
Poster Edges… Άκρες αφίσας…
|
||||
Rough Pastels… Χοντρά παστέλ…
|
||||
Poster Edges Άκρες αφίσας
|
||||
Rough Pastels Χοντρά παστέλ
|
||||
Underpainting… Υποζωγραφία…
|
||||
Underpainting Υποζωγραφία
|
||||
Levels Επίπεδα
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2038 and column 19.
|
@@ -4655,7 +4655,9 @@ lighting Light Luz
|
||||
Paint Daubs Pinceladas
|
||||
Palette Knife Espátula
|
||||
Poster Edges… Bordes de póster…
|
||||
Rough Pastels… Pastel rudo…
|
||||
Poster Edges Bordes de póster
|
||||
Rough Pastels Pastel rudo
|
||||
Underpainting… Subpintura…
|
||||
Underpainting Subpintura
|
||||
Levels Niveles
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4962,7 +4962,9 @@ imageTrace Outline Ääriviiva
|
||||
Paint Daubs Maalitahrat
|
||||
Palette Knife Palettiveitsi
|
||||
Poster Edges… Julisteen reunat…
|
||||
Rough Pastels… Karkeat pastellit…
|
||||
Poster Edges Julisteen reunat
|
||||
Rough Pastels Karkeat pastellit
|
||||
Underpainting… Alapinta…
|
||||
Underpainting Alapinta
|
||||
Levels Tasot
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4665,7 +4665,9 @@ lighting Light Lumière
|
||||
Paint Daubs Empâtements
|
||||
Palette Knife Couteau à palette
|
||||
Poster Edges… Bords d’affiche…
|
||||
Rough Pastels… Pastels secs…
|
||||
Poster Edges Bords d’affiche
|
||||
Rough Pastels Pastels secs
|
||||
Underpainting… Sous-peinture…
|
||||
Underpainting Sous-peinture
|
||||
Levels Niveaux
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1598,7 +1598,9 @@ file-filter Templates Sablonok
|
||||
Paint Daubs Festékpaca
|
||||
Palette Knife Palettakés
|
||||
Poster Edges… Poszterszélek…
|
||||
Rough Pastels… Durva pasztell…
|
||||
Poster Edges Poszterszélek
|
||||
Rough Pastels Durva pasztell
|
||||
Underpainting… Alapozás…
|
||||
Underpainting Alapozás
|
||||
Levels Szintek
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5187,6 +5187,7 @@ swatch Bright Violet Violet cerah
|
||||
Neon Glow… Pendar neon…
|
||||
Palette Knife… Pisau palet…
|
||||
Poster Edges… Tepi poster…
|
||||
Rough Pastels… Pastel kasar…
|
||||
Cutout Potongan
|
||||
Dry Brush Kuas kering
|
||||
Neon Glow Pendar neon
|
||||
@@ -5194,6 +5195,7 @@ swatch Bright Violet Violet cerah
|
||||
Paint Daubs Coretan cat
|
||||
Palette Knife Pisau palet
|
||||
Poster Edges Tepi poster
|
||||
Rough Pastels Pastel kasar
|
||||
Underpainting… Underpainting…
|
||||
Underpainting Underpainting
|
||||
Apply Data Set Terapkan set data
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3808 and column 19.
|
@@ -4697,7 +4697,9 @@ lighting Light Luce
|
||||
Paint Daubs Pennellate
|
||||
Palette Knife Spatola
|
||||
Poster Edges… Bordi poster…
|
||||
Rough Pastels… Pastelli grezzi…
|
||||
Poster Edges Bordi poster
|
||||
Rough Pastels Pastelli grezzi
|
||||
Underpainting… Sottopittura…
|
||||
Underpainting Sottopittura
|
||||
Levels Livelli
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4736,7 +4736,9 @@ lighting Light ライト
|
||||
Paint Daubs ペイントダブ
|
||||
Palette Knife パレットナイフ
|
||||
Poster Edges… ポスターエッジ…
|
||||
Rough Pastels… ラフパステル…
|
||||
Poster Edges ポスターエッジ
|
||||
Rough Pastels ラフパステル
|
||||
Underpainting… アンダーペインティング…
|
||||
Underpainting アンダーペインティング
|
||||
Levels レベル数
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5096,9 +5096,11 @@ imageTrace Outline კონტური
|
||||
Persistent მუდმივი
|
||||
Place from Library ბიბლიოთეკიდან განთავსება
|
||||
Poster Edges პოსტერის კიდეები
|
||||
Rough Pastels მკვრივი პასტელი
|
||||
Underpainting… ქვეფენის მხატვრობა…
|
||||
Underpainting ქვეფენის მხატვრობა
|
||||
Poster Edges… პოსტერის კიდეები…
|
||||
Rough Pastels… მკვრივი პასტელი…
|
||||
Posterization პოსტერიზაცია
|
||||
Previous Artboard წინა სამუშაო დაფა
|
||||
Rearrange Artboards სამუშაო დაფების გადალაგება
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4660,7 +4660,9 @@ lighting Light 광원
|
||||
Paint Daubs 페인트 다브
|
||||
Palette Knife 팔레트 나이프
|
||||
Poster Edges… 포스터 가장자리…
|
||||
Rough Pastels… 거친 파스텔…
|
||||
Poster Edges 포스터 가장자리
|
||||
Rough Pastels 거친 파스텔
|
||||
Underpainting… 언더페인팅…
|
||||
Underpainting 언더페인팅
|
||||
Levels 레벨 수
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5198,6 +5198,7 @@ swatch Bright Violet Felviolet
|
||||
Neon Glow… Neongloed…
|
||||
Palette Knife… Paletmes…
|
||||
Poster Edges… Posterranden…
|
||||
Rough Pastels… Ruwe pastels…
|
||||
Cutout Knipsel
|
||||
Dry Brush Droog penseel
|
||||
Neon Glow Neongloed
|
||||
@@ -5205,6 +5206,7 @@ swatch Bright Violet Felviolet
|
||||
Paint Daubs Verfstipjes
|
||||
Palette Knife Paletmes
|
||||
Poster Edges Posterranden
|
||||
Rough Pastels Ruwe pastels
|
||||
Underpainting… Onderlaag…
|
||||
Underpainting Onderlaag
|
||||
Apply Data Set Gegevensset toepassen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4900,7 +4900,9 @@ imageTrace Outline Kontur
|
||||
Paint Daubs Plamy farby
|
||||
Palette Knife Szpachel
|
||||
Poster Edges… Krawędzie plakatu…
|
||||
Rough Pastels… Suche pastele…
|
||||
Poster Edges Krawędzie plakatu
|
||||
Rough Pastels Suche pastele
|
||||
Underpainting… Podmalówka…
|
||||
Underpainting Podmalówka
|
||||
Levels Poziomy
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4050,7 +4050,9 @@ axis Both Ambos
|
||||
Paint Daubs Manchas de tinta
|
||||
Palette Knife Espátula
|
||||
Poster Edges… Bordas de pôster…
|
||||
Rough Pastels… Pastéis ásperos…
|
||||
Poster Edges Bordas de pôster
|
||||
Rough Pastels Pastéis ásperos
|
||||
Underpainting… Subpintura…
|
||||
Underpainting Subpintura
|
||||
Levels Níveis
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4693,7 +4693,9 @@ lighting Light Свет
|
||||
Paint Daubs Мазки кисти
|
||||
Palette Knife Нож для палитры
|
||||
Poster Edges… Края плаката…
|
||||
Rough Pastels… Грубые пастели…
|
||||
Poster Edges Края плаката
|
||||
Rough Pastels Грубые пастели
|
||||
Underpainting… Подмалёвка…
|
||||
Underpainting Подмалёвка
|
||||
Levels Уровни
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4574,7 +4574,9 @@ lighting Light Ljus
|
||||
Paint Daubs Färgklickar
|
||||
Palette Knife Palettkniv
|
||||
Poster Edges… Affischkanter…
|
||||
Rough Pastels… Grova pasteller…
|
||||
Poster Edges Affischkanter
|
||||
Rough Pastels Grova pasteller
|
||||
Underpainting… Undermålning…
|
||||
Underpainting Undermålning
|
||||
Levels Nivåer
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4677,7 +4677,9 @@ lighting Light Світло
|
||||
Paint Daubs Мазки фарби
|
||||
Palette Knife Ніж палітри
|
||||
Poster Edges… Плакатні краї…
|
||||
Rough Pastels… Грубі пастелі…
|
||||
Poster Edges Плакатні краї
|
||||
Rough Pastels Грубі пастелі
|
||||
Underpainting… Підмалювання…
|
||||
Underpainting Підмалювання
|
||||
Levels Рівні
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 733 and column 40.
|
@@ -1279,7 +1279,9 @@
|
||||
Paint Daubs Vệt sơn
|
||||
Palette Knife Dao palette
|
||||
Poster Edges… Viền áp phích…
|
||||
Rough Pastels… Pastel thô…
|
||||
Poster Edges Viền áp phích
|
||||
Rough Pastels Pastel thô
|
||||
Underpainting… Lớp sơn nền…
|
||||
Underpainting Lớp sơn nền
|
||||
Levels Số mức
|
||||
|
||||
|
@@ -4961,7 +4961,9 @@ lighting Light 光源
|
||||
Paint Daubs 绘画涂抹
|
||||
Palette Knife 调色刀
|
||||
Poster Edges… 海报边缘…
|
||||
Rough Pastels… 粗糙蜡笔…
|
||||
Poster Edges 海报边缘
|
||||
Rough Pastels 粗糙蜡笔
|
||||
Underpainting… 底纹效果…
|
||||
Underpainting 底纹效果
|
||||
Levels 色阶数
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4767,7 +4767,9 @@ lighting Light 光源
|
||||
Paint Daubs 繪畫塗抹
|
||||
Palette Knife 調色刀
|
||||
Poster Edges… 海報邊緣…
|
||||
Rough Pastels… 粗糙粉彩…
|
||||
Poster Edges 海報邊緣
|
||||
Rough Pastels 粗糙粉彩
|
||||
Underpainting… 底紋效果…
|
||||
Underpainting 底紋效果
|
||||
Levels 色階數
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -97,6 +97,7 @@ fn effect_menu_lists_the_artistic_filters_before_blur() {
|
||||
"Palette Knife…",
|
||||
"Plastic Wrap…",
|
||||
"Poster Edges…",
|
||||
"Rough Pastels…",
|
||||
"Smudge Stick…",
|
||||
"Sponge…",
|
||||
"Underpainting…",
|
||||
|
||||
Reference in New Issue
Block a user