Skip to main content

ImageFilter

Enum ImageFilter 

Source
pub enum ImageFilter {
    None,
    Blur {
        sigma_x: f32,
        sigma_y: f32,
    },
    Matrix {
        transform: Transform2D,
    },
    Dilate {
        radius_x: f32,
        radius_y: f32,
    },
    Erode {
        radius_x: f32,
        radius_y: f32,
    },
    Color(ColorFilter),
    Runtime {
        program: u32,
        uniforms: Vec<f32>,
    },
    Compose {
        outer: Box<ImageFilter>,
        inner: Box<ImageFilter>,
    },
}
Expand description

A function applied to what a paint drew, rather than to the color it computed.

The distinction from a color filter is what the input is. A color filter sees one color at a time and cannot know its neighbors; this sees the picture, which is what a blur needs.

The distinction from Paint::mask_blur is what is blurred. A mask blur blurs coverage and then fills, which is only the same picture as blurring the result when the fill does not vary – so it takes a solid color and refuses anything else. This blurs the result, which is defined for every paint and is what dart:ui means by an image filter. For a solid color the two agree, and there is a test that says so.

Variants§

§

None

§

Blur

Blur what was drawn, by a standard deviation per axis in device pixels.

Two, because dart:ui’s ImageFilter.blur takes sigmaX and sigmaY separately and upstream’s MakeBlur passes both through. A blur is two separable passes here already, one along each axis, so the second deviation costs nothing but the field: each pass uses its own, and a pass whose deviation is zero is skipped rather than run as an identity that would resample for no reason.

Self::blur is the isotropic case, which is nearly every use.

Fields

§sigma_x: f32
§sigma_y: f32
§

Matrix

Move what was drawn, in device pixels, by resampling it.

Not the same as drawing under the transform, which is what the canvas’s own stack does. This draws at the size it was written and then moves the finished image, so magnifying gives enlarged pixels where the transform stack would give the shape redrawn larger. That difference is the reason dart:ui has both, and a caller wanting the sharp one already has concat.

Fields

§transform: Transform2D
§

Dilate

Spread what was drawn, taking the largest sample within these radii in device pixels.

ImageFilter.dilate. On premultiplied color and channel by channel, so a translucent shape spreads its coverage along with its color.

Fields

§radius_x: f32
§radius_y: f32
§

Erode

Shrink what was drawn, taking the smallest sample within these radii in device pixels.

ImageFilter.erode, and the dual of Self::Dilate: what one does to a shape the other does to the space around it.

Fields

§radius_x: f32
§radius_y: f32
§

Color(ColorFilter)

Recolor what was drawn, rather than what the paint computed.

dart:ui’s ColorFilter is itself an ImageFilter, and upstream’s DlImageFilter::MakeColorFilter is the same thing. A paint carries a color filter of its own, so the obvious question is what this adds, and the answer is narrower than it first looks: it can be half of a Self::Compose, and Paint::color_filter cannot. Recoloring a blurred result, or blurring a recolored one, has no other spelling here.

On a single draw with a solid fill it is the same picture as the paint’s own filter, and a test pins that rather than leaving it to be discovered. A paint’s image filter applies per draw – each draw gets a layer of its own – so there is no arrangement of two draws under one paint for the two to disagree about. Where they would disagree is inside a composition, which is the case this exists for.

§

Runtime

Run a caller’s fragment program over what was drawn.

dart:ui’s ImageFilter.shader, and upstream’s DlImageFilter::MakeRuntimeEffect. The program reads its input as a texture with an identity transform – the same guarantee upstream re-rasterizes to provide, and one this renderer has by construction: a filter is a pass whose target is the size of its source, covered by a quad, so a fragment’s clip position is its texture coordinate. A program written for this samples exactly as the fixture programs do.

The uniforms are the whole material block, because a program replaces the shader that would have read it. RUNTIME_FLOATS is the bound and anything past it is dropped, as it is for a runtime effect used as a paint.

Fields

§program: u32
§uniforms: Vec<f32>
§

Compose

Filter with inner, then filter that result with outer.

ImageFilter.compose, and the reason this type is not Copy: a filter that holds filters cannot be a fixed size without a bound on the depth, and dart:ui puts no bound on it.

A caller can already nest Canvas::save_layer calls to the same effect, and did before this existed. What this adds is that the bounds come out right without being worked out by hand: the outer layer has to be opened wide enough to hold whatever the inner one grew to, which means knowing how far each filter in the chain reaches.

Fields

Implementations§

Source§

impl ImageFilter

Source

pub fn blur(sigma: f32) -> ImageFilter

A blur of the same deviation along both axes, which is nearly every use.

Source

pub fn blur_xy(sigma_x: f32, sigma_y: f32) -> ImageFilter

A blur with a deviation per axis, as dart:ui’s ImageFilter.blur states one.

Source

pub fn is_identity(&self) -> bool

Whether this would change anything.

Source

pub fn compose(outer: ImageFilter, inner: ImageFilter) -> ImageFilter

Filter with inner first and then with outer.

The order dart:ui states, which is the order the names suggest once you picture them nested: the inner filter is the one closer to what was drawn. A composition where either half does nothing is the other half, since the layer it would have taken is a copy of an image.

Trait Implementations§

Source§

impl Clone for ImageFilter

Source§

fn clone(&self) -> ImageFilter

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ImageFilter

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for ImageFilter

Source§

fn default() -> ImageFilter

Returns the “default value” for a type. Read more
Source§

impl PartialEq for ImageFilter

Source§

fn eq(&self, other: &ImageFilter) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for ImageFilter

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>