runmat_plot/export/
image.rs1use std::path::Path;
6use wgpu::{Device, Queue, TextureFormat};
7
8pub struct ImageExporter {
10 #[allow(dead_code)]
12 device: Device,
13 #[allow(dead_code)]
15 queue: Queue,
16 #[allow(dead_code)]
18 format: TextureFormat,
19 settings: ImageExportSettings,
21}
22
23#[derive(Debug, Clone)]
25pub struct ImageExportSettings {
26 pub width: u32,
28 pub height: u32,
30 pub samples: u32,
32 pub background_color: [f32; 4],
34 pub quality: f32,
36 pub include_metadata: bool,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq)]
42pub enum ImageFormat {
43 Png,
44 Jpeg,
45 WebP,
46 Bmp,
47}
48
49impl Default for ImageExportSettings {
50 fn default() -> Self {
51 Self {
52 width: 800,
53 height: 600,
54 samples: 4, background_color: [1.0, 1.0, 1.0, 1.0], quality: 0.95,
57 include_metadata: true,
58 }
59 }
60}
61
62impl ImageExporter {
63 pub async fn new() -> Result<Self, String> {
65 Self::with_settings(ImageExportSettings::default()).await
66 }
67
68 pub async fn with_settings(settings: ImageExportSettings) -> Result<Self, String> {
70 let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
72
73 let adapter = instance
74 .request_adapter(&wgpu::RequestAdapterOptions {
75 power_preference: wgpu::PowerPreference::HighPerformance,
76 compatible_surface: None,
77 force_fallback_adapter: false,
78 })
79 .await
80 .ok_or("Failed to find suitable GPU adapter")?;
81
82 let (device, queue) = adapter
83 .request_device(&wgpu::DeviceDescriptor::default(), None)
84 .await
85 .map_err(|e| format!("Failed to create device: {e}"))?;
86
87 Ok(Self {
88 device,
89 queue,
90 format: TextureFormat::Rgba8UnormSrgb,
91 settings,
92 })
93 }
94
95 pub async fn export_png<P: AsRef<Path>>(
97 &self,
98 _figure: &mut crate::plots::Figure,
99 path: P,
100 ) -> Result<(), String> {
101 let placeholder_data =
103 vec![255u8; (self.settings.width * self.settings.height * 4) as usize];
104 self.save_png(&placeholder_data, path).await
105 }
106
107 async fn save_png<P: AsRef<Path>>(&self, data: &[u8], path: P) -> Result<(), String> {
109 use image::{ImageBuffer, Rgba};
110
111 let image =
112 ImageBuffer::<Rgba<u8>, _>::from_raw(self.settings.width, self.settings.height, data)
113 .ok_or("Failed to create image buffer")?;
114
115 image
116 .save(path)
117 .map_err(|e| format!("Failed to save PNG: {e}"))?;
118
119 println!("DEBUG: PNG export completed successfully");
120 Ok(())
121 }
122
123 pub fn set_settings(&mut self, settings: ImageExportSettings) {
125 self.settings = settings;
126 }
127
128 pub fn settings(&self) -> &ImageExportSettings {
130 &self.settings
131 }
132}