Beispiel #1
0
def build_config(args: argparse.Namespace) -> m.Image:
    """Turn CLI arguments into a configuration argument."""
    layers = []
    for noise in args.noise:
        name, args_, loc, filters, blend = noise.split('_')
        layer = m.Layer(
            **{
                'source': _build_source(name, args_),
                'blend': _build_blend(blend),
                'blend_amount': _build_blend_amount(blend),
                'location': _build_location(loc),
                'filters': _build_filters(filters),
                'mask': None,
                'mask_filters': [],
            })
        layers.append(layer)
    if len(layers) == 1:
        layers = layers[0]

    return m.Image(
        **{
            'source': layers,
            'size': [int(n) for n in args.size[::-1]],
            'filename': args.filename,
            'format': get_format(args.filename),
            'mode': args.mode,
            'framerate': args.framerate,
        })
Beispiel #2
0
def load_conf(filename: str,
              args: Union[None, 'argparse.Namespace'] = None) -> m.Image:
    """Load a configuration file."""
    # Get the configuration from the file.
    with open(filename, 'r') as fh:
        conf_json = fh.read()
    conf = json.loads(conf_json)

    # Deserialize configuration based on the given version.
    if (conf['Version'] == '0.2.0' or conf['Version'] == '0.3.0'
            or conf['Version'] == '0.3.1'):
        # Allow CLI arguments to change or override values in the
        # loaded config.
        if args and args.filename:
            conf['Image']['filename'] = args.filename
            conf['Image']['format'] = get_format(args.filename)
        if args and args.size:
            conf['Image']['size'] = args.size[::-1]
        if args and args.location:
            _update_location(conf['Image'], args.location[::-1])

        # Deserialize and return the configuration object.
        return m.Image(**conf['Image'])

    # Otherwise, the version isn't recognized, so throw an error.
    else:
        raise ValueError(f'Version {conf["Version"]} not supported.')
Beispiel #3
0
    def test_serialize_config_to_json_file(self):
        """Given a configuration object, serialize that object to
        file as JSON.
        """
        # Set up for expected data.
        format = 'JPEG'
        filename = 'spam.json'
        framerate = None
        imagefile = 'spam.jpeg'
        location = [0, 0, 0]
        mode = 'RGB'
        size = [1, 1280, 720]
        conf = m.Image(**{
            'source': m.Layer(**{
                'source': s.Spot(**{
                    'radius': 128,
                    'ease': 'l',
                }),
                'location': location,
                'filters': [],
                'mask': None,
                'mask_filters': [],
                'blend': op.difference,
                'blend_amount': 1.0,
            }),
            'size': size,
            'filename': imagefile,
            'format': format,
            'mode': mode,
            'framerate': None
        })
        serialized_conf = {
            'Version': __version__,
            'Image': conf.asdict()
        }

        # Expected values.
        exp_json = json.dumps(serialized_conf, indent=4)
        exp_args = (filename, 'w')

        # Set up test data and state.
        open_mock = mock_open()
        with patch('pjinoise.io.open', open_mock, create=True):

            # Run test.
            io.save_conf(conf)

        # Extract actual values.
        act_json = open_mock.return_value.write.call_args[0][0]

        # Determine if test passed.
        self.assertEqual(exp_json, act_json)
        open_mock.assert_called_with(*exp_args)
Beispiel #4
0
    def test_load_config_from_json_file(self):
        """Given the path of a configuration serialized as JSON,
        deserialize and return that configuration.
        """
        # Set up for expected data.
        format = 'JPEG'
        filename = 'spam.json'
        framerate = None
        imagefile = 'spam.jpeg'
        location = [0, 0, 0]
        mode = 'RGB'
        size = [1, 1280, 720]

        # Expected data.
        exp_conf = m.Image(**{
            'source': m.Layer(**{
                'source': s.Spot(**{
                    'radius': 128,
                    'ease': 'l',
                }),
                'location': location,
                'filters': [],
                'mask': None,
                'mask_filters': [],
                'blend': op.difference,
                'blend_amount': 1.0,
            }),
            'size': size,
            'filename': imagefile,
            'format': format,
            'mode': mode,
            'framerate': None
        })
        exp_args = (filename, 'r')

        # Set up test data and state.
        conf = {
            'Version': '0.2.0',
            'Image': exp_conf.asdict(),
        }
        text = json.dumps(conf)
        open_mock = mock_open()
        with patch('pjinoise.io.open', open_mock, create=True):
            open_mock.return_value.read.return_value = text

            # Run test.
            act_conf = io.load_conf(filename)

        # Determine if test passed.
        self.assertEqual(exp_conf, act_conf)
        open_mock.assert_called_with(*exp_args)
Beispiel #5
0
    def test_load_config_cli_override_filename(self):
        """If a filename was passed to the CLI, override the filename
        in the loaded config with that filename.
        """
        # Expected value.
        exp = 'eggs.tiff'
        exp_format = 'TIFF'

        # Build test data and state.
        filename = 'spam.conf'
        args = _get_cli_args_mock()
        type(args).filename = PropertyMock(return_value=exp)
        type(args).load_config = PropertyMock(return_value=filename)
        image = m.Image(**{
            'source': m.Layer(**{
                'source': s.Spot(**{
                    'radius': 128,
                    'ease': 'l',
                }),
                'location': [0, 0, 0],
                'filters': [],
                'mask': None,
                'mask_filters': [],
                'blend': op.difference,
                'blend_amount': 1.0,
            }),
            'size': [1, 1280, 720],
            'filename': 'spam.jpeg',
            'format': 'JPEG',
            'mode': 'RGB',
            'framerate': None
        })
        conf = json.dumps({
            'Version': __version__,
            'Image': image.asdict()
        })
        open_mock = mock_open()
        with patch('pjinoise.io.open', open_mock, create=True):
            open_mock.return_value.read.return_value = conf

            # Run test.
            result = io.load_conf(filename, args)

        # Extract actual values from result.
        act = result.filename
        act_format = result.format

        # Determine if test passed.
        self.assertEqual(exp, act)
        self.assertEqual(exp_format, act_format)
Beispiel #6
0
assert __version__ == '0.3.1'

# Basic image file configuration and other commonly used values.
filename = 'work.jpg'
filetype = 'JPEG'
colorspace = 'RGB'
size = (1, 720, 1280)

# Layers.
layer = m.Layer(
    **{
        'source': None,
        'blend': None,
        'filters': [],
        'mask': None,
        'mask_filters': [],
    })

# Image.
conf = m.Image(
    **{
        'source': layer,
        'size': size,
        'filename': filename,
        'format': filetype,
        'mode': colorspace,
    })

# Create image.
pn.main(False, conf)
Beispiel #7
0
    def test_load_config_cli_override_location(self):
        """If an image location was passed to the CLI, offset the
        locations in the loaded config with that location.
        """
        # Expected value.
        exp = [10, 10, 10]

        # Build test data and state.
        filename = 'spam.conf'
        location = [4, 5, 6]
        offset = [6, 5, 4]
        args = _get_cli_args_mock()
        type(args).location = PropertyMock(return_value=offset[::-1])
        type(args).load_config = PropertyMock(return_value=filename)
        image = m.Image(**{
            'source': m.Layer(**{
                'source': [
                    m.Layer(**{
                        'source': s.Spot(**{
                            'radius': 128,
                            'ease': 'l',
                        }),
                        'location': location,
                        'filters': [],
                        'mask': None,
                        'mask_filters': [],
                        'blend': op.replace,
                        'blend_amount': 1.0,
                    }),
                    m.Layer(**{
                        'source': s.Spot(**{
                            'radius': 128,
                            'ease': 'l',
                        }),
                        'location': location,
                        'filters': [],
                        'mask': None,
                        'mask_filters': [],
                        'blend': op.difference,
                        'blend_amount': 1.0,
                    }),
                ],
                'location': location,
                'filters': [],
                'mask': None,
                'mask_filters': [],
                'blend': op.replace,
                'blend_amount': 1.0,
            }),
            'size': [1, 1280, 720],
            'filename': 'spam.jpeg',
            'format': 'JPEG',
            'mode': 'RGB',
            'framerate': None
        })
        conf = json.dumps({
            'Version': __version__,
            'Image': image.asdict()
        })
        open_mock = mock_open()
        with patch('pjinoise.io.open', open_mock, create=True):
            open_mock.return_value.read.return_value = conf

            # Run test.
            result = io.load_conf(filename, args)

        # Extract actual values from result.
        def find_location(item):
            result = []
            if 'location' in vars(item):
                result.append(item.location)
            if '_source' in vars(item):
                if isinstance(item._source, Sequence):
                    for obj in item._source:
                        result.extend(find_location(obj))
                else:
                    result.extend(find_location(item._source))
            return result
        acts = find_location(result)
        for act in acts:

            # Determine if test passed.
            self.assertListEqual(exp, act)
Beispiel #8
0
def main(seed=None, origin=(0, 0, 0), solve=False, save_dir='', unit=20):
    # Make sure the version of pjinoise supports mazer.
    assert __version__ == '0.3.1'

    # Set up the size and structure of the maze.
    size = (1, 720, 560)
    units = (1, unit, unit)
    exit_size = (1, int(unit * .8), unit)
    title = seed.replace('_', ' ').upper()

    # The maze interior.
    path = m.Layer(
        **{
            'filters': [],
            'source': s.Path(width=.4, origin=origin, unit=units, seed=seed),
            'blend': op.replace,
        })

    # The solution.
    sol = m.Layer(
        **{
            'source': s.Solid(1),
            'filters': [
                f.Color('s'),
            ],
            'mask': s.SolvedPath(
                width=.1, origin=origin, unit=units, seed=seed),
            'blend': op.replace,
        })

    # The maze entrance.
    entrance = m.Layer(
        **{
            'source': s.Box((0, int(unit * .6), 0), exit_size, 1.0),
            'blend': op.lighter,
        })

    # The maze exit.
    exit = m.Layer(
        **{
            'source':
            s.Box(*[(0, int(size[Y] - unit * 1.4),
                     size[X] - unit), exit_size, 1.0]),
            'blend':
            op.lighter,
        })

    if unit >= 16:
        ft_origin = (int(unit * .6), 1)
        ft_size = int(unit * .5)
        title = m.Layer(
            **{
                'source':
                s.Text(title,
                       size=ft_size,
                       origin=ft_origin,
                       font='Helvetica',
                       face=1),
                'blend':
                op.lighter,
            })

    # Put it all together and you get the maze.
    layers = [
        path,
        entrance,
        exit,
    ]
    if unit >= 16:
        layers.append(title)
    if solve:
        layers.append(sol)
    maze = m.Layer(**{
        'source': layers,
        'blend': op.replace,
    })

    # Image output configuration.
    mode = 'L'
    name = f'{save_dir}maze_{seed}_{origin}'
    if unit != 20:
        name = name + f'_{unit}'
    if solve:
        mode = 'RGB'
        name = name + '_solved'
    name = f'{name}.png'
    conf = m.Image(
        **{
            'source': maze,
            'size': size,
            'filename': name,
            'format': 'PNG',
            'mode': mode,
        })

    # Create image.
    pn.main(False, conf)
Beispiel #9
0
    def test_count_sources(self):
        """Given a configuration object, count the number of sources
        used in the configuration. This is used to display progress
        in the UI.
        """
        # Expected values.
        exp = 3

        # Set up test data and state.
        src = Source()
        conf = m.Image(
            **{
                'source': [
                    m.Layer(
                        **{
                            'source': Source(),
                            'blend': op.replace,
                            'blend_amount': 1,
                            'location': [0, 0, 0],
                            'filters': [],
                            'mask': None,
                            'mask_filters': []
                        }),
                    m.Layer(
                        **{
                            'source': [
                                m.Layer(
                                    **{
                                        'source': Source(),
                                        'blend': op.difference,
                                        'blend_amount': 1,
                                        'location': [0, 0, 0],
                                        'filters': [],
                                        'mask': None,
                                        'mask_filters': []
                                    }),
                                m.Layer(
                                    **{
                                        'source': Source(),
                                        'blend': op.difference,
                                        'blend_amount': 1,
                                        'location': [0, 0, 0],
                                        'filters': [],
                                        'mask': None,
                                        'mask_filters': []
                                    }),
                            ],
                            'blend':
                            op.difference,
                            'blend_amount':
                            1,
                            'location': [0, 0, 0],
                            'filters': [],
                            'mask':
                            None,
                            'mask_filters': []
                        }),
                ],
                'size':
                src.size,
                'filename':
                'spam.jpg',
                'format':
                'JPEG',
                'mode':
                'RGB',
                'framerate':
                None,
            })

        # Run test.
        act = conf.count_sources()

        # Determine if test passed.
        self.assertEqual(exp, act)
Beispiel #10
0
    def test_create_single_layer_image(self):
        """Given the proper CLI options, cli.build_config should
        return the config as a model.Image object.
        """
        # Back up initial state.
        argv_bkp = sys.argv
        try:

            # Set up data for expected values.
            format = 'JPEG'
            filename = 'spam.json'
            framerate = None
            imagefile = 'spam.jpeg'
            location = [5, 0, 0]
            mode = 'L'
            size = [1, 1280, 720]

            # Expected values.
            exp = m.Image(
                **{
                    'source':
                    m.Layer(
                        **{
                            'source': s.Spot(**{
                                'radius': 128,
                                'ease': 'l',
                            }),
                            'location': location,
                            'filters': [
                                f.BoxBlur(5),
                                f.Skew(.1),
                            ],
                            'mask': None,
                            'mask_filters': [],
                            'blend': op.difference,
                            'blend_amount': .5,
                        }),
                    'size':
                    size,
                    'filename':
                    imagefile,
                    'format':
                    format,
                    'mode':
                    mode,
                    'framerate':
                    None
                })

            # Set up test data and state.
            sys.argv = [
                'python3.8 -m pjinoise.pjinoise',
                '-s',
                str(size[-1]),
                str(size[-2]),
                str(size[-3]),
                '-n',
                'spot_128:l_0:0:5_boxblur:5+skew:.1_difference:.5',
                '-o',
                imagefile,
                '-m',
                mode,
            ]

            # Run tests.
            args = cli.parse_cli_args()
            act = cli.build_config(args)

            # Determine if test passed.
            try:
                self.assertEqual(exp, act)
            except AssertionError as e:
                exp = exp.asdict()
                act = act.asdict()
                result = map_compare(exp, act)
                if result is not True:
                    msg = f'Path to bad key(s): {result}'
                    raise ValueError(msg)
                else:
                    raise e

        # Restore initial state.
        finally:
            sys.argv = argv_bkp