Source code for exports.png_kit

"""
Contains PngKit class
"""
import os
import sys
import logging
import array
import PIL

from lib.db.style.false_colour import make_false_colour_tup
from lib.exports.export_kit import ExportKit

[docs]class PngKit(ExportKit): ''' Class used to output PNG files, given geometry, style and metadata data structures ''' def __init__(self, debug_level): ''' Initialise class :param debug_level: debug level taken from python's 'logging' module ''' # Call parent class ExportKit.__init__(self, debug_level)
[docs] def write_single_voxel_png(self, geom_obj, style_obj, meta_obj, file_name): ''' Writes out a PNG file of the top layer of the voxel data :param geom_obj: MODEL_GEOMETRY object that holds voxel data :param style_obj: SYTLE object, contains colour map :param meta_obj: FILENAME object, contains object information :param file_name: filename of PNG file, without extension ''' self.logger.debug("write_single_voxel_png(%s)", file_name) colour_arr = array.array("B") z_val = geom_obj.vol_sz[2]-1 pixel_cnt = 0 # Volume data are RGBA, data is stored in geom_obj's xyz_data if geom_obj.vol_data_type == 'RGBA': self.logger.debug("Using in-situ RGBA data") # Use False to get data using IJK int indexes xyz_data = geom_obj.get_loose_3d_data(is_xyz=False) for x_val in range(0, geom_obj.vol_sz[0]): for y_val in range(0, geom_obj.vol_sz[1]): try: pixel_colour = xyz_data.get((x_val, y_val, z_val), (0, 0, 0, 0)) except ValueError: pixel_colour = (0, 0, 0, 0) colour_arr.fromlist(list(pixel_colour)) pixel_cnt += 1 # Volume data are floats, stored in geom_obj's vol_data else: colour_map = style_obj.get_colour_table() self.logger.debug("style_obj.get_colour_table() = %s", repr(colour_map)) self.logger.debug("geom_obj.get_min_data() = %s", repr(geom_obj.get_min_data())) self.logger.debug("geom_obj.get_max_data() = %s", repr(geom_obj.get_max_data())) # If colour table is provided within source file, use it if colour_map: self.logger.debug("Using style colour map") for x_val in range(0, geom_obj.vol_sz[0]): for y_val in range(0, geom_obj.vol_sz[1]): try: val = int(geom_obj.vol_data[x_val][y_val][z_val]) (r_val, g_val, b_val, a_val) = colour_map[val] pixel_colour = [int(r_val*255.0), int(g_val*255.0), int(b_val*255.0), int(a_val*255.0)] except ValueError: pixel_colour = [0, 0, 0, 0] colour_arr.fromlist(pixel_colour) pixel_cnt += 1 # Else use a false colour map else: self.logger.debug("Using false colour map") for x_val in range(0, geom_obj.vol_sz[0]): for y_val in range(0, geom_obj.vol_sz[1]): try: # pylint:disable=W0612 (r_val, g_val, b_val, a_val) = make_false_colour_tup( geom_obj.vol_data[x_val][y_val][z_val], geom_obj.get_min_data(), geom_obj.get_max_data()) pixel_colour = [int(r_val*255.0), int(g_val*255.0), int(b_val*255.0), int(a_val*255.0)] except ValueError: pixel_colour = [0, 0, 0, 0] colour_arr.fromlist(pixel_colour) pixel_cnt += 1 img = PIL.Image.frombytes('RGBA', (geom_obj.vol_sz[1], geom_obj.vol_sz[0]), colour_arr.tobytes()) self.logger.info("Writing PNG file: %s.PNG", file_name) try: img.save(file_name+".PNG") except OSError as os_exc: self.logger.error("ERROR - Cannot write file %s.PNG: %s", file_name, repr(os_exc)) return {} property_name = meta_obj.get_property_name() if property_name: label_str = property_name else: label_str = meta_obj.name popup_dict = {os.path.basename(file_name): {'title': label_str, 'name': label_str}} return popup_dict