11 private void InitializeZarrMenu()
13 var menu =
new ToolStripMenuItem(
"Open OME-Zarr");
14 menu.DropDownItems.Add(
"Local folder...",
null, async (_, _) =>
16 using var dialog =
new FolderBrowserDialog
18 Description =
"Select an OME-Zarr folder",
19 UseDescriptionForTitle =
true,
20 ShowNewFolderButton =
false
22 if (dialog.ShowDialog(
this) == DialogResult.OK)
23 await OpenZarrSourceAsync(dialog.SelectedPath);
25 menu.DropDownItems.Add(
"Remote URL...",
null, async (_, _) =>
27 using var dialog =
new Form
29 Text =
"Open OME-Zarr URL",
30 StartPosition = FormStartPosition.CenterParent,
31 FormBorderStyle = FormBorderStyle.FixedDialog,
34 ClientSize =
new Size(520, 100)
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)
45 string url = input.Text.Trim();
46 if (!url.StartsWith(
"https://", StringComparison.OrdinalIgnoreCase) &&
47 !url.StartsWith(
"s3://", StringComparison.OrdinalIgnoreCase))
49 MessageBox.Show(
this,
"Enter an HTTPS or S3 URL.",
"Open OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Warning);
52 await OpenZarrSourceAsync(url);
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);
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);
66 private async Task OpenZarrSourceAsync(
string source)
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.");
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));
86 if (image.zarrReader?.RootNodeType == OmeAttributesParser.OmeNodeType.Scene &&
89 int middleZ = image.SizeZ / 2;
90 image.Coordinate =
new ZCT(middleZ, image.Coordinate.C, image.Coordinate.T);
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))
102 MessageBox.Show(
this, $
"Could not open OME-Zarr: {ex.Message}",
"Open OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Error);
106 UseWaitCursor =
false;
110 private async Task SaveZarrAsync()
112 BioImage image =
Image;
115 MessageBox.Show(
this,
"Open an image first.",
"Save OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Information);
118 using var dialog =
new SaveFileDialog
120 Title =
"Save OME-Zarr folder",
121 Filter =
"OME-Zarr folders (*.ome.zarr)|*.ome.zarr",
122 DefaultExt =
"ome.zarr",
124 OverwritePrompt =
false,
125 FileName = Path.GetFileNameWithoutExtension(image.filename) +
".ome.zarr"
127 if (dialog.ShowDialog(
this) != DialogResult.OK)
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);
139 MessageBox.Show(
this, $
"Could not save OME-Zarr: {ex.Message}",
"Save OME-Zarr", MessageBoxButtons.OK, MessageBoxIcon.Error);
143 UseWaitCursor =
false;