BioCore  5.0.0
A Windows .NET microscopy library and application for viewing, editing, and annotating images.
Loading...
Searching...
No Matches
TabsView.Zarr.cs
Go to the documentation of this file.
1using AForge;
2using BioLib;
3using ZarrNET.Core.OmeZarr.Metadata;
4using Point = System.Drawing.Point;
5using Size = System.Drawing.Size;
6
7namespace BioCore
8{
9 public partial class TabsView
10 {
11 private void InitializeZarrMenu()
12 {
13 var menu = new ToolStripMenuItem("Open OME-Zarr");
14 menu.DropDownItems.Add("Local folder...", null, async (_, _) =>
15 {
16 using var dialog = new FolderBrowserDialog
17 {
18 Description = "Select an OME-Zarr folder",
19 UseDescriptionForTitle = true,
20 ShowNewFolderButton = false
21 };
22 if (dialog.ShowDialog(this) == DialogResult.OK)
23 await OpenZarrSourceAsync(dialog.SelectedPath);
24 });
25 menu.DropDownItems.Add("Remote URL...", null, async (_, _) =>
26 {
27 using var dialog = new Form
28 {
29 Text = "Open OME-Zarr URL",
30 StartPosition = FormStartPosition.CenterParent,
31 FormBorderStyle = FormBorderStyle.FixedDialog,
32 MinimizeBox = false,
33 MaximizeBox = false,
34 ClientSize = new Size(520, 100)
35 };
36 var label = new Label { Text = "HTTPS or S3 URL:", AutoSize = true, Location = new Point(12, 12) };
37 var input = new TextBox { Location = new Point(12, 32), Width = 496 };
38 var ok = new Button { Text = "Open", DialogResult = DialogResult.OK, Location = new Point(352, 65) };
39 var cancel = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, Location = new Point(433, 65) };
40 dialog.Controls.AddRange(new Control[] { label, input, ok, cancel });
41 dialog.AcceptButton = ok;
42 dialog.CancelButton = cancel;
43 if (dialog.ShowDialog(this) == DialogResult.OK)
44 {
45 string url = input.Text.Trim();
46 if (!url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) &&
47 !url.StartsWith("s3://", StringComparison.OrdinalIgnoreCase))
48 {
49 MessageBox.Show(this, "Enter an HTTPS or S3 URL.", "Open OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Warning);
50 return;
51 }
52 await OpenZarrSourceAsync(url);
53 }
54 });
55 fileToolStripMenuItem.DropDownItems.Insert(1, menu);
56 var saveMenu = new ToolStripMenuItem("Save OME-Zarr...");
57 saveMenu.Click += async (_, _) => await SaveZarrAsync();
58 fileToolStripMenuItem.DropDownItems.Insert(fileToolStripMenuItem.DropDownItems.IndexOf(saveToolStripMenuItem) + 1, saveMenu);
59 }
60
61 private static bool IsZarrSource(string source) =>
62 source.Contains(".zarr", StringComparison.OrdinalIgnoreCase) ||
63 source.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ||
64 source.StartsWith("s3://", StringComparison.OrdinalIgnoreCase);
65
66 private async Task OpenZarrSourceAsync(string source)
67 {
68 try
69 {
70 if (source.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
71 source = "https://" + source.Substring(8);
72 else if (source.StartsWith("s3://", StringComparison.OrdinalIgnoreCase))
73 source = "s3://" + source.Substring(5);
74 if (!source.StartsWith("https://", StringComparison.OrdinalIgnoreCase) &&
75 !source.StartsWith("s3://", StringComparison.OrdinalIgnoreCase) &&
76 !source.Contains(".zarr", StringComparison.Ordinal))
77 throw new ArgumentException("The folder path must contain .zarr for the current BioLib reader.");
78
79 UseWaitCursor = true;
80 BioImage image = await BioImage.OpenURL(source, new ZCT(0, 0, 0), 0, 0, 800, 600);
81 if (Directory.Exists(source))
82 image.Annotations.AddRange(Zarr.LoadROIs(source));
83 // A scene is a relationship between child volumes rather than a
84 // single plane. When it has no declared display Z, start near the
85 // centre instead of on an often-empty boundary slice.
86 if (image.zarrReader?.RootNodeType == OmeAttributesParser.OmeNodeType.Scene &&
87 image.SizeZ > 1)
88 {
89 int middleZ = image.SizeZ / 2;
90 image.Coordinate = new ZCT(middleZ, image.Coordinate.C, image.Coordinate.T);
91 }
92 AddTab(image);
93 // Avoid persisting potentially sensitive signed URL query parameters.
94 bool hasCredentials = Uri.TryCreate(source, UriKind.Absolute, out var uri) &&
95 !string.IsNullOrEmpty(uri.UserInfo);
96 if (!source.Contains('?') && !hasCredentials && !App.recent.Contains(source))
97 App.recent.Add(source);
98 SaveProperties();
99 }
100 catch (Exception ex)
101 {
102 MessageBox.Show(this, $"Could not open OME-Zarr: {ex.Message}", "Open OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Error);
103 }
104 finally
105 {
106 UseWaitCursor = false;
107 }
108 }
109
110 private async Task SaveZarrAsync()
111 {
112 BioImage image = Image;
113 if (image == null)
114 {
115 MessageBox.Show(this, "Open an image first.", "Save OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Information);
116 return;
117 }
118 using var dialog = new SaveFileDialog
119 {
120 Title = "Save OME-Zarr folder",
121 Filter = "OME-Zarr folders (*.ome.zarr)|*.ome.zarr",
122 DefaultExt = "ome.zarr",
123 AddExtension = true,
124 OverwritePrompt = false,
125 FileName = Path.GetFileNameWithoutExtension(image.filename) + ".ome.zarr"
126 };
127 if (dialog.ShowDialog(this) != DialogResult.OK)
128 return;
129
130 try
131 {
132 Enabled = false;
133 UseWaitCursor = true;
134 await Task.Run(() => ZarrExporter.SaveAsync(image, dialog.FileName));
135 MessageBox.Show(this, "OME-Zarr saved successfully.", "Save OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Information);
136 }
137 catch (Exception ex)
138 {
139 MessageBox.Show(this, $"Could not save OME-Zarr: {ex.Message}", "Save OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Error);
140 }
141 finally
142 {
143 UseWaitCursor = false;
144 Enabled = true;
145 }
146 }
147 }
148}
System.Drawing.Size Size
System.Drawing.Point Point
static List< string > recent
Definition App.cs:20
BioImage Image
Definition TabsView.cs:331
void AddTab(BioImage b)
Definition TabsView.cs:96