Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/imageio-2.35.1-py3.8.egg/imageio/plugins/tifffile.py: 29%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

120 statements  

1# -*- coding: utf-8 -*- 

2# imageio is distributed under the terms of the (new) BSD License. 

3 

4""" Read/Write TIFF files. 

5 

6Backend: internal 

7 

8Provides support for a wide range of Tiff images using the tifffile 

9backend. 

10 

11Parameters for reading 

12---------------------- 

13offset : int 

14 Optional start position of embedded file. By default this is 

15 the current file position. 

16size : int 

17 Optional size of embedded file. By default this is the number 

18 of bytes from the 'offset' to the end of the file. 

19multifile : bool 

20 If True (default), series may include pages from multiple files. 

21 Currently applies to OME-TIFF only. 

22multifile_close : bool 

23 If True (default), keep the handles of other files in multifile 

24 series closed. This is inefficient when few files refer to 

25 many pages. If False, the C runtime may run out of resources. 

26 

27Parameters for saving 

28--------------------- 

29bigtiff : bool 

30 If True, the BigTIFF format is used. 

31byteorder : {'<', '>'} 

32 The endianness of the data in the file. 

33 By default this is the system's native byte order. 

34software : str 

35 Name of the software used to create the image. 

36 Saved with the first page only. 

37 

38Metadata for reading 

39-------------------- 

40planar_configuration : {'contig', 'planar'} 

41 Specifies if samples are stored contiguous or in separate planes. 

42 By default this setting is inferred from the data shape. 

43 'contig': last dimension contains samples. 

44 'planar': third last dimension contains samples. 

45resolution_unit : int 

46 The resolution unit stored in the TIFF tag. Usually 1 means no/unknown unit, 

47 2 means dpi (inch), 3 means dpc (centimeter). 

48resolution : (float, float, str) 

49 A tuple formatted as (X_resolution, Y_resolution, unit). The unit is a 

50 string representing one of the following units:: 

51 

52 NONE # No unit or unit unknown 

53 INCH # dpi 

54 CENTIMETER # cpi 

55 MILLIMETER 

56 MICROMETER 

57 

58compression : int 

59 Value indicating the compression algorithm used, e.g. 5 is LZW, 

60 7 is JPEG, 8 is deflate. 

61 If 1, data are uncompressed. 

62predictor : int 

63 Value 2 indicates horizontal differencing was used before compression, 

64 while 3 indicates floating point horizontal differencing. 

65 If 1, no prediction scheme was used before compression. 

66orientation : {'top_left', 'bottom_right', ...} 

67 Oriented of image array. 

68is_rgb : bool 

69 True if page contains a RGB image. 

70is_contig : bool 

71 True if page contains a contiguous image. 

72is_tiled : bool 

73 True if page contains tiled image. 

74is_palette : bool 

75 True if page contains a palette-colored image and not OME or STK. 

76is_reduced : bool 

77 True if page is a reduced image of another image. 

78is_shaped : bool 

79 True if page contains shape in image_description tag. 

80is_fluoview : bool 

81 True if page contains FluoView MM_STAMP tag. 

82is_nih : bool 

83 True if page contains NIH image header. 

84is_micromanager : bool 

85 True if page contains Micro-Manager metadata. 

86is_ome : bool 

87 True if page contains OME-XML in image_description tag. 

88is_sgi : bool 

89 True if page contains SGI image and tile depth tags. 

90is_mdgel : bool 

91 True if page contains md_file_tag tag. 

92is_mediacy : bool 

93 True if page contains Media Cybernetics Id tag. 

94is_stk : bool 

95 True if page contains UIC2Tag tag. 

96is_lsm : bool 

97 True if page contains LSM CZ_LSM_INFO tag. 

98description : str 

99 Image description 

100description1 : str 

101 Additional description 

102is_imagej : None or str 

103 ImageJ metadata 

104software : str 

105 Software used to create the TIFF file 

106datetime : datetime.datetime 

107 Creation date and time 

108 

109Metadata for writing 

110-------------------- 

111photometric : {'minisblack', 'miniswhite', 'rgb'} 

112 The color space of the image data. 

113 By default this setting is inferred from the data shape. 

114planarconfig : {'contig', 'planar'} 

115 Specifies if samples are stored contiguous or in separate planes. 

116 By default this setting is inferred from the data shape. 

117 'contig': last dimension contains samples. 

118 'planar': third last dimension contains samples. 

119resolution : (float, float) or ((int, int), (int, int)) 

120 X and Y resolution in dots per inch as float or rational numbers. 

121description : str 

122 The subject of the image. Saved with the first page only. 

123compress : int 

124 Values from 0 to 9 controlling the level of zlib (deflate) compression. 

125 If 0, data are written uncompressed (default). 

126compression : str, (int, int) 

127 Compression scheme used while writing the image. If omitted (default) the 

128 image is not uncompressed. Compression cannot be used to write contiguous 

129 series. Compressors may require certain data shapes, types or value ranges. 

130 For example, JPEG compression requires grayscale or RGB(A), uint8 or 12-bit 

131 uint16. JPEG compression is experimental. JPEG markers and TIFF tags may not 

132 match. Only a limited set of compression schemes are implemented. 'ZLIB' is 

133 short for ADOBE_DEFLATE. The value is written to the Compression tag. 

134compressionargs: 

135 Extra arguments passed to compression codec, e.g., compression level. Refer 

136 to the Imagecodecs implementation for supported arguments. 

137predictor : bool 

138 If True, horizontal differencing is applied before compression. 

139 Note that using an int literal 1 actually means no prediction scheme 

140 will be used. 

141volume : bool 

142 If True, volume data are stored in one tile (if applicable) using 

143 the SGI image_depth and tile_depth tags. 

144 Image width and depth must be multiple of 16. 

145 Few software can read this format, e.g. MeVisLab. 

146writeshape : bool 

147 If True, write the data shape to the image_description tag 

148 if necessary and no other description is given. 

149extratags: sequence of tuples 

150 Additional tags as [(code, dtype, count, value, writeonce)]. 

151 

152 code : int 

153 The TIFF tag Id. 

154 dtype : str 

155 Data type of items in 'value' in Python struct format. 

156 One of B, s, H, I, 2I, b, h, i, f, d, Q, or q. 

157 count : int 

158 Number of data values. Not used for string values. 

159 value : sequence 

160 'Count' values compatible with 'dtype'. 

161 writeonce : bool 

162 If True, the tag is written to the first page only. 

163 

164Notes 

165----- 

166Global metadata is stored with the first frame in a TIFF file. 

167Thus calling :py:meth:`Format.Writer.set_meta_data` after the first frame 

168was written has no effect. Also, global metadata is ignored if metadata is 

169provided via the `meta` argument of :py:meth:`Format.Writer.append_data`. 

170 

171If you have installed tifffile as a Python package, imageio will attempt 

172to use that as backend instead of the bundled backend. Doing so can 

173provide access to new performance improvements and bug fixes. 

174 

175""" 

176 

177import datetime 

178 

179from ..core import Format 

180from ..core.request import URI_BYTES, URI_FILE 

181 

182import numpy as np 

183import warnings 

184 

185 

186try: 

187 import tifffile as _tifffile 

188except ImportError: 

189 warnings.warn( 

190 "ImageIO's vendored tifffile backend is deprecated and will be" 

191 " removed in ImageIO v3. Install the tifffile directly:" 

192 " `pip install imageio[tifffile]`", 

193 DeprecationWarning, 

194 ) 

195 from . import _tifffile 

196 

197 

198TIFF_FORMATS = (".tif", ".tiff", ".stk", ".lsm") 

199WRITE_METADATA_KEYS = ( 

200 "photometric", 

201 "planarconfig", 

202 "resolution", 

203 "description", 

204 "compress", 

205 "compression", 

206 "compressionargs", 

207 "predictor", 

208 "volume", 

209 "writeshape", 

210 "extratags", 

211 "datetime", 

212) 

213READ_METADATA_KEYS = ( 

214 "planar_configuration", 

215 "is_fluoview", 

216 "is_nih", 

217 "is_contig", 

218 "is_micromanager", 

219 "is_ome", 

220 "is_lsm", 

221 "is_palette", 

222 "is_reduced", 

223 "is_rgb", 

224 "is_sgi", 

225 "is_shaped", 

226 "is_stk", 

227 "is_tiled", 

228 "is_mdgel", 

229 "resolution_unit", 

230 "compression", 

231 "predictor", 

232 "is_mediacy", 

233 "orientation", 

234 "description", 

235 "description1", 

236 "is_imagej", 

237 "software", 

238) 

239 

240 

241class TiffFormat(Format): 

242 """Provides support for a wide range of Tiff images using the tifffile 

243 backend. 

244 

245 Images that contain multiple pages can be read using ``imageio.mimread()`` 

246 to read the individual pages, or ``imageio.volread()`` to obtain a 

247 single (higher dimensional) array. 

248 

249 Note that global metadata is stored with the first frame in a TIFF file. 

250 Thus calling :py:meth:`Format.Writer.set_meta_data` after the first frame 

251 was written has no effect. Also, global metadata is ignored if metadata is 

252 provided via the `meta` argument of :py:meth:`Format.Writer.append_data`. 

253 

254 If you have installed tifffile as a Python package, imageio will attempt 

255 to use that as backend instead of the bundled backend. Doing so can 

256 provide access to new performance improvements and bug fixes. 

257 

258 Parameters for reading 

259 ---------------------- 

260 offset : int 

261 Optional start position of embedded file. By default this is 

262 the current file position. 

263 size : int 

264 Optional size of embedded file. By default this is the number 

265 of bytes from the 'offset' to the end of the file. 

266 multifile : bool 

267 If True (default), series may include pages from multiple files. 

268 Currently applies to OME-TIFF only. 

269 multifile_close : bool 

270 If True (default), keep the handles of other files in multifile 

271 series closed. This is inefficient when few files refer to 

272 many pages. If False, the C runtime may run out of resources. 

273 

274 Parameters for saving 

275 --------------------- 

276 bigtiff : bool 

277 If True, the BigTIFF format is used. 

278 byteorder : {'<', '>'} 

279 The endianness of the data in the file. 

280 By default this is the system's native byte order. 

281 software : str 

282 Name of the software used to create the image. 

283 Saved with the first page only. 

284 

285 Metadata for reading 

286 -------------------- 

287 planar_configuration : {'contig', 'planar'} 

288 Specifies if samples are stored contiguous or in separate planes. 

289 By default this setting is inferred from the data shape. 

290 'contig': last dimension contains samples. 

291 'planar': third last dimension contains samples. 

292 resolution_unit : (float, float) or ((int, int), (int, int)) 

293 X and Y resolution in dots per inch as float or rational numbers. 

294 compression : int 

295 Value indicating the compression algorithm used, e.g. 5 is LZW, 

296 7 is JPEG, 8 is deflate. 

297 If 1, data are uncompressed. 

298 predictor : int 

299 Value 2 indicates horizontal differencing was used before compression, 

300 while 3 indicates floating point horizontal differencing. 

301 If 1, no prediction scheme was used before compression. 

302 orientation : {'top_left', 'bottom_right', ...} 

303 Oriented of image array. 

304 is_rgb : bool 

305 True if page contains a RGB image. 

306 is_contig : bool 

307 True if page contains a contiguous image. 

308 is_tiled : bool 

309 True if page contains tiled image. 

310 is_palette : bool 

311 True if page contains a palette-colored image and not OME or STK. 

312 is_reduced : bool 

313 True if page is a reduced image of another image. 

314 is_shaped : bool 

315 True if page contains shape in image_description tag. 

316 is_fluoview : bool 

317 True if page contains FluoView MM_STAMP tag. 

318 is_nih : bool 

319 True if page contains NIH image header. 

320 is_micromanager : bool 

321 True if page contains Micro-Manager metadata. 

322 is_ome : bool 

323 True if page contains OME-XML in image_description tag. 

324 is_sgi : bool 

325 True if page contains SGI image and tile depth tags. 

326 is_stk : bool 

327 True if page contains UIC2Tag tag. 

328 is_mdgel : bool 

329 True if page contains md_file_tag tag. 

330 is_mediacy : bool 

331 True if page contains Media Cybernetics Id tag. 

332 is_stk : bool 

333 True if page contains UIC2Tag tag. 

334 is_lsm : bool 

335 True if page contains LSM CZ_LSM_INFO tag. 

336 description : str 

337 Image description 

338 description1 : str 

339 Additional description 

340 is_imagej : None or str 

341 ImageJ metadata 

342 software : str 

343 Software used to create the TIFF file 

344 datetime : datetime.datetime 

345 Creation date and time 

346 

347 Metadata for writing 

348 -------------------- 

349 photometric : {'minisblack', 'miniswhite', 'rgb'} 

350 The color space of the image data. 

351 By default this setting is inferred from the data shape. 

352 planarconfig : {'contig', 'planar'} 

353 Specifies if samples are stored contiguous or in separate planes. 

354 By default this setting is inferred from the data shape. 

355 'contig': last dimension contains samples. 

356 'planar': third last dimension contains samples. 

357 resolution : (float, float) or ((int, int), (int, int)) 

358 X and Y resolution in dots per inch as float or rational numbers. 

359 description : str 

360 The subject of the image. Saved with the first page only. 

361 compress : int 

362 Values from 0 to 9 controlling the level of zlib (deflate) compression. 

363 If 0, data are written uncompressed (default). 

364 predictor : bool 

365 If True, horizontal differencing is applied before compression. 

366 Note that using an int literal 1 actually means no prediction scheme 

367 will be used. 

368 volume : bool 

369 If True, volume data are stored in one tile (if applicable) using 

370 the SGI image_depth and tile_depth tags. 

371 Image width and depth must be multiple of 16. 

372 Few software can read this format, e.g. MeVisLab. 

373 writeshape : bool 

374 If True, write the data shape to the image_description tag 

375 if necessary and no other description is given. 

376 extratags: sequence of tuples 

377 Additional tags as [(code, dtype, count, value, writeonce)]. 

378 

379 code : int 

380 The TIFF tag Id. 

381 dtype : str 

382 Data type of items in 'value' in Python struct format. 

383 One of B, s, H, I, 2I, b, h, i, f, d, Q, or q. 

384 count : int 

385 Number of data values. Not used for string values. 

386 value : sequence 

387 'Count' values compatible with 'dtype'. 

388 writeonce : bool 

389 If True, the tag is written to the first page only. 

390 """ 

391 

392 def _can_read(self, request): 

393 try: 

394 _tifffile.TiffFile(request.get_file(), **request.kwargs) 

395 except ValueError: 

396 # vendored backend raises value exception 

397 return False 

398 except _tifffile.TiffFileError: # pragma: no-cover 

399 # current version raises custom exception 

400 return False 

401 finally: 

402 request.get_file().seek(0) 

403 

404 return True 

405 

406 def _can_write(self, request): 

407 if request._uri_type in [URI_FILE, URI_BYTES]: 

408 pass # special URI 

409 elif request.extension not in self.extensions: 

410 return False 

411 

412 try: 

413 _tifffile.TiffWriter(request.get_file(), **request.kwargs) 

414 except ValueError: 

415 # vendored backend raises value exception 

416 return False 

417 except _tifffile.TiffFileError: # pragma: no-cover 

418 # current version raises custom exception 

419 return False 

420 finally: 

421 request.get_file().seek(0) 

422 return True 

423 

424 # -- reader 

425 

426 class Reader(Format.Reader): 

427 def _open(self, **kwargs): 

428 # Allow loading from http; tifffile uses seek, so download first 

429 if self.request.filename.startswith(("http://", "https://")): 

430 self._f = f = open(self.request.get_local_filename(), "rb") 

431 else: 

432 self._f = None 

433 f = self.request.get_file() 

434 self._tf = _tifffile.TiffFile(f, **kwargs) 

435 

436 def _close(self): 

437 self._tf.close() 

438 if self._f is not None: 

439 self._f.close() 

440 

441 def _get_length(self): 

442 return len(self._tf.series) 

443 

444 def _get_data(self, index): 

445 if index < 0 or index >= self._get_length(): 

446 raise IndexError("Index out of range while reading from tiff file") 

447 

448 im = self._tf.asarray(series=index) 

449 meta = self._get_meta_data(index) 

450 

451 return im, meta 

452 

453 def _get_meta_data(self, index): 

454 meta = {} 

455 page = self._tf.pages[index or 0] 

456 for key in READ_METADATA_KEYS: 

457 try: 

458 meta[key] = getattr(page, key) 

459 except Exception: 

460 pass 

461 

462 # tifffile <= 0.12.1 use datetime, newer use DateTime 

463 for key in ("datetime", "DateTime"): 

464 try: 

465 meta["datetime"] = datetime.datetime.strptime( 

466 page.tags[key].value, "%Y:%m:%d %H:%M:%S" 

467 ) 

468 break 

469 except Exception: 

470 pass 

471 

472 if 296 in page.tags: 

473 meta["resolution_unit"] = page.tags[296].value.value 

474 

475 if 282 in page.tags and 283 in page.tags and 296 in page.tags: 

476 resolution_x = page.tags[282].value 

477 resolution_y = page.tags[283].value 

478 if resolution_x[1] == 0 or resolution_y[1] == 0: 

479 warnings.warn( 

480 "Ignoring resolution metadata, " 

481 "because at least one direction has a 0 denominator.", 

482 RuntimeWarning, 

483 ) 

484 else: 

485 meta["resolution"] = ( 

486 resolution_x[0] / resolution_x[1], 

487 resolution_y[0] / resolution_y[1], 

488 page.tags[296].value.name, 

489 ) 

490 

491 return meta 

492 

493 # -- writer 

494 class Writer(Format.Writer): 

495 def _open(self, bigtiff=None, byteorder=None, software=None): 

496 try: 

497 self._tf = _tifffile.TiffWriter( 

498 self.request.get_file(), 

499 bigtiff=bigtiff, 

500 byteorder=byteorder, 

501 software=software, 

502 ) 

503 self._software = None 

504 except TypeError: 

505 # In tifffile >= 0.15, the `software` arg is passed to 

506 # TiffWriter.save 

507 self._tf = _tifffile.TiffWriter( 

508 self.request.get_file(), bigtiff=bigtiff, byteorder=byteorder 

509 ) 

510 self._software = software 

511 

512 self._meta = {} 

513 self._frames_written = 0 

514 

515 def _close(self): 

516 self._tf.close() 

517 

518 def _append_data(self, im, meta): 

519 if meta is not None: 

520 meta = self._sanitize_meta(meta) 

521 else: 

522 # Use global metadata for first frame 

523 meta = self._meta if self._frames_written == 0 else {} 

524 if self._software is not None and self._frames_written == 0: 

525 meta["software"] = self._software 

526 # No need to check self.request.mode; tifffile figures out whether 

527 # this is a single page, or all page data at once. 

528 try: 

529 # TiffWriter.save has been deprecated in version 2020.9.30 

530 write_meth = self._tf.write 

531 except AttributeError: 

532 write_meth = self._tf.save 

533 write_meth(np.asanyarray(im), contiguous=False, **meta) 

534 self._frames_written += 1 

535 

536 @staticmethod 

537 def _sanitize_meta(meta): 

538 ret = {} 

539 for key, value in meta.items(): 

540 if key in WRITE_METADATA_KEYS: 

541 # Special case of previously read `predictor` int value 

542 # 1(=NONE) translation to False expected by TiffWriter.save 

543 if key == "predictor" and not isinstance(value, bool): 

544 ret[key] = value > 1 

545 elif key == "compress" and value != 0: 

546 warnings.warn( 

547 "The use of `compress` is deprecated. Use `compression` and `compressionargs` instead.", 

548 DeprecationWarning, 

549 ) 

550 

551 if _tifffile.__version__ < "2022": 

552 ret["compression"] = (8, value) 

553 else: 

554 ret["compression"] = "zlib" 

555 ret["compressionargs"] = {"level": value} 

556 else: 

557 ret[key] = value 

558 return ret 

559 

560 def set_meta_data(self, meta): 

561 self._meta = self._sanitize_meta(meta)