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): ...@@ -27,6 +27,7 @@ def guessType(path):
import fsl.data.gifti as fslgifti import fsl.data.gifti as fslgifti
import fsl.data.freesurfer as fslfs import fsl.data.freesurfer as fslfs
import fsl.data.mghimage as fslmgh import fsl.data.mghimage as fslmgh
import fsl.data.bitmap as fslbmp
import fsl.data.featimage as featimage import fsl.data.featimage as featimage
import fsl.data.melodicimage as melimage import fsl.data.melodicimage as melimage
import fsl.data.dtifit as dtifit import fsl.data.dtifit as dtifit
...@@ -56,6 +57,8 @@ def guessType(path): ...@@ -56,6 +57,8 @@ def guessType(path):
return fslfs.FreesurferMesh, path return fslfs.FreesurferMesh, path
elif fslpath.hasExt(path, fslmgh.ALLOWED_EXTENSIONS): elif fslpath.hasExt(path, fslmgh.ALLOWED_EXTENSIONS):
return fslmgh.MGHImage, path return fslmgh.MGHImage, path
elif fslpath.hasExt(path, fslbmp.BITMAP_EXTENSIONS):
return fslbmp.Bitmap, path
# Other specialised image types # Other specialised image types
elif melanalysis .isMelodicImage(path): 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