[Yt-svn] yt: * Adding a write_bitmap function to image_writer. This acce...

hg at spacepope.org hg at spacepope.org
Wed May 26 16:35:45 PDT 2010


hg Repository: yt
details:   yt/rev/b775ab154834
changeset: 1712:b775ab154834
user:      Matthew Turk <matthewturk at gmail.com>
date:
Wed May 26 16:35:37 2010 -0700
description:
* Adding a write_bitmap function to image_writer.  This accepts either a uint8
   bitmap of shape (N,M,3), (N,M,4) and writes it, or a non-uint8 bitmap of the
   same set of shapes and writes them out.  Optionally it can scale to an
   arbitrary value, otherwise it scales to the max.  This function can take the
   output of a camera.snapshot() call directly and save it.
 * Moved the docstrings from the image_handling routines into their functions
   so that autodoc will pick them up, and changed them to be more narrative.
   (This change is up for discussion, but that's the way the vast majority of
   the rest of yt is currently written.  Something like the NumPy standard
   would be better, but a large effort to implement.)

diffstat:

 yt/extensions/image_writer.py                    |  26 ++++++++
 yt/extensions/volume_rendering/image_handling.py |  87 ++++++++--------------------
 2 files changed, 52 insertions(+), 61 deletions(-)

diffs (159 lines):

diff -r 8bc8433ed313 -r b775ab154834 yt/extensions/image_writer.py
--- a/yt/extensions/image_writer.py	Wed May 26 14:58:12 2010 -0700
+++ b/yt/extensions/image_writer.py	Wed May 26 16:35:37 2010 -0700
@@ -60,6 +60,32 @@
     image = image.transpose().copy() # Have to make sure it's contiguous 
     au.write_png(image, fn)
 
+def write_bitmap(bitmap_array, filename, max_val = None):
+    """
+    This accepts a three- or four-channel *bitmap_array*.  If the image is not
+    already uint8, it will be scaled and converted.  If it is not four channel,
+    a fourth alpha channel will be added and set to fully opaque.  The
+    resultant image will be directly written to *filename* as a PNG with no
+    colormap applied.  *max_val* is a value used if the array is passed in as
+    anything other than uint8; it will be the value used for scaling and
+    clipping when the array is converted.
+
+    Additionally, the minimum is assumed to be zero; this makes it primarily
+    suited for the results of volume rendered images, rather than misaligned
+    projections.
+    """
+    if bitmap_array.dtype != na.uint8:
+        if max_val is None: max_val = bitmap_array.max()
+        bitmap_array = na.clip(bitmap_array / max_val, 0.0, 1.0) * 255
+        bitmap_array = bitmap_array.astype("uint8")
+    if len(bitmap_array.shape) != 3 or bitmap_array.shape[-1] not in (3,4):
+        raise RuntimeError
+    if bitmap_array.shape[-1] == 3:
+        s1, s2 = bitmap_array.shape[:2]
+        alpha_channel = 255*na.ones((s1,s2,1), dtype='uint8')
+        bitmap_array = na.concatenate([bitmap_array, alpha_channel], axis=-1)
+    au.write_png(bitmap_array.copy(), filename)
+
 def write_image(image, filename, color_bounds = None, cmap_name = "algae"):
     if color_bounds is None:
         mi = na.nanmin(image[~na.isinf(image)])
diff -r 8bc8433ed313 -r b775ab154834 yt/extensions/volume_rendering/image_handling.py
--- a/yt/extensions/volume_rendering/image_handling.py	Wed May 26 14:58:12 2010 -0700
+++ b/yt/extensions/volume_rendering/image_handling.py	Wed May 26 16:35:37 2010 -0700
@@ -30,19 +30,12 @@
 try: import pyfits
 except: pass
 
-'''
-export_rgba:
-args: 
-image - rgba numpy array of dimension NxNx4 
-fn - file basename for exported files
-
-kwargs:
-h5 [True]: Use hdf5 to export the rgba channels, creates fn.h5 file.
-fits [False]: Export to fits format (requires pyfits), creates fn_[r,g,b,a].fits files
-
-output: None
-'''
 def export_rgba(image, fn, h5=True, fits=False, ):
+    """
+    This function accepts an *image*, of shape (N,M,4) corresponding to r,g,b,a,
+    and saves to *fn*.  If *h5* is True, then it will save in hdf5 format.  If
+    *fits* is True, it will save in fits format.
+    """
     if h5:
         f = h5py.File('%s.h5'%fn, "w")
         f.create_dataset("R", data=image[:,:,0])
@@ -66,18 +59,12 @@
             hdulist.writeto('%s_a.fits'%fn,clobber=True)
         except: print 'You do not have pyfits, install before attempting to use fits exporter'
 
-'''
-import_rgba:
-args: 
-name of hdf5 file containing R,G,B,A arrays
-
-kwargs:
-h5 [True]: Use hdf5 to input the rgba channels.
-
-returns: 
-a Numpy array of shape NxNx4
-'''
 def import_rgba(name, h5=True):
+    """
+    This function will read back in an HDF5 file, as saved by export_rgba, and
+    return the frames to the user.  *name* is the name of the file to be read
+    in.
+    """
     if h5:
         f = h5py.File(name, "r")
         r = f['R'].value
@@ -88,29 +75,18 @@
         print 'No support for fits import.'
     return na.array([r,g,b,a]).swapaxes(0,2).swapaxes(0,1)
 
-'''
-plot_channel:
-args: 
-image - single channel of an image, of shape NxN
-name - prefix for image output 
-
-kwargs:
-cmap ['gist_stern'] - name of colormap to use
-log [True] - use a log scale
-dex [3] - Scale the image between image.max()/10**dex and image.max()
-zero_factor [1.0e-10] - Set all zero values to zero_factor
-label [None] - Label in upper left corner of image
-label_color ['w'] - Color of label
-label_size ['large'] - Size of label
-
-returns: 
-None
-
-output:
-name_cmap.png
-'''
 def plot_channel(image, name, cmap='gist_heat', log=True, dex=3, zero_factor=1.0e-10, 
                  label=None, label_color='w', label_size='large'):
+    """
+    This function will plot a single channel. *image* is an array shaped like
+    (N,M), *name* is the pefix for the output filename.  *cmap* is the name of
+    the colormap to apply, *log* is whether or not the channel should be
+    logged.  Additionally, you may optionally specify the minimum-value cutoff
+    for scaling as *dex*, which is taken with respect to the minimum value of
+    the image.  *zero_factor* applies a minimum value to all zero-valued
+    elements.  Optionally, *label*, *label_color* and *label_size* may be
+    specified.
+    """
     Nvec = image.shape[0]
     image[na.isnan(image)] = 0.0
     ma = image[image>0.0].max()
@@ -132,24 +108,13 @@
     pylab.savefig("%s_%s.png" % (name,cmap))
     pylab.clf()
 
-'''
-plot_rgb:
-args: 
-image - rgb channels of an image, of shape NxNx3 or NxNx4.  Values must be normalized from 0.0-1.0
-name - prefix for image output 
-
-kwargs:
-label [None] - Label in upper left corner of image
-label_color ['w'] - Color of label
-label_size ['large'] - Size of label
-
-returns: 
-None
-
-output:
-name_rgb.png
-'''
 def plot_rgb(image, name, label=None, label_color='w', label_size='large'):
+    """
+    This will plot the r,g,b channels of an *image* of shape (N,M,3) or
+    (N,M,4).  *name* is the prefix of the file name, which will be supplemented
+    with "_rgb.png."  *label*, *label_color* and *label_size* may also be
+    specified.
+    """
     Nvec = image.shape[0]
     image[na.isnan(image)] = 0.0
     if image.shape[2] >= 4:



More information about the yt-svn mailing list