Skip to content
Snippets Groups Projects
Commit c3996827 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

ENH: New Bitmap class, for loading bitmap images

parent d19d4708
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python
#
# bitmap.py - The Bitmap class
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module contains the :class:`Bitmap` class, for loading bitmap image
files.
"""
import os.path as op
import logging
import six
import numpy as np
import PIL.Image as Image
from . import image as fslimage
log = logging.getLogger(__name__)
BITMAP_EXTENSIONS = ['.bmp', '.png', '.jpg', '.jpeg',
'.tif', '.tiff', '.gif', '.rgba']
"""File extensions we understand. """
BITMAP_DESCRIPTIONS = [
'Bitmap',
'Portable Network Graphics',
'JPEG',
'JPEG',
'TIFF',
'TIFF',
'Graphics Interchange Format',
'Raw RGBA']
"""A description for each :attr:`BITMAP_EXTENSION`. """
class Bitmap(object):
"""The ``Bitmap`` class can be used to load a bitmap image. The
:meth:`asImage` method will convert the bitmap into an :class:`.Image`
instance.
"""
def __init__(self, bmp):
"""Create a ``Bitmap``.
:arg bmp: File name of an image, or a ``numpy`` array containing image
data.
"""
if isinstance(bmp, six.string_types):
source = bmp
data = np.array(Image.open(source))
elif isinstance(bmp, np.ndarray):
source = 'array'
data = np.copy(bmp)
else:
raise ValueError('unknown bitmap: {}'.format(bmp))
# Make the array (w, h, c)
data = data.transpose((1, 0, 2))
w, h = data.shape[:2]
data = np.array(data, dtype=np.uint8, order='C')
self.__data = data
self.__dataSource = source
self.__name = op.basename(source)
def __hash__(self):
"""Returns a number which uniquely idenfities this ``Bitmap`` instance
(the result of ``id(self)``).
"""
return id(self)
def __str__(self):
"""Return a string representation of this ``Bitmap`` instance."""
return '{}({}, {})'.format(self.__class__.__name__,
self.dataSource,
self.shape)
def __repr__(self):
"""See the :meth:`__str__` method. """
return self.__str__()
@property
def name(self):
"""Returns the name of this ``Bitmap``, typically the base name of the
file.
"""
return self.__name
@property
def dataSource(self):
"""Returns the bitmap data source - typically the file name. """
return self.__dataSource
@property
def data(self):
"""Convenience method which returns the bitmap data as a ``(w, h, c)``
array, where ``c`` is either 3 or 4.
"""
return self.__data
@property
def shape(self):
"""Returns the bitmap shape - ``(width, height, nchannels)``. """
return self.__data.shape
def asImage(self):
"""Convert this ``Bitmap`` into an :class:`.Image` instance. """
width, height, nchannels = self.shape
if nchannels == 1:
dtype = np.uint8
elif nchannels == 3:
dtype = np.dtype([('R', 'uint8'),
('G', 'uint8'),
('B', 'uint8')])
elif nchannels == 4:
dtype = np.dtype([('R', 'uint8'),
('G', 'uint8'),
('B', 'uint8'),
('A', 'uint8')])
else:
raise ValueError('Cannot convert bitmap with {} '
'channels into nifti image'.format(nchannels))
if nchannels == 1:
data = self.data.reshape((width, height))
else:
data = np.zeros((width, height), dtype=dtype)
for ch, ci in enumerate(dtype.names):
data[ch] = self.data[..., ci]
return fslimage.Image(data, np.eye(4))
......@@ -27,6 +27,7 @@ def guessType(path):
import fsl.data.gifti as fslgifti
import fsl.data.freesurfer as fslfs
import fsl.data.mghimage as fslmgh
import fsl.data.bitmap as fslbmp
import fsl.data.featimage as featimage
import fsl.data.melodicimage as melimage
import fsl.data.dtifit as dtifit
......@@ -56,6 +57,8 @@ def guessType(path):
return fslfs.FreesurferMesh, path
elif fslpath.hasExt(path, fslmgh.ALLOWED_EXTENSIONS):
return fslmgh.MGHImage, path
elif fslpath.hasExt(path, fslbmp.BITMAP_EXTENSIONS):
return fslbmp.Bitmap, path
# Other specialised image types
elif melanalysis .isMelodicImage(path):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment