def load(self): """Load the image data into memory, if it is not already accessible. It is save to call this method several times successively. """ # do nothing if there already is data # which included memory mapped arrays not just data in memory if self._haveImageData(): return if ncl.nifti_image_load(self.raw_nimg) < 0: raise RuntimeError, "Unable to load image data." self._data = ncl.wrapImageDataWithArray(self.raw_nimg) # take data pointer away from nifticlibs so we can let Python manage # the memory ncl.detachDataFromImage(self.raw_nimg)
def save(self, filename=None, filetype="NIFTI", update_minmax=True): """Save the image to a file. If the image was created using array data (i.e., not loaded from a file) a filename has to be specified. If not yet done already, the image data will be loaded into memory before saving the file. :Parameters: filename: str | None The name of the target file (typically including its extension). Filenames might be provided as unicode strings. However, as the underlying library does not support unicode, they must be ascii-encodable, i.e. must not contain pure unicode characters. Usually setting the filename also determines the filetype (NIfTI/ANALYZE). Please see :meth:`~nifti.image.NiftiImage.setFilename` for some more details. If None, an image loaded from a file will cause the original image to be overwritten. filetype: str Provide intented filetype. Please see the documentation of the `setFilename()` method for some more details. update_minmax: bool Whether the image header's min and max values should be updated according to the current image data. .. warning:: There will be no exception if writing fails for any reason, as the underlying function nifti_write_hdr_img() from libniftiio does not provide any feedback. Suggestions for improvements are appreciated. """ if not filename is None: # make sure filename is not unicode try: filename = str(filename) except UnicodeEncodeError: raise UnicodeError, "The filename must not contain unicode characters, since " "the NIfTI library cannot handle them." # If image data is not yet loaded, do it now. # It is important to do it already here, because nifti_image_load # depends on the correct filename set in the nifti_image struct # and this will be modified in this function! self.load() # set a default description if there is none if not self.description: self.description = "Written by PyNIfTI version %s" % nifti.__version__ # update header information if update_minmax: self.updateCalMinMax() # saving for the first time? if not self.filename or filename: if not filename: raise ValueError, "When saving an image for the first time a filename " + "has to be specified." self.setFilename(filename, filetype) # if still no data is present data source has been an array # -> allocate memory in nifti struct and assign data to it if not self.raw_nimg.data: if not ncl.allocateImageMemory(self.raw_nimg): raise RuntimeError, "Could not allocate memory for image data." else: raise RuntimeError, "This should never happen! Please report me!" # This assumes that the nimg struct knows about the correct datatype and # dimensions of the array a = ncl.wrapImageDataWithArray(self.raw_nimg) a[:] = self._data[:] # # embed meta data # if len(self.meta.keys()): self.extensions += ("pypickle", cPickle.dumps(self.meta, protocol=0)) # now save it ncl.nifti_image_write_hdr_img(self.raw_nimg, 1, "wb") # yoh comment: unfortunately return value of nifti_image_write_hdr_img # can't be used to track the successful completion of save # raise IOError, 'An error occured while attempting to save the image # file.' # take data pointer away from nifticlibs so we can let Python manage # the memory ncl.detachDataFromImage(self.raw_nimg) # and finally clean 'pypickle' extension again, since its data is in # 'meta' self._removePickleExtension()