Exemplo n.º 1
0
 def _get_colour_range(self, min_value, max_value, config_heading):
     """Get the colour range for the chosen config heading,
     or revert back to the default one if it is invalid.
     """
     try:
         colour_map = calculate_colour_map(
             CONFIG[config_heading]['ColourProfile'])
     except ValueError:
         colour_map = calculate_colour_map(
             CONFIG[config_heading]['ColourProfile'].default)
     return ColourRange(min_value, max_value, colour_map)
Exemplo n.º 2
0
 def clicks(self, last_session=False, click_type='Single', _cache_file=None):
     """Generate the click image."""
     self._generate_start()
     
     #Attempt to load data from cache
     cache_data = self.cache_load(_cache_file)
     if cache_data is not None:
         (min_value, max_value), heatmap = cache_data
     skip_calculations = cache_data is not None
     
     if not skip_calculations:
     
         #Detect session information
         if last_session:
             clicks = self.data['Maps']['Session']['Click'][click_type]
         else:
             clicks = self.data['Maps']['Click'][click_type]
     
         lmb = CONFIG['GenerateHeatmap']['_MouseButtonLeft']
         mmb = CONFIG['GenerateHeatmap']['_MouseButtonMiddle']
         rmb = CONFIG['GenerateHeatmap']['_MouseButtonRight']
         valid_buttons = [i for i, v in zip(('Left', 'Middle', 'Right'), (lmb, mmb, rmb)) if v]
         
         numpy_arrays = merge_resolutions(clicks, map_selection=valid_buttons)[1]
         
         width, height = CONFIG['GenerateImages']['_UpscaleResolutionX'], CONFIG['GenerateImages']['_UpscaleResolutionY']
         (min_value, max_value), heatmap = arrays_to_heatmap(numpy_arrays,
                     gaussian_size=gaussian_size(width, height),
                     clip=1-CONFIG['Advanced']['HeatmapRangeClipping'])
     
     #Save cache if it wasn't generated
     if _cache_file is not None and not skip_calculations:
         self.cache_save(_cache_file, min_value, max_value, heatmap)
         
     #Convert each point to an RGB tuple
     try:
         colour_map = calculate_colour_map(CONFIG['GenerateHeatmap']['ColourProfile'])
     except ValueError:
         default_colours = _config_defaults['GenerateHeatmap']['ColourProfile'][0]
         colour_map = calculate_colour_map(default_colours)
     colour_range = ColourRange(min_value, max_value, colour_map)
     
     image_name = self.name.generate('Clicks', reload=True)
     image_output = Image.fromarray(convert_to_rgb(heatmap, colour_range))
     
     if image_output is None:
         _print('No click data was found.')
         return None
         
     return self._generate_end(image_name, image_output, resize=True)
Exemplo n.º 3
0
    def tracks(self, last_session=False, _cache_file=None):
        """Generate the track image."""
        self._generate_start()

        #Attempt to load data from cache
        cache_data = self.cache_load(_cache_file)
        if cache_data is not None:
            (min_value, max_value), numpy_arrays = cache_data
        skip_calculations = cache_data is not None

        if not skip_calculations:

            #Detect session information
            if last_session:
                session_start = self.data['Ticks']['Session']['Tracks']
            else:
                session_start = None

            #Resize all arrays
            high_precision = CONFIG['GenerateImages']['HighPrecision']
            (min_value, max_value), numpy_arrays = merge_resolutions(
                self.data['Maps']['Tracks'],
                session_start=session_start,
                high_precision=high_precision)

        #Save cache if it wasn't generated
        if _cache_file is not None and not skip_calculations:
            self.cache_save(_cache_file, min_value, max_value, numpy_arrays)

        #Convert each point to an RGB tuple
        try:
            colour_map = calculate_colour_map(
                CONFIG['GenerateTracks']['ColourProfile'])
        except ValueError:
            default_colours = _config_defaults['GenerateTracks'][
                'ColourProfile'][0]
            colour_map = calculate_colour_map(default_colours)
        colour_range = ColourRange(min_value, max_value, colour_map)

        image_name = self.name.generate('Tracks', reload=True)
        image_output = arrays_to_colour(colour_range, numpy_arrays)
        if image_output is None:
            _print('No tracks data was found.')
            return None

        return self._generate_end(image_name, image_output, resize=True)
Exemplo n.º 4
0
    def generate_coordinates(self, key_names={}):
        image = {'Fill': {}, 'Outline': [], 'Text': []}
        max_offset = {'X': 0, 'Y': 0}

        if CONFIG['GenerateKeyboard']['LinearMapping']:
            if CONFIG['GenerateKeyboard']['LinearPower'] != 1:
                mapping = 'exponential'
            else:
                mapping = 'linear'
        else:
            mapping = 'standard'

        use_time = CONFIG['GenerateKeyboard']['DataSet'].lower() == 'time'
        use_count = CONFIG['GenerateKeyboard']['DataSet'].lower() == 'count'

        #Setup the colour range
        if use_time:
            values = self.count_time.values()
        elif use_count:
            values = self.count_press.values()

        if mapping == 'standard':
            pools = sorted(set(values))
            max_range = len(pools) + 1
            lookup = {v: i + 1 for i, v in enumerate(pools)}
            lookup[0] = 0
        else:
            max_range = max(values)
            if mapping == 'exponential':
                exponential = CONFIG['GenerateKeyboard']['LinearPower']
                max_range **= exponential

        colours = calculate_colour_map(
            CONFIG['GenerateKeyboard']['ColourProfile'])
        colour_range = ColourRange(0, max_range, colours)

        #Decide on background colour
        #For now the options are black or while
        if any(i > 128 for i in colours[0][:3]):
            image['Background'] = self.colours['white']['Colour']
            image['Shadow'] = self.colours['black']['Colour']
        else:
            image['Background'] = self.colours['black']['Colour']
            image['Shadow'] = self.colours['white']['Colour']

        y_offset = IMAGE_PADDING
        y_current = 0
        for i, row in enumerate(self.grid):
            x_offset = IMAGE_PADDING

            for values in row:

                x, y = values['Dimensions']
                hide_background = False

                if values['Name'] is not None:
                    count_time = self.count_time.get(values['Name'], 0)
                    count_press = self.count_press.get(values['Name'], 0)
                    if use_time:
                        key_count = count_time
                    elif use_count:
                        key_count = count_press
                    display_name = key_names.get(values['Name'],
                                                 values['Name'])

                    button_coordinates = KeyboardButton(
                        x_offset, y_offset, x, y)

                    #Calculate colour for key
                    if values['CustomColour'] is None:
                        if mapping == 'standard':
                            fill_colour = colour_range[lookup[key_count]]
                        elif mapping == 'exponential':
                            fill_colour = colour_range[key_count**exponential]
                        else:
                            fill_colour = colour_range[key_count]
                    else:
                        if values['CustomColour'] == False:
                            hide_background = True
                            fill_colour = image['Background']
                        else:
                            fill_colour = values['CustomColour']

                    #Calculate colour for border
                    if get_luminance(*fill_colour) > 128:
                        text_colour = self.colours['black']['Colour']
                    else:
                        text_colour = self.colours['white']['Colour']

                    #Store values
                    _values = {
                        'Offset': (x_offset, y_offset),
                        'KeyName': display_name,
                        'Counts': {
                            'press': count_press,
                            'time': count_time
                        },
                        'Colour': text_colour,
                        'Dimensions': values['DimensionMultipliers']
                    }
                    image['Text'].append(_values)

                    if not values['HideBorder']:
                        image['Outline'] += button_coordinates.outline(
                            KEY_BORDER)
                    if not hide_background:
                        try:
                            image['Fill'][
                                fill_colour] += button_coordinates.fill()
                        except KeyError:
                            image['Fill'][
                                fill_colour] = button_coordinates.fill()

                x_offset += KEY_PADDING + x
                y_current = max(y_current, y)

            #Decrease size of empty row
            if row:
                y_offset += KEY_SIZE + KEY_PADDING
            else:
                y_offset += (KEY_SIZE + KEY_PADDING) // 2

            max_offset['X'] = max(max_offset['X'], x_offset)
            max_offset['Y'] = max(max_offset['Y'], y_offset)
            y_current -= KEY_SIZE

        width = max_offset['X'] + IMAGE_PADDING - KEY_PADDING + 1
        height = max_offset[
            'Y'] + IMAGE_PADDING + y_current - KEY_PADDING * 2 + 1 + DROP_SHADOW_Y
        return ((width, height), image)