-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a writer function to the napari-tiff plugin #12
Comments
@Czaki has an IJ tiff writer here: but has the following issues (Zulip discussion) in making it a real napari writer plugin:
But that code will be a good reference once we have the necessary metadata on layers. |
This issue has been mentioned on Image.sc Forum. There might be relevant details there: |
Relevant zulip discussion: https://napari.zulipchat.com/#narrow/stream/212875-general/topic/How.20do.20I.20save.20in.20the.20ImageJ.20TIFF-format David has come up with this solution, for preserving the image metadata (scales, etc.) import napari
import tifffile
from qtpy.QtWidgets import QFileDialog, QPushButton, QVBoxLayout, QWidget, QListWidget, QListWidgetItem
import numpy as np
class SaveLayerWidget(QWidget):
def __init__(self, viewer):
super().__init__()
self.viewer = viewer
# Layout and buttons
layout = QVBoxLayout()
self.layer_list = QListWidget()
self.layer_list.setSelectionMode(QListWidget.MultiSelection)
layout.addWidget(self.layer_list)
save_button = QPushButton('Save Selected Layers')
save_button.clicked.connect(self.save_selected_layers)
layout.addWidget(save_button)
self.setLayout(layout)
self.populate_layer_list()
def populate_layer_list(self):
self.layer_list.clear()
for layer in self.viewer.layers:
item = QListWidgetItem(layer.name)
item.setData(0x0100, layer)
self.layer_list.addItem(item)
def save_selected_layers(self):
selected_items = self.layer_list.selectedItems()
if not selected_items:
print("No layers selected.")
return
dialog = QFileDialog()
save_dir = dialog.getExistingDirectory(caption="Select Directory to Save Layers")
if not save_dir:
print("No directory selected.")
return
for item in selected_items:
layer = item.data(0x0100)
if isinstance(layer, napari.layers.Image):
self.save_layer(layer, save_dir)
else:
print(f"Layer {layer.name} is not an image layer. Skipping.")
def save_layer(self, layer, save_dir):
try:
image_data = layer.data
metadata = layer.metadata or {}
scale_metadata = layer.scale
if len(scale_metadata) == 3:
z_scale, y_scale, x_scale = scale_metadata
elif len(scale_metadata) == 2:
z_scale = 1
y_scale, x_scale = scale_metadata
else:
raise ValueError('Unexpected scale dimensions.')
ij_metadata = {
'axes': 'ZYX',
'spacing': z_scale,
'unit': 'micron',
'Info': 'Exported from Napari using tifffile.',
'Properties': {'License': 'Public domain'},
}
resolution = (1.0 / x_scale, 1.0 / y_scale)
filename = f"{save_dir}/{layer.name}.tif"
tifffile.imwrite(
filename,
image_data.astype(np.float32),
imagej=True,
resolution=resolution,
metadata=ij_metadata
)
print(f"Image layer {layer.name} saved with metadata to {filename}")
except Exception as e:
print(f"An error occurred: {e}")
# Hook into Napari
def main():
viewer = napari.current_viewer()
save_layer_widget = SaveLayerWidget(viewer)
viewer.window.add_dock_widget(save_layer_widget, area='right')
if __name__ == "__main__":
main() |
It'd be nice if this plugin could write tiff images, as well as read them.
Adding a writer function will involve:
napari_tiff/napari_tiff_writer.py
file, similar to this examplenapari.yaml
file to include the writer plugin information (see here and here, you need to updatenapari.yaml
in two places)The text was updated successfully, but these errors were encountered: