Skip to main content

Image

Struct Image 

Source
pub struct Image<'a> { /* private fields */ }
Expand description

Fixed size image widget that uses Protocol.

The widget does not react to area resizes. Its advantage lies in that the Protocol needs only one initial resize.

The image won’t render if it doesn’t fit, unless Image::allow_clipping has been set.

// let picker = Picker::from_query_studio()?;
let image = image::ImageReader::open("./assets/NixOS.png")?.decode()?;
let proto = picker.new_protocol(image, Size::new(20, 10), Resize::Fit(None))?;

terminal.draw(|f| {
    f.render_widget(Image::new(&proto), f.area());
});

Implementations§

Source§

impl<'a> Image<'a>

Source

pub fn new(image: &'a Protocol) -> Self

Examples found in repository?
examples/demo/main.rs (line 363)
318fn ui(f: &mut Frame<'_>, app: &mut App) {
319    let outer_block = Block::default()
320        .borders(Borders::TOP)
321        .title(app.title.as_str());
322
323    let chunks = Layout::default()
324        .direction(Direction::Horizontal)
325        .constraints([
326            Constraint::Percentage(app.split_percent),
327            Constraint::Percentage(100 - app.split_percent),
328        ])
329        .split(outer_block.inner(f.area()));
330    f.render_widget(outer_block, f.area());
331
332    let left_chunks = vertical_layout().split(chunks[0]);
333    let right_chunks = vertical_layout().split(chunks[1]);
334
335    let chunks_left_top = Layout::default()
336        .direction(Direction::Horizontal)
337        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
338        .split(left_chunks[0]);
339
340    let block_left_top = block("Fixed");
341    let area = block_left_top.inner(chunks_left_top[0]);
342    f.render_widget(
343        paragraph(app.background.as_str()).style(Color::Yellow),
344        area,
345    );
346    f.render_widget(block_left_top, chunks_left_top[0]);
347    if app.show_images != ShowImages::Resized {
348        // Let it be surrounded by styled text.
349        let area = Rect {
350            x: area.x + 1,
351            y: area.y + 1,
352            width: area.width.saturating_sub(2),
353            height: area.height.saturating_sub(2),
354        };
355
356        if let Some(placeholder_area) = app.image_static.needs_placeholder(area) {
357            let placeholder = Block::bordered()
358                .border_type(BorderType::QuadrantOutside)
359                .bg(Color::DarkGray);
360            f.render_widget(Clear {}, placeholder.inner(placeholder_area));
361            f.render_widget(placeholder, placeholder_area);
362        } else {
363            let image = Image::new(&app.image_static).allow_clipping(true);
364            f.render_widget(image, area);
365        }
366    }
367
368    let block_middle_top = block("Sliced");
369    let area = block_middle_top.inner(chunks_left_top[1]);
370    app.image_sliced_viewport = Some(area.into());
371    f.render_widget(
372        paragraph(app.background.as_str()).style(Color::LightBlue),
373        area,
374    );
375    f.render_widget(block_middle_top, chunks_left_top[1]);
376    if app.show_images != ShowImages::Resized {
377        let (pos, _, _) = app.image_sliced_position;
378        let image = SlicedImage::new(&app.image_sliced, pos);
379        f.render_widget(image, area);
380    }
381
382    let chunks_left_bottom = Layout::default()
383        .direction(Direction::Horizontal)
384        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
385        .split(left_chunks[1]);
386
387    app.render_resized_image(f, Resize::Crop(None), chunks_left_bottom[0]);
388    app.render_resized_image(f, Resize::Scale(None), chunks_left_bottom[1]);
389    app.render_resized_image(f, Resize::Fit(None), right_chunks[0]);
390
391    let block_right_bottom = block("Help");
392    let area = block_right_bottom.inner(right_chunks[1]);
393    f.render_widget(
394        paragraph(vec![
395            Line::from(format!(
396                "Font size: {}×{}",
397                app.picker.font_size().width,
398                app.picker.font_size().height
399            )),
400            Line::from(format!("Protocol: {:?}", app.picker.protocol_type())),
401            Line::from("Key bindings:"),
402            Line::from(vec![
403                Span::from("H").green(),
404                Span::from("/"),
405                Span::from("L").green(),
406                Span::from(": resize panes"),
407            ]),
408            Line::from(vec![Span::from("o").green(), Span::from(": cycle image")]),
409            Line::from(vec![
410                Span::from("t").green(),
411                Span::from(format!(": toggle ({:?})", app.show_images)),
412            ]),
413            Line::from(vec![
414                Span::from("h").green(),
415                Span::from("/"),
416                Span::from("j").green(),
417                Span::from("/"),
418                Span::from("k").green(),
419                Span::from("/"),
420                Span::from("l").green(),
421                Span::from(": move"),
422            ]),
423            Line::from(vec![
424                Span::from("a").green(),
425                Span::from(": toggle animation"),
426            ]),
427        ]),
428        area,
429    );
430    f.render_widget(block_right_bottom, right_chunks[1]);
431}
Source

pub fn allow_clipping(self, allow: bool) -> Self

Allow clipping the image if the render area is smaller than the image, and if the protocol supports it (protocol::kitty and protocol::halfblocks).

This is disabled by default to make the behavior consistent.

See also protocol::Protocol::needs_placeholder, which is an excellent complement if you need to render something when the image couldn’t.

terminal.draw(|f| {
    if let Some(placeholder_area) = proto.needs_placeholder(f.area()) {
        // Render `Box` or something with placeholder_area.
    } else {
        f.render_widget(Image::new(&proto).allow_clipping(true), f.area());
    }
});
Examples found in repository?
examples/demo/main.rs (line 363)
318fn ui(f: &mut Frame<'_>, app: &mut App) {
319    let outer_block = Block::default()
320        .borders(Borders::TOP)
321        .title(app.title.as_str());
322
323    let chunks = Layout::default()
324        .direction(Direction::Horizontal)
325        .constraints([
326            Constraint::Percentage(app.split_percent),
327            Constraint::Percentage(100 - app.split_percent),
328        ])
329        .split(outer_block.inner(f.area()));
330    f.render_widget(outer_block, f.area());
331
332    let left_chunks = vertical_layout().split(chunks[0]);
333    let right_chunks = vertical_layout().split(chunks[1]);
334
335    let chunks_left_top = Layout::default()
336        .direction(Direction::Horizontal)
337        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
338        .split(left_chunks[0]);
339
340    let block_left_top = block("Fixed");
341    let area = block_left_top.inner(chunks_left_top[0]);
342    f.render_widget(
343        paragraph(app.background.as_str()).style(Color::Yellow),
344        area,
345    );
346    f.render_widget(block_left_top, chunks_left_top[0]);
347    if app.show_images != ShowImages::Resized {
348        // Let it be surrounded by styled text.
349        let area = Rect {
350            x: area.x + 1,
351            y: area.y + 1,
352            width: area.width.saturating_sub(2),
353            height: area.height.saturating_sub(2),
354        };
355
356        if let Some(placeholder_area) = app.image_static.needs_placeholder(area) {
357            let placeholder = Block::bordered()
358                .border_type(BorderType::QuadrantOutside)
359                .bg(Color::DarkGray);
360            f.render_widget(Clear {}, placeholder.inner(placeholder_area));
361            f.render_widget(placeholder, placeholder_area);
362        } else {
363            let image = Image::new(&app.image_static).allow_clipping(true);
364            f.render_widget(image, area);
365        }
366    }
367
368    let block_middle_top = block("Sliced");
369    let area = block_middle_top.inner(chunks_left_top[1]);
370    app.image_sliced_viewport = Some(area.into());
371    f.render_widget(
372        paragraph(app.background.as_str()).style(Color::LightBlue),
373        area,
374    );
375    f.render_widget(block_middle_top, chunks_left_top[1]);
376    if app.show_images != ShowImages::Resized {
377        let (pos, _, _) = app.image_sliced_position;
378        let image = SlicedImage::new(&app.image_sliced, pos);
379        f.render_widget(image, area);
380    }
381
382    let chunks_left_bottom = Layout::default()
383        .direction(Direction::Horizontal)
384        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
385        .split(left_chunks[1]);
386
387    app.render_resized_image(f, Resize::Crop(None), chunks_left_bottom[0]);
388    app.render_resized_image(f, Resize::Scale(None), chunks_left_bottom[1]);
389    app.render_resized_image(f, Resize::Fit(None), right_chunks[0]);
390
391    let block_right_bottom = block("Help");
392    let area = block_right_bottom.inner(right_chunks[1]);
393    f.render_widget(
394        paragraph(vec![
395            Line::from(format!(
396                "Font size: {}×{}",
397                app.picker.font_size().width,
398                app.picker.font_size().height
399            )),
400            Line::from(format!("Protocol: {:?}", app.picker.protocol_type())),
401            Line::from("Key bindings:"),
402            Line::from(vec![
403                Span::from("H").green(),
404                Span::from("/"),
405                Span::from("L").green(),
406                Span::from(": resize panes"),
407            ]),
408            Line::from(vec![Span::from("o").green(), Span::from(": cycle image")]),
409            Line::from(vec![
410                Span::from("t").green(),
411                Span::from(format!(": toggle ({:?})", app.show_images)),
412            ]),
413            Line::from(vec![
414                Span::from("h").green(),
415                Span::from("/"),
416                Span::from("j").green(),
417                Span::from("/"),
418                Span::from("k").green(),
419                Span::from("/"),
420                Span::from("l").green(),
421                Span::from(": move"),
422            ]),
423            Line::from(vec![
424                Span::from("a").green(),
425                Span::from(": toggle animation"),
426            ]),
427        ]),
428        area,
429    );
430    f.render_widget(block_right_bottom, right_chunks[1]);
431}

Trait Implementations§

Source§

impl Widget for Image<'_>

Source§

fn render(self, area: Rect, buf: &mut Buffer)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom widget.

Auto Trait Implementations§

§

impl<'a> Freeze for Image<'a>

§

impl<'a> RefUnwindSafe for Image<'a>

§

impl<'a> Send for Image<'a>

§

impl<'a> Sync for Image<'a>

§

impl<'a> Unpin for Image<'a>

§

impl<'a> UnsafeUnpin for Image<'a>

§

impl<'a> UnwindSafe for Image<'a>

Blanket Implementations§

Source§

impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
where T: Real + Zero + Arithmetics + Clone, Swp: WhitePoint<T>, Dwp: WhitePoint<T>, D: AdaptFrom<S, Swp, Dwp, T>,

Source§

fn adapt_into_using<M>(self, method: M) -> D
where M: TransformMatrix<T>,

Convert the source color to the destination color using the specified method.
Source§

fn adapt_into(self) -> D

Convert the source color to the destination color using the bradford method by default.
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, C> ArraysFrom<C> for T
where C: IntoArrays<T>,

Source§

fn arrays_from(colors: C) -> T

Cast a collection of colors into a collection of arrays.
Source§

impl<T, C> ArraysInto<C> for T
where C: FromArrays<T>,

Source§

fn arrays_into(self) -> C

Cast this collection of arrays into a collection of colors.
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<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for U
where T: FromCam16Unclamped<WpParam, U>,

Source§

type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, C> ComponentsFrom<C> for T
where C: IntoComponents<T>,

Source§

fn components_from(colors: C) -> T

Cast a collection of colors into a collection of color components.
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromAngle<T> for T

Source§

fn from_angle(angle: T) -> T

Performs a conversion from angle.
Source§

impl<T, U> FromStimulus<U> for T
where U: IntoStimulus<T>,

Source§

fn from_stimulus(other: U) -> T

Converts other into Self, while performing the appropriate scaling, rounding and clamping.
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, U> IntoAngle<U> for T
where U: FromAngle<T>,

Source§

fn into_angle(self) -> U

Performs a conversion into T.
Source§

impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for U
where T: Cam16FromUnclamped<WpParam, U>,

Source§

type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, U> IntoColor<U> for T
where U: FromColor<T>,

Source§

fn into_color(self) -> U

Convert into T with values clamped to the color defined bounds Read more
Source§

impl<T, U> IntoColorUnclamped<U> for T
where U: FromColorUnclamped<T>,

Source§

fn into_color_unclamped(self) -> U

Convert into T. The resulting color might be invalid in its color space Read more
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoStimulus<T> for T

Source§

fn into_stimulus(self) -> T

Converts self into T, while performing the appropriate scaling, rounding and clamping.
Source§

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

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T, C> TryComponentsInto<C> for T
where C: TryFromComponents<T>,

Source§

type Error = <C as TryFromComponents<T>>::Error

The error for when try_into_colors fails to cast.
Source§

fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>

Try to cast this collection of color components into a collection of colors. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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, U> TryIntoColor<U> for T
where U: TryFromColor<T>,

Source§

fn try_into_color(self) -> Result<U, OutOfBounds<U>>

Convert into T, returning ok if the color is inside of its defined range, otherwise an OutOfBounds error is returned which contains the unclamped color. Read more
Source§

impl<C, U> UintsFrom<C> for U
where C: IntoUints<U>,

Source§

fn uints_from(colors: C) -> U

Cast a collection of colors into a collection of unsigned integers.
Source§

impl<C, U> UintsInto<C> for U
where C: FromUints<U>,

Source§

fn uints_into(self) -> C

Cast this collection of unsigned integers into a collection of colors.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V