|
1 |
| -use re_types::components::{Blob, MediaType, VideoTimestamp}; |
2 |
| -use re_ui::{list_item::PropertyContent, UiExt}; |
| 1 | +use std::sync::Arc; |
| 2 | + |
| 3 | +use re_types::{ |
| 4 | + components::{Blob, MediaType, VideoTimestamp}, |
| 5 | + RowId, |
| 6 | +}; |
| 7 | +use re_ui::{ |
| 8 | + list_item::{self, PropertyContent}, |
| 9 | + UiExt, |
| 10 | +}; |
3 | 11 | use re_viewer_context::UiLayout;
|
4 | 12 |
|
5 | 13 | use crate::{
|
@@ -108,6 +116,10 @@ pub fn blob_preview_and_save_ui(
|
108 | 116 | let mut video_result_for_frame_preview = None;
|
109 | 117 |
|
110 | 118 | if let Some(blob_row_id) = blob_row_id {
|
| 119 | + if !ui_layout.is_single_line() && ui_layout != UiLayout::Tooltip { |
| 120 | + exif_ui(ui, blob_row_id, blob); |
| 121 | + } |
| 122 | + |
111 | 123 | // Try to treat it as an image:
|
112 | 124 | image = ctx
|
113 | 125 | .store_context
|
@@ -197,3 +209,40 @@ pub fn blob_preview_and_save_ui(
|
197 | 209 | }
|
198 | 210 | }
|
199 | 211 | }
|
| 212 | + |
| 213 | +/// Show EXIF data about the given blob (image), if possible. |
| 214 | +fn exif_ui(ui: &mut egui::Ui, blob_row_id: RowId, blob: &re_types::datatypes::Blob) { |
| 215 | + let exif_result = ui.ctx().memory_mut(|mem| { |
| 216 | + // Cache EXIF parsing to avoid re-parsing every frame. |
| 217 | + // The parsing is really fast, so this is not really needed. |
| 218 | + let key = blob_row_id; |
| 219 | + let cache = mem |
| 220 | + .caches |
| 221 | + .cache::<egui::cache::FramePublisher<RowId, Arc<rexif::ExifResult>>>(); |
| 222 | + cache.get(&key).cloned().unwrap_or_else(|| { |
| 223 | + re_tracing::profile_scope!("exif-parse"); |
| 224 | + let (result, _warnings) = rexif::parse_buffer_quiet(blob); |
| 225 | + let result = Arc::new(result); |
| 226 | + cache.set(key, result.clone()); |
| 227 | + result |
| 228 | + }) |
| 229 | + }); |
| 230 | + |
| 231 | + if let Ok(exif) = &*exif_result { |
| 232 | + ui.list_item_collapsible_noninteractive_label("EXIF", false, |ui| { |
| 233 | + list_item::list_item_scope(ui, "exif", |ui| { |
| 234 | + for entry in &exif.entries { |
| 235 | + let tag_string = if entry.tag == rexif::ExifTag::UnknownToMe { |
| 236 | + "<Unknown tag>".to_owned() |
| 237 | + } else { |
| 238 | + entry.tag.to_string() |
| 239 | + }; |
| 240 | + ui.list_item_flat_noninteractive( |
| 241 | + list_item::PropertyContent::new(tag_string) |
| 242 | + .value_text(entry.value_more_readable.to_string()), |
| 243 | + ); |
| 244 | + } |
| 245 | + }); |
| 246 | + }); |
| 247 | + } |
| 248 | +} |
0 commit comments