1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Temporary until https://github.com/rust-lang/rust-clippy/issues/15151 is rolled out
//! Library to display images in the terminal.
//!
//! This library contains functionality extracted from the [`viu`](https://github.com/atanunq/viu) crate.
//! It aims to provide an easy to use interface to print images in the terminal. Uses some abstractions
//! provided by the [`image`] crate. [Kitty](https://sw.kovidgoyal.net/kitty/graphics-protocol.html)
//! and [iTerm](https://iterm2.com/documentation-images.html) graphic protocols are supported and used by default,
//! if detected. If not, `viuer` will fallback to using regular half blocks instead (▄ and ▀).
//!
//! ## Basic Usage
//! The default features of this crate can only work with [image::DynamicImage]. The below example
//! creates a 60x60 gradient and prints it. More options are available through the [Config] struct.
//! ```
//! use image::{DynamicImage, Pixel, Rgba, RgbaImage};
//!
//! let conf = viuer::Config {
//! absolute_offset: false,
//! ..Default::default()
//! };
//!
//! let mut img = DynamicImage::ImageRgba8(RgbaImage::new(60, 60));
//! let start = Rgba::from_slice(&[0, 196, 0, 255]);
//! let end = Rgba::from_slice(&[255, 255, 255, 255]);
//! image::imageops::horizontal_gradient(&mut img, start, end);
//!
//! viuer::print(&img, &conf).unwrap();
//! ```
//!
//! ## Decoding files
//! To work directly with files, the non-default `print-file` feature must be enabled.
//!
//! The example below shows how to print the image `img.jpg` in 40x30 terminal cells, with vertical
//! offset of 4 and horizontal of 10, starting from the top left corner.
//! ```no_run
//! let conf = viuer::Config {
//! width: Some(40),
//! height: Some(30),
//! x: 10,
//! y: 4,
//! ..Default::default()
//! };
//!
//! #[cfg(feature="print-file")]
//! viuer::print_from_file("img.jpg", &conf).expect("Image printing failed.");
//! ```
use Path;
use Term;
use ;
use DynamicImage;
use ;
pub use Config;
pub use ;
pub use ;
pub use terminal_size;
pub use is_sixel_supported;
/// Default printing method. Uses either iTerm or Kitty graphics protocol, if supported,
/// and half blocks otherwise.
///
/// Check the [Config] struct for all customization options.
/// ## Example
/// The snippet below reads all of stdin, decodes it with the [`image`] crate
/// and prints it to the terminal. The image will also be resized to fit in the terminal.
///
/// ```no_run
/// use std::io::{stdin, Read};
/// use viuer::{Config, print};
///
/// let stdin = stdin();
/// let mut handle = stdin.lock();
///
/// let mut buf: Vec<u8> = Vec::new();
/// let _ = handle
/// .read_to_end(&mut buf)
/// .expect("Could not read until EOF.");
///
/// let img = image::load_from_memory(&buf).expect("Data from stdin could not be decoded.");
/// print(&img, &Config::default()).expect("Image printing failed.");
/// ```
/// Helper method that reads a file, tries to decode and print it. The feature is available only
/// with the `print-file` feature.
///
/// ## Example
/// ```no_run
/// use viuer::{Config, print_from_file};
/// let conf = Config {
/// width: Some(30),
/// transparent: true,
/// ..Default::default()
/// };
/// // Image will be scaled down to width 30. Aspect ratio will be preserved.
/// // Also, the terminal's background color will be used instead of checkerboard pattern.
/// print_from_file("img.jpg", &conf).expect("Image printing failed.");
/// ```
// Choose the appropriate printer to use based on user config and availability