Loading imagej_tiffwriter.py +92 −86 Original line number Original line Diff line number Diff line Loading @@ -2,7 +2,7 @@ ''' ''' /** /** * @file imagej_tiff_saver.py * @file imagej_tiffwriter.py * @brief save tiffs for imagej (1.52d+) - with stacks and hyperstacks * @brief save tiffs for imagej (1.52d+) - with stacks and hyperstacks * @par <b>License</b>: * @par <b>License</b>: * This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify Loading @@ -29,47 +29,88 @@ Usage example: import imagej_tiffwriter import imagej_tiffwriter import numpy as np import numpy as np # have a few images in the form of numpy arrays Have a few images in the form of numpy arrays np.float32: # make sure to stack them as: - (h,w) # - (t,z,h,w,c) - (n,h,w) # - (z,h,w,c) # - (h,w,c) # - (h,w) imagej_tiffwriter.save(path,images) Labels can be provided as a list: ['label1','label2', etc.] No list length check against number of images imagej_tiffwriter.save(path,images,labels) ''' ''' from PIL import Image, TiffImagePlugin import numpy as np import numpy as np import struct import tifffile import math import math # DO NOT USE? # from here: https://stackoverflow.com/questions/50258287/how-to-specify-colormap-when-saving-tiff-stack # thing is the old ImageJs <1.52d poorly handle tags directories or something like that def imagej_metadata_tags(metadata, byteorder): def __get_IJ_IFD(t,z,c): """Return IJMetadata and IJMetadataByteCounts tags from metadata dict. ifd = TiffImagePlugin.ImageFileDirectory_v2() The tags can be passed to the TiffWriter.save function as extratags. ijheader = [ """ 'ImageJ=', header = [{'>': b'IJIJ', '<': b'JIJI'}[byteorder]] 'hyperstack=true', bytecounts = [0] 'images='+str(t*z*c), body = [] 'channels='+str(c), 'slices='+str(z), def writestring(data, byteorder): 'frames='+str(t), return data.encode('utf-16' + {'>': 'be', '<': 'le'}[byteorder]) 'loop=false' ] def writedoubles(data, byteorder): return struct.pack(byteorder+('d' * len(data)), *data) ifd[270] = ("\n".join(ijheader)+"\n") def writebytes(data, byteorder): return data.tobytes() metadata_types = ( ('Info', b'info', 1, writestring), ('Labels', b'labl', None, writestring), ('Ranges', b'rang', 1, writedoubles), ('LUTs', b'luts', None, writebytes), ('Plot', b'plot', 1, writebytes), ('ROI', b'roi ', 1, writebytes), ('Overlays', b'over', None, writebytes)) for key, mtype, count, func in metadata_types: if key not in metadata: continue if byteorder == '<': mtype = mtype[::-1] values = metadata[key] if count is None: count = len(values) else: values = [values] header.append(mtype + struct.pack(byteorder+'I', count)) for value in values: data = func(value, byteorder) body.append(data) bytecounts.append(len(data)) body = b''.join(body) header = b''.join(header) data = header + body bytecounts[0] = len(header) bytecounts = struct.pack(byteorder+('I' * len(bytecounts)), *bytecounts) return ((50839, 'B', len(data), data, True), (50838, 'I', len(bytecounts)//4, bytecounts, True)) #is_hyperstack = 'true' if len(shape)>1 else 'false' #if (len(shape)>0): return ifd #def save(path,images,force_stack=False,force_hyperstack=False): def save(path,images,labels=None,label_prefix="Label "): ''' labels a list or None ''' #def save(path,images,force_stack=False,force_hyperstack=False): ''' def save(path,images): Expecting: (h,w), (n,h,w) - just create a simple stack ''' # Got images, analyze shape: # Got images, analyze shape: # - possible formats (c == depth): # - possible formats (c == depth): Loading @@ -78,46 +119,30 @@ def save(path,images): # -- (h,w,c) # -- (h,w,c) # -- (h,w) # -- (h,w) # 0 or 1 images.shapes are not handled # 0 or 1 images.shapes are not handled # # # (h,w) # (h,w) if len(images.shape)==2: if len(images.shape)==2: images = images[np.newaxis,...] image = Image.fromarray(images) # now the shape length is 3 image.save(path) elif len(images.shape)>2: h,w,c = images.shape[-3:] if len(images.shape)==3: if len(images.shape)==3: images = np.reshape(images,(1,h,w,c)) # tifffile treats shape[0] as channel, need to expand to get labels displayed #images = images[images.shape[0],np.newaxis,images.shape[1],images.shape[2]] z = images.shape[-4] images = np.reshape(images,(images.shape[0],1,images.shape[1],images.shape[2])) if len(images.shape)==4: labels_list = [] images = np.reshape(images,(1,z,h,w,c)) if labels is None: for i in range(images.shape[0]): t = images.shape[-5] labels_list.append(label_prefix+str(i+1)) c_axis = -1 if c==1: split_channels = images else: else: channels = np.array(np.split(images,c,axis=c_axis)) labels_list = labels split_channels = np.concatenate(channels,axis=-3) images_flat = np.reshape(split_channels,(-1,h,w)) imlist = [] ijtags = imagej_metadata_tags({'Labels':labels_list}, '<') for i in range(images_flat.shape[0]): imlist.append(Image.fromarray(images_flat[i])) imlist[0].save(path,save_all=True,append_images=imlist[1:]) with tifffile.TiffWriter(path, bigtiff=False,imagej=True) as tif: # thing is the old ImageJs <1.52d poorly handle tags directories or something like that for i in range(images.shape[0]): #imlist[0].save(path,save_all=True,append_images=imlist[1:],tiffinfo=__get_IJ_IFD(t,z,c)) tif.save(images[i], metadata={'version':'1.11a','loop': False}, extratags=ijtags) # Testing # Testing if __name__ == "__main__": if __name__ == "__main__": Loading @@ -129,34 +154,15 @@ if __name__ == "__main__": hw = hamming_window hw = hamming_window NT = 5 NT = 5 NC = 2 NZ = 3 NX = 512 NX = 512 NY = 512 NY = 512 images = np.empty((NT,NZ,NY,NX,NC)) images = np.empty((NT,NY,NX),np.float32) import time import time print(str(time.time())+": Generating test images") print(str(time.time())+": Generating test images") for t in range(NT): for t in range(NT): for z in range(NZ): images[t,:,:] = np.array([[(255-t*25)*hw(i,512)*hw(j,512) for i in range(NX)] for j in range(NY)],np.float32) for c in range(NC): images[t,z,:,:,c] = np.array([[(255-t*25)*hw(i,512)*hw(j,512) for i in range(NX)] for j in range(NY)],np.float32) print(str(time.time())+": Test images generated") print(str(time.time())+": Test images generated") print("Images shape: "+str(images.shape)) print("Images shape: "+str(images.shape)) v = save("tiffwriter_test.tiff",images) print("5D run") v = save("result_5D.tiff",images) print("4D run") v = save("result_4D.tiff",images[0]) print("3D run") v = save("result_3D.tiff",images[0,0]) print("3D run, 1 channel") tmp_images = images[0,0,:,:,0] v = save("result_3D1C.tiff",tmp_images[:,:,np.newaxis]) imagej_tiffwriter_test.pydeleted 100644 → 0 +0 −240 Original line number Original line Diff line number Diff line #!/usr/bin/env python3 ''' /** * @file imagej_tiff_saver.py * @brief save tiffs for imagej (1.52d+) - with stacks and hyperstacks * @par <b>License</b>: * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ ''' __copyright__ = "Copyright 2018, Elphel, Inc." __license__ = "GPL-3.0+" __email__ = "oleg@elphel.com" ''' Usage example: import imagej_tiffwriter import numpy as np # have a few images in the form of numpy arrays # make sure to stack them as: # - (t,z,h,w,c) # - (z,h,w,c) # - (h,w,c) # - (h,w) imagej_tiffwriter.save(path,images) ''' from PIL import Image, TiffImagePlugin import numpy as np import math # DO NOT USE? # thing is the old ImageJs <1.52d poorly handle tags directories or something like that def __get_IJ_IFD(t,z,c): #ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=b"MM*\x00\x00\x00\x00\x00",prefix= b"MM") ifd = TiffImagePlugin.ImageFileDirectory_v2(prefix= b"MM") #ifd = TiffImagePlugin.ImageFileDirectory_v2() #ifd = TiffImagePlugin.ImageFileDirectory(prefix='MM') ijheader = [ 'ImageJ=', 'hyperstack=true', 'images='+str(t*z*c), 'channels='+str(c), 'slices='+str(z), 'frames='+str(t), 'loop=false' ] ifd[270] = ("\n".join(ijheader)+"\n") ijlabl = [ b'IJIJinfo\x00\x00\x00\x01labl\x00\x00\x00\x05', '<info></info>'.encode('UTF-16-LE'), 'img1'.encode('UTF-16-LE'), 'img2'.encode('UTF-16-LE'), 'img3'.encode('UTF-16-LE'), 'img4'.encode('UTF-16-LE'), 'img5'.encode('UTF-16-LE') ] #for i in range() #ifd[50838] = (20,10) #ifd[50839] = (20,10) ifd_50838_list = [] ifd_50839 = b"".join(ijlabl) for label in ijlabl: ifd_50838_list.append(len(label)) ifd_50838 = tuple(ifd_50838_list) #print(ifd_50838) #print(ifd_50839) #is_hyperstack = 'true' if len(shape)>1 else 'false' #if (len(shape)>0): ifd[50838] = ifd_50838 ifd[50839] = ifd_50839 # override #tif = Image.open("test.tiff") #tag_50838 = tif.tag[50838] #tag_50839 = tif.tag[50839] #tag_270 = tif.tag[270] #print(tag_50839) #ifd[270] = tag_270 #ifd[50838] = tag_50838 #ifd[50839] = tag_50839 return ifd #def save(path,images,force_stack=False,force_hyperstack=False): def save(path,images): # Got images, analyze shape: # - possible formats (c == depth): # -- (t,z,h,w,c) # -- (t,h,w,c), t or z does not matter # -- (h,w,c) # -- (h,w) # 0 or 1 images.shapes are not handled # # (h,w) if len(images.shape)==2: image = Image.fromarray(images) image.save(path) elif len(images.shape)>2: h,w,c = images.shape[-3:] if len(images.shape)==3: images = np.reshape(images,(1,h,w,c)) z = images.shape[-4] if len(images.shape)==4: images = np.reshape(images,(1,z,h,w,c)) t = images.shape[-5] c_axis = -1 if c==1: split_channels = images else: channels = np.array(np.split(images,c,axis=c_axis)) split_channels = np.concatenate(channels,axis=-3) images_flat = np.reshape(split_channels,(-1,h,w)) imlist = [] for i in range(images_flat.shape[0]): imlist.append(Image.fromarray(images_flat[i])) #imlist[0].save(path,save_all=True,append_images=imlist[1:]) # thing is the old ImageJs <1.52d poorly handle tags directories or something like that imlist[0].save(path,save_all=True,append_images=imlist[1:],tiffinfo=__get_IJ_IFD(t,z,c)) # Testing if __name__ == "__main__": def hamming_window(x,N): y = 0.54 - 0.46*math.cos(2*math.pi*x/(N-1)) return y hw = hamming_window NT = 5 NC = 1 NZ = 1 NX = 2916 NY = 2178 images = np.empty((NT,NZ,NY,NX,NC)) import time print(str(time.time())+": Generating test images") for t in range(NT): for z in range(NZ): for c in range(NC): images[t,z,:,:,c] = np.array([[(255-t*25)*hw(i,512)*hw(j,512) for i in range(NX)] for j in range(NY)],np.float32) print(str(time.time())+": Test images generated") print("Images shape: "+str(images.shape)) print("1D run") imgs = images[:,0,:,:,0] print(imgs.shape) imlist = [] for i in range(imgs.shape[0]): tmp = Image.fromarray(imgs[i]) #tmp.mode = "I;32BS" imlist.append(tmp) TiffImagePlugin.DEBUG = True TiffImagePlugin.WRITE_LIBTIFF = False #import sys #sys.byteorder = "big" #imlist[0].mode = "I;16B" #print("encoderconfig") #print(imlist[0].encoderconfig) imlist[0].save("result_1D.tiff",save_all=True,append_images=imlist[1:],tiffinfo=__get_IJ_IFD(NT,NZ,NC)) #v = save("result_1D.tiff",imgs) #tif = Image.open("result_1D.tiff") #tag_50838 = tif.tag[50838] #tag_50839 = tif.tag[50839] #tag_270 = tif.tag[270] #print(tag_50839) #tif = Image.open("test.tiff") #tif.save("test_saved.tiff") #print("5D run") #v = save("result_5D.tiff",images) #print("4D run") #v = save("result_4D.tiff",images[0]) #print("3D run") #v = save("result_3D.tiff",images[0,0]) #print("3D run, 1 channel") #tmp_images = images[0,0,:,:,0] #v = save("result_3D1C.tiff",tmp_images[:,:,np.newaxis]) # open test Loading
imagej_tiffwriter.py +92 −86 Original line number Original line Diff line number Diff line Loading @@ -2,7 +2,7 @@ ''' ''' /** /** * @file imagej_tiff_saver.py * @file imagej_tiffwriter.py * @brief save tiffs for imagej (1.52d+) - with stacks and hyperstacks * @brief save tiffs for imagej (1.52d+) - with stacks and hyperstacks * @par <b>License</b>: * @par <b>License</b>: * This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify Loading @@ -29,47 +29,88 @@ Usage example: import imagej_tiffwriter import imagej_tiffwriter import numpy as np import numpy as np # have a few images in the form of numpy arrays Have a few images in the form of numpy arrays np.float32: # make sure to stack them as: - (h,w) # - (t,z,h,w,c) - (n,h,w) # - (z,h,w,c) # - (h,w,c) # - (h,w) imagej_tiffwriter.save(path,images) Labels can be provided as a list: ['label1','label2', etc.] No list length check against number of images imagej_tiffwriter.save(path,images,labels) ''' ''' from PIL import Image, TiffImagePlugin import numpy as np import numpy as np import struct import tifffile import math import math # DO NOT USE? # from here: https://stackoverflow.com/questions/50258287/how-to-specify-colormap-when-saving-tiff-stack # thing is the old ImageJs <1.52d poorly handle tags directories or something like that def imagej_metadata_tags(metadata, byteorder): def __get_IJ_IFD(t,z,c): """Return IJMetadata and IJMetadataByteCounts tags from metadata dict. ifd = TiffImagePlugin.ImageFileDirectory_v2() The tags can be passed to the TiffWriter.save function as extratags. ijheader = [ """ 'ImageJ=', header = [{'>': b'IJIJ', '<': b'JIJI'}[byteorder]] 'hyperstack=true', bytecounts = [0] 'images='+str(t*z*c), body = [] 'channels='+str(c), 'slices='+str(z), def writestring(data, byteorder): 'frames='+str(t), return data.encode('utf-16' + {'>': 'be', '<': 'le'}[byteorder]) 'loop=false' ] def writedoubles(data, byteorder): return struct.pack(byteorder+('d' * len(data)), *data) ifd[270] = ("\n".join(ijheader)+"\n") def writebytes(data, byteorder): return data.tobytes() metadata_types = ( ('Info', b'info', 1, writestring), ('Labels', b'labl', None, writestring), ('Ranges', b'rang', 1, writedoubles), ('LUTs', b'luts', None, writebytes), ('Plot', b'plot', 1, writebytes), ('ROI', b'roi ', 1, writebytes), ('Overlays', b'over', None, writebytes)) for key, mtype, count, func in metadata_types: if key not in metadata: continue if byteorder == '<': mtype = mtype[::-1] values = metadata[key] if count is None: count = len(values) else: values = [values] header.append(mtype + struct.pack(byteorder+'I', count)) for value in values: data = func(value, byteorder) body.append(data) bytecounts.append(len(data)) body = b''.join(body) header = b''.join(header) data = header + body bytecounts[0] = len(header) bytecounts = struct.pack(byteorder+('I' * len(bytecounts)), *bytecounts) return ((50839, 'B', len(data), data, True), (50838, 'I', len(bytecounts)//4, bytecounts, True)) #is_hyperstack = 'true' if len(shape)>1 else 'false' #if (len(shape)>0): return ifd #def save(path,images,force_stack=False,force_hyperstack=False): def save(path,images,labels=None,label_prefix="Label "): ''' labels a list or None ''' #def save(path,images,force_stack=False,force_hyperstack=False): ''' def save(path,images): Expecting: (h,w), (n,h,w) - just create a simple stack ''' # Got images, analyze shape: # Got images, analyze shape: # - possible formats (c == depth): # - possible formats (c == depth): Loading @@ -78,46 +119,30 @@ def save(path,images): # -- (h,w,c) # -- (h,w,c) # -- (h,w) # -- (h,w) # 0 or 1 images.shapes are not handled # 0 or 1 images.shapes are not handled # # # (h,w) # (h,w) if len(images.shape)==2: if len(images.shape)==2: images = images[np.newaxis,...] image = Image.fromarray(images) # now the shape length is 3 image.save(path) elif len(images.shape)>2: h,w,c = images.shape[-3:] if len(images.shape)==3: if len(images.shape)==3: images = np.reshape(images,(1,h,w,c)) # tifffile treats shape[0] as channel, need to expand to get labels displayed #images = images[images.shape[0],np.newaxis,images.shape[1],images.shape[2]] z = images.shape[-4] images = np.reshape(images,(images.shape[0],1,images.shape[1],images.shape[2])) if len(images.shape)==4: labels_list = [] images = np.reshape(images,(1,z,h,w,c)) if labels is None: for i in range(images.shape[0]): t = images.shape[-5] labels_list.append(label_prefix+str(i+1)) c_axis = -1 if c==1: split_channels = images else: else: channels = np.array(np.split(images,c,axis=c_axis)) labels_list = labels split_channels = np.concatenate(channels,axis=-3) images_flat = np.reshape(split_channels,(-1,h,w)) imlist = [] ijtags = imagej_metadata_tags({'Labels':labels_list}, '<') for i in range(images_flat.shape[0]): imlist.append(Image.fromarray(images_flat[i])) imlist[0].save(path,save_all=True,append_images=imlist[1:]) with tifffile.TiffWriter(path, bigtiff=False,imagej=True) as tif: # thing is the old ImageJs <1.52d poorly handle tags directories or something like that for i in range(images.shape[0]): #imlist[0].save(path,save_all=True,append_images=imlist[1:],tiffinfo=__get_IJ_IFD(t,z,c)) tif.save(images[i], metadata={'version':'1.11a','loop': False}, extratags=ijtags) # Testing # Testing if __name__ == "__main__": if __name__ == "__main__": Loading @@ -129,34 +154,15 @@ if __name__ == "__main__": hw = hamming_window hw = hamming_window NT = 5 NT = 5 NC = 2 NZ = 3 NX = 512 NX = 512 NY = 512 NY = 512 images = np.empty((NT,NZ,NY,NX,NC)) images = np.empty((NT,NY,NX),np.float32) import time import time print(str(time.time())+": Generating test images") print(str(time.time())+": Generating test images") for t in range(NT): for t in range(NT): for z in range(NZ): images[t,:,:] = np.array([[(255-t*25)*hw(i,512)*hw(j,512) for i in range(NX)] for j in range(NY)],np.float32) for c in range(NC): images[t,z,:,:,c] = np.array([[(255-t*25)*hw(i,512)*hw(j,512) for i in range(NX)] for j in range(NY)],np.float32) print(str(time.time())+": Test images generated") print(str(time.time())+": Test images generated") print("Images shape: "+str(images.shape)) print("Images shape: "+str(images.shape)) v = save("tiffwriter_test.tiff",images) print("5D run") v = save("result_5D.tiff",images) print("4D run") v = save("result_4D.tiff",images[0]) print("3D run") v = save("result_3D.tiff",images[0,0]) print("3D run, 1 channel") tmp_images = images[0,0,:,:,0] v = save("result_3D1C.tiff",tmp_images[:,:,np.newaxis])
imagej_tiffwriter_test.pydeleted 100644 → 0 +0 −240 Original line number Original line Diff line number Diff line #!/usr/bin/env python3 ''' /** * @file imagej_tiff_saver.py * @brief save tiffs for imagej (1.52d+) - with stacks and hyperstacks * @par <b>License</b>: * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ ''' __copyright__ = "Copyright 2018, Elphel, Inc." __license__ = "GPL-3.0+" __email__ = "oleg@elphel.com" ''' Usage example: import imagej_tiffwriter import numpy as np # have a few images in the form of numpy arrays # make sure to stack them as: # - (t,z,h,w,c) # - (z,h,w,c) # - (h,w,c) # - (h,w) imagej_tiffwriter.save(path,images) ''' from PIL import Image, TiffImagePlugin import numpy as np import math # DO NOT USE? # thing is the old ImageJs <1.52d poorly handle tags directories or something like that def __get_IJ_IFD(t,z,c): #ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=b"MM*\x00\x00\x00\x00\x00",prefix= b"MM") ifd = TiffImagePlugin.ImageFileDirectory_v2(prefix= b"MM") #ifd = TiffImagePlugin.ImageFileDirectory_v2() #ifd = TiffImagePlugin.ImageFileDirectory(prefix='MM') ijheader = [ 'ImageJ=', 'hyperstack=true', 'images='+str(t*z*c), 'channels='+str(c), 'slices='+str(z), 'frames='+str(t), 'loop=false' ] ifd[270] = ("\n".join(ijheader)+"\n") ijlabl = [ b'IJIJinfo\x00\x00\x00\x01labl\x00\x00\x00\x05', '<info></info>'.encode('UTF-16-LE'), 'img1'.encode('UTF-16-LE'), 'img2'.encode('UTF-16-LE'), 'img3'.encode('UTF-16-LE'), 'img4'.encode('UTF-16-LE'), 'img5'.encode('UTF-16-LE') ] #for i in range() #ifd[50838] = (20,10) #ifd[50839] = (20,10) ifd_50838_list = [] ifd_50839 = b"".join(ijlabl) for label in ijlabl: ifd_50838_list.append(len(label)) ifd_50838 = tuple(ifd_50838_list) #print(ifd_50838) #print(ifd_50839) #is_hyperstack = 'true' if len(shape)>1 else 'false' #if (len(shape)>0): ifd[50838] = ifd_50838 ifd[50839] = ifd_50839 # override #tif = Image.open("test.tiff") #tag_50838 = tif.tag[50838] #tag_50839 = tif.tag[50839] #tag_270 = tif.tag[270] #print(tag_50839) #ifd[270] = tag_270 #ifd[50838] = tag_50838 #ifd[50839] = tag_50839 return ifd #def save(path,images,force_stack=False,force_hyperstack=False): def save(path,images): # Got images, analyze shape: # - possible formats (c == depth): # -- (t,z,h,w,c) # -- (t,h,w,c), t or z does not matter # -- (h,w,c) # -- (h,w) # 0 or 1 images.shapes are not handled # # (h,w) if len(images.shape)==2: image = Image.fromarray(images) image.save(path) elif len(images.shape)>2: h,w,c = images.shape[-3:] if len(images.shape)==3: images = np.reshape(images,(1,h,w,c)) z = images.shape[-4] if len(images.shape)==4: images = np.reshape(images,(1,z,h,w,c)) t = images.shape[-5] c_axis = -1 if c==1: split_channels = images else: channels = np.array(np.split(images,c,axis=c_axis)) split_channels = np.concatenate(channels,axis=-3) images_flat = np.reshape(split_channels,(-1,h,w)) imlist = [] for i in range(images_flat.shape[0]): imlist.append(Image.fromarray(images_flat[i])) #imlist[0].save(path,save_all=True,append_images=imlist[1:]) # thing is the old ImageJs <1.52d poorly handle tags directories or something like that imlist[0].save(path,save_all=True,append_images=imlist[1:],tiffinfo=__get_IJ_IFD(t,z,c)) # Testing if __name__ == "__main__": def hamming_window(x,N): y = 0.54 - 0.46*math.cos(2*math.pi*x/(N-1)) return y hw = hamming_window NT = 5 NC = 1 NZ = 1 NX = 2916 NY = 2178 images = np.empty((NT,NZ,NY,NX,NC)) import time print(str(time.time())+": Generating test images") for t in range(NT): for z in range(NZ): for c in range(NC): images[t,z,:,:,c] = np.array([[(255-t*25)*hw(i,512)*hw(j,512) for i in range(NX)] for j in range(NY)],np.float32) print(str(time.time())+": Test images generated") print("Images shape: "+str(images.shape)) print("1D run") imgs = images[:,0,:,:,0] print(imgs.shape) imlist = [] for i in range(imgs.shape[0]): tmp = Image.fromarray(imgs[i]) #tmp.mode = "I;32BS" imlist.append(tmp) TiffImagePlugin.DEBUG = True TiffImagePlugin.WRITE_LIBTIFF = False #import sys #sys.byteorder = "big" #imlist[0].mode = "I;16B" #print("encoderconfig") #print(imlist[0].encoderconfig) imlist[0].save("result_1D.tiff",save_all=True,append_images=imlist[1:],tiffinfo=__get_IJ_IFD(NT,NZ,NC)) #v = save("result_1D.tiff",imgs) #tif = Image.open("result_1D.tiff") #tag_50838 = tif.tag[50838] #tag_50839 = tif.tag[50839] #tag_270 = tif.tag[270] #print(tag_50839) #tif = Image.open("test.tiff") #tif.save("test_saved.tiff") #print("5D run") #v = save("result_5D.tiff",images) #print("4D run") #v = save("result_4D.tiff",images[0]) #print("3D run") #v = save("result_3D.tiff",images[0,0]) #print("3D run, 1 channel") #tmp_images = images[0,0,:,:,0] #v = save("result_3D1C.tiff",tmp_images[:,:,np.newaxis]) # open test