pnte/
image.rs

1use crate::*;
2use std::path::Path;
3use windows::Win32::{Foundation::GENERIC_READ, Graphics::Direct2D::*, Graphics::Imaging::*};
4use windows::core::{GUID, HSTRING, Interface};
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug)]
7#[repr(i32)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub enum Interpolation {
10    NearestNeighbor = D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR.0,
11    Linear = D2D1_INTERPOLATION_MODE_LINEAR.0,
12    Cubic = D2D1_INTERPOLATION_MODE_CUBIC.0,
13    MultiSampleLinear = D2D1_INTERPOLATION_MODE_DEFINITION_MULTI_SAMPLE_LINEAR.0,
14    Anisotropic = D2D1_INTERPOLATION_MODE_ANISOTROPIC.0,
15    HighQualityCubic = D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC.0,
16}
17
18impl From<Interpolation> for D2D1_INTERPOLATION_MODE {
19    fn from(value: Interpolation) -> Self {
20        Self(value as i32)
21    }
22}
23
24#[derive(Clone, PartialEq, Eq, Debug)]
25pub struct Image(ID2D1Bitmap1);
26
27impl Image {
28    pub fn from_file<T>(ctx: &Context<T>, path: impl AsRef<Path>) -> Result<Self>
29    where
30        T: Backend,
31    {
32        let factory = &ctx.wic_imaging_factory;
33        unsafe {
34            let decoder = factory.CreateDecoderFromFilename(
35                &HSTRING::from(path.as_ref().to_string_lossy().as_ref()),
36                Some(&GUID::zeroed()),
37                GENERIC_READ,
38                WICDecodeMetadataCacheOnDemand,
39            )?;
40            let frame = decoder.GetFrame(0)?;
41            let converter = factory.CreateFormatConverter()?;
42            converter.Initialize(
43                &frame,
44                &GUID_WICPixelFormat32bppPBGRA,
45                WICBitmapDitherTypeNone,
46                None,
47                1.0,
48                WICBitmapPaletteTypeMedianCut,
49            )?;
50            let bitmap = ctx
51                .d2d1_device_context
52                .CreateBitmapFromWicBitmap(&converter, None)?
53                .cast()?;
54            Ok(Self(bitmap))
55        }
56    }
57
58    #[inline]
59    pub fn size(&self) -> Size<f32> {
60        unsafe { self.0.GetSize().into() }
61    }
62
63    #[inline]
64    pub fn pixel_size(&self) -> Size<u32> {
65        unsafe { self.0.GetPixelSize().into() }
66    }
67
68    pub(crate) fn handle(&self) -> &ID2D1Bitmap1 {
69        &self.0
70    }
71}