Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ You can find its changes [documented below](#060---2020-06-01).

### Changed

- `Image` and `ImageData` exported by default. ([#1011] by [@covercash2])

### Deprecated

### Removed
Expand Down
78 changes: 52 additions & 26 deletions druid/src/widget/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
//! An Image widget.
//! Please consider using SVG and the SVG wideget as it scales much better.

use std::convert::AsRef;
use std::error::Error;
use std::path::Path;

use crate::{
piet::{ImageFormat, InterpolationMode},
widget::common::FillStrat,
Expand All @@ -27,6 +23,17 @@ use crate::{
};

/// A widget that renders an Image
///
/// `druid` does not support loading image data by default.
/// However, there is an optional dependency on the `image` crate
/// that makes loading simple. This feature can be enabled with cargo.
/// For example, in `Cargo.toml`:
/// ```no_compile
/// [dependencies.druid]
/// version = "0.6.0"
/// features = ["image"]
/// ```
///
pub struct Image {
image_data: ImageData,
fill: FillStrat,
Expand Down Expand Up @@ -108,6 +115,16 @@ impl<T: Data> Widget<T> for Image {
}

/// Stored Image data.
///
/// By default `druid` does not parse image metadata.
/// However, `druid` supports an optional dependency on the `image` crate,
/// which allows reading image metadata and some kinds of image data manipulation.
/// These features are enabled with "image" feature. For example, in `Cargo.toml`:
/// ```no_compile
/// [dependencies.druid]
/// version = "0.6.0"
/// features = ["image"]
/// ```
#[derive(Clone)]
pub struct ImageData {
pixels: Vec<u8>,
Expand All @@ -127,6 +144,35 @@ impl ImageData {
}
}

/// Get the size in pixels of the contained image.
fn get_size(&self) -> Size {
Size::new(self.x_pixels as f64, self.y_pixels as f64)
}

/// Convert ImageData into Piet draw instructions.
fn to_piet(&self, offset_matrix: Affine, ctx: &mut PaintCtx, interpolation: InterpolationMode) {
ctx.with_save(|ctx| {
ctx.transform(offset_matrix);
let size = self.get_size();
let im = ctx
.make_image(
size.width as usize,
size.height as usize,
&self.pixels,
self.format,
)
.unwrap();
ctx.draw_image(&im, size.to_rect(), interpolation);
})
}
}

#[cfg(feature = "image")]
use std::{convert::AsRef, error::Error, path::Path};

#[cfg(feature = "image")]
#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
impl ImageData {
/// Load an image from a DynamicImage from the image crate
pub fn from_dynamic_image(image_data: image::DynamicImage) -> ImageData {
if has_alpha_channel(&image_data) {
Expand Down Expand Up @@ -173,30 +219,10 @@ impl ImageData {
let image_data = image::open(path).map_err(|e| e)?;
Ok(ImageData::from_dynamic_image(image_data))
}

/// Get the size in pixels of the contained image.
fn get_size(&self) -> Size {
Size::new(self.x_pixels as f64, self.y_pixels as f64)
}

/// Convert ImageData into Piet draw instructions.
fn to_piet(&self, offset_matrix: Affine, ctx: &mut PaintCtx, interpolation: InterpolationMode) {
ctx.with_save(|ctx| {
ctx.transform(offset_matrix);
let size = self.get_size();
let im = ctx
.make_image(
size.width as usize,
size.height as usize,
&self.pixels,
self.format,
)
.unwrap();
ctx.draw_image(&im, size.to_rect(), interpolation);
})
}
}

#[cfg(feature = "image")]
#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
fn has_alpha_channel(image: &image::DynamicImage) -> bool {
use image::ColorType::*;
match image.color() {
Expand Down
4 changes: 0 additions & 4 deletions druid/src/widget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ mod either;
mod env_scope;
mod flex;
mod identity_wrapper;
#[cfg(feature = "image")]
#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
mod image;
mod invalidation;
mod label;
Expand All @@ -52,8 +50,6 @@ mod view_switcher;
mod widget;
mod widget_ext;

#[cfg(feature = "image")]
#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
pub use self::image::{Image, ImageData};
pub use align::Align;
pub use button::Button;
Expand Down