示例#1
0
def test_colour_at():
    """
    Get a colour at a point
    """
    from painterm.image import Image

    image = Image.new_image(2, 1)

    # out-of-bounds colours
    for x, y in ((0, 1), (-1, 0), (2, 0), (0, -1)):
        with assert_raises(AssertionError):
            image.colour_at(x, y)

    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 0), BACKGROUND)

    colour = Colour(0, 1, 2, 0.5)
    image.draw(1, 0, colour)

    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)

    colour2 = Colour(5, 4, 3, 0.2)
    image.draw(0, 0, colour2)
    image.draw(1, 0, colour2)

    assert_equals(image.colour_at(0, 0), colour2)
    assert_equals(image.colour_at(1, 0), colour2)

    redrawn = Image.new_image(1, 1)
    redrawn.draw(0, 0, BACKGROUND)
    redrawn.draw(0, 0, colour, continue_transaction=True)
    redrawn.draw(0, 0, colour2, continue_transaction=True)

    assert_equals(redrawn.colour_at(0, 0), colour2)
示例#2
0
def test_load_image():
    """
    Load an existing image
    """
    from painterm.image import Image

    # file-based:
    with TemporaryDirectory() as name:
        path = Path(name) / 'named'

        Image.new_image(9, 7, path)

        image = Image.load(path)

        assert_equals(image.width, 9)
        assert_equals(image.height, 7)
        assert_is_none(image.copyright)
        assert_is_none(image.description)

        cursor = image._cursor

        cursor.execute('SELECT major, minor, micro, width, height FROM meta;')
        assert_equals(cursor.fetchall(), [(0, 1, 0, 9, 7)])

        cursor.execute('SELECT id, time FROM transactions;')
        assert_equals(cursor.fetchall(), [(0, 0)])

        cursor.execute(
            'SELECT transaction_id, x, y, red, green, blue, alpha FROM draws;'
        )
        assert_equals(
            frozenset(cursor),
            {(0, x, y, *BACKGROUND) for x in range(9) for y in range(7)}
        )
示例#3
0
def test_export_bitmap():
    """
    Export to a BMP
    """
    from painterm.image import Image

    base = Path(__file__).absolute().parent
    expected = base / 'sample_image.bmp'

    points = {
        (1, 1), (1, 2), (2, 1), (2, 2), (5, 1), (5, 2), (6, 1), (6, 2),
        (6, 5), (6, 6), (5, 6), (4, 6), (3, 6)
    }

    yellow = Colour(234, 236, 35, 1.0)
    black = Colour(0, 0, 0, 1.0)

    image = Image.new_image(8, 8, background=yellow)

    for x, y in points:
        image.draw(x, y, black)

    with TemporaryDirectory() as name:
        actual = Path(name) / 'actual.bmp'

        image.export_bitmap(actual)
        assert_equals(actual.read_bytes(), expected.read_bytes())

        # magnification
        for magnification in (3.3, -1, 0):
            with assert_raises(AssertionError):
                image.export_bitmap(actual, magnification=magnification)

    with TemporaryDirectory() as name:
        actual = Path(name)

        image = Image.new_image(2, 2, background=yellow)
        image.draw(0, 0, black)
        image.draw(1, 1, black)
        image.export_bitmap(actual / '4x.bmp', magnification=4)
        assert_equals(
            (actual / '4x.bmp').read_bytes(),
            (base / '4x.bmp').read_bytes())

        image = Image.new_image(4, 4, background=yellow)
        image.draw(0, 0, black)
        image.draw(1, 1, black)
        image.export_bitmap(actual / '2x.bmp', magnification=2)
        assert_equals(
            (actual / '2x.bmp').read_bytes(),
            (base / '2x.bmp').read_bytes()
        )
示例#4
0
    def fillable():
        """
        Return the fillable image
        """
        image = Image.new_image(4, 3,)

        image.draw(0, 1, colour)
        image.draw(1, 0, colour)
        image.draw(1, 2, colour)
        image.draw(3, 0, colour)
        image.draw(3, 2, colour)

        return image
示例#5
0
def test_copyright():
    """
    Copyrights?
    """
    from painterm.image import Image

    image = Image.new_image(1, 1)

    assert_is_none(image.copyright)

    image.set_copyright('©️2015 bcj')

    assert_equals(image.copyright, '©️2015 bcj')
示例#6
0
def test_description():
    """
    described?
    """
    from painterm.image import Image

    image = Image.new_image(1, 1)
    image.draw(0, 0, Colour(128, 197, 221, 1.0))

    assert_is_none(image.description)

    image.set_description('A minimal Sagan')

    assert_equals(image.description, 'A minimal Sagan')
示例#7
0
def test_resize():
    """
    Resize an image
    """
    from painterm.image import Image

    image = Image.new_image(1, 1)

    colour1 = Colour(255, 0, 0, 1)
    colour2 = Colour(0, 255, 0, 1)

    image.draw(0, 0, colour1)

    image.resize(2, 2)

    assert_equals(image.width, 2)
    assert_equals(image.height, 2)
    assert_equals(image.colour_at(0, 0), colour1)
    assert_equals(image.colour_at(0, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 1), BACKGROUND)

    image.fill(1, 1, colour2)
    image.draw(0, 1, colour1)
    image.draw(1, 0, colour1)

    image.resize(1, 2)

    assert_equals(image.width, 1)
    assert_equals(image.height, 2)
    assert_equals(image.colour_at(0, 0), colour1)
    assert_equals(image.colour_at(0, 1), colour1)

    # emptry transaction should be gone. next undo should remove
    # draw(0, 1)
    image.undo()

    assert_equals(image.width, 1)
    assert_equals(image.height, 2)
    assert_equals(image.colour_at(0, 0), colour1)
    assert_equals(image.colour_at(0, 1), colour2)

    image.resize(2, 1)

    assert_equals(image.width, 2)
    assert_equals(image.height, 1)
    assert_equals(image.colour_at(0, 0), colour1)
    assert_equals(image.colour_at(1, 0), BACKGROUND)
示例#8
0
def test_export_pxon():
    """
    Export to PXON
    """
    from painterm.image import Image, PXON_VERSION

    points = {
        (1, 1), (1, 2), (2, 1), (2, 2), (5, 1), (5, 2), (6, 1), (6, 2),
        (6, 5), (6, 6), (5, 6), (4, 6), (3, 6)
    }

    yellow = Colour(234, 236, 35, 1.0)
    black = Colour(0, 0, 0, 1.0)

    image = Image.new_image(8, 8)

    for x, y in points:
        image.draw(x, y, black)

    image.fill(0, 0, yellow)

    with TemporaryDirectory() as name:
        actual = Path(name) / 'actual.pxon'

        image.export_pxon(actual, size=1)

        with actual.open() as stream:
            pxon = json.load(stream)

            assert_equals(pxon.keys(), {'exif', 'pxif', 'version'})

            assert_equals(tuple(pxon['version']), PXON_VERSION)

            exif = pxon['exif']
            assert_equals(
                exif.keys(),
                {'software', 'dateTime', 'height', 'width'}
            )
            assert_equals(exif['software'], 'painterm')
            assert_equals(exif['dateTime'], image.creation_date)
            assert_equals(exif['height'], image.height)
            assert_equals(exif['width'], image.width)

            pxif = pxon['pxif']
            assert_equals(pxif.keys(), {'pixels'})
示例#9
0
def test_authors():
    """
    who wrote this?
    """
    from painterm.image import Image

    image = Image.new_image(1, 1)

    assert_equals(image.authors, frozenset())

    image.add_authors()
    assert_equals(image.authors, frozenset())

    image.add_authors('bcj')
    assert_equals(image.authors, {'bcj'})

    image.add_authors('someone', 'else')
    assert_equals(image.authors, {'bcj', 'someone', 'else'})
示例#10
0
文件: cli.py 项目: bcj/painterm
def main():
    """
    Run painterm from the command line.
    """
    parser = ArgumentParser(description="A curses-based pixel art tool")
    sub = parser.add_subparsers(help="functions")

    new = sub.add_parser('new', help="Create a new image")
    new.set_defaults(function='new')

    new.add_argument(
        'path',
        type=lambda raw: Path(raw).expanduser().absolute(),
        help="The location to save to"
    )
    new.add_argument(
        '--width', '-x',
        default=DEFAULT_WIDTH,
        type=int,
        help="The width of the new image."
    )
    new.add_argument(
        '--height', '-y',
        default=DEFAULT_HEIGHT,
        type=int,
        help="The height of the new image."
    )
    new.add_argument(
        '--platform',
        default=None,
        type=lambda name: Platform[name.lower()],
        help="The palette to use ({})".format(
            ', '.join(Platform.__members__.keys())
        )
    )

    load = sub.add_parser('load', help="Load an existing image")
    load.set_defaults(function='load')

    load.add_argument(
        'path',
        type=lambda raw: Path(raw).expanduser().absolute(),
        help="The location to load from to"
    )

    load.add_argument(
        '--platform',
        default=None,
        type=lambda name: Platform[name.lower()],
        help="The palette to use ({})".format(
            ', '.join(Platform.__members__.keys())
        )
    )

    bmp = sub.add_parser('bmp', help="Export image to a bitmap file")
    bmp.set_defaults(function='bmp')

    bmp.add_argument(
        'input',
        type=lambda raw: Path(raw).expanduser().absolute(),
        help="The location of the image"
    )

    bmp.add_argument(
        'output',
        type=lambda raw: Path(raw).expanduser().absolute(),
        help="The location to save the bitmap"
    )

    bmp.add_argument(
        '--magnification', '-m',
        default=1,
        type=int,
        help="How much to magnify the bitmap"
    )

    pxon = sub.add_parser('pxon', help="Export image to a PXON file")
    pxon.set_defaults(function='pxon')

    pxon.add_argument(
        'input',
        type=lambda raw: Path(raw).expanduser().absolute(),
        help="The location of the image"
    )

    pxon.add_argument(
        'output',
        type=lambda raw: Path(raw).expanduser().absolute(),
        help="The location to save the PXON file"
    )

    pxon.add_argument(
        '--size', '-s',
        default=PXON_SIZE,
        type=int,
        help="How large each pixel should be"
    )

    args = parser.parse_args()

    if not hasattr(args, 'function'):
        print('run painterm --help to see options')
        return

    if args.function == 'new':
        palette = get_palette(args.platform)

        image = Image.new_image(
            args.width, args.height, path=args.path,
        )
    elif args.function == 'load':
        palette = get_palette(args.platform)

        image = Image.load(args.path)
    elif args.function == 'bmp':
        Image.load(args.input).export_bitmap(
            args.output, magnification=args.magnification
        )
        return
    elif args.function == 'pxon':
        Image.load(args.input).export_pxon(
            args.output, size=args.size
        )
        return

    curses.wrapper(
        painterm,
        image=image,
        palette=palette,
    )
示例#11
0
def test_undo_redo():
    """
    Undo/Redo
    """
    from painterm.image import Image

    image = Image.new_image(1, 1, background=Colour(0, 0, 0, 0))

    def get_committed():
        """
        get committed transactions
        """
        return {
            transaction_id for (transaction_id,) in
            image._cursor.execute(
                'SELECT id FROM transactions WHERE time IS NOT NULL;'
            )
        }

    def get_uncommitted():
        """
        get uncommitted transactions
        """
        return {
            transaction_id for (transaction_id,) in
            image._cursor.execute(
                'SELECT id FROM transactions WHERE time IS NULL;'
            )
        }

    def get_draws():
        """
        get uncommitted transactions
        """
        results = image._cursor.execute(
            'SELECT transaction_id, red, green, blue, alpha FROM draws;'
        ).fetchall()
        return {
            transaction_id
            if all(transaction_id == channel for channel in channels[:3]) else
            (transaction_id, Colour(*channels))
            for transaction_id, *channels in results
        }

    # undo/redo shouldn't effect a new image
    image.undo()

    assert_equals(get_committed(), {0})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0})
    assert_equals(image.colour_at(0, 0), Colour(0, 0, 0, 0))

    image.redo()

    assert_equals(get_committed(), {0})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0})
    assert_equals(image.colour_at(0, 0), Colour(0, 0, 0, 0))

    # redo should do nothing if at latest
    image.draw(0, 0, Colour(1, 1, 1, 1))

    assert_equals(get_committed(), {0, 1})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0, 1})
    assert_equals(image.colour_at(0, 0), Colour(1, 1, 1, 1))

    image.redo()

    assert_equals(get_committed(), {0, 1})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0, 1})
    assert_equals(image.colour_at(0, 0), Colour(1, 1, 1, 1))

    # undo shouldn't happen more than once
    for _ in range(5):
        image.undo()

        assert_equals(get_committed(), {0})
        assert_equals(get_uncommitted(), {1})
        assert_equals(get_draws(), {0, 1})
        assert_equals(image.colour_at(0, 0), Colour(0, 0, 0, 0))

    image.redo()

    assert_equals(get_committed(), {0, 1})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0, 1})
    assert_equals(image.colour_at(0, 0), Colour(1, 1, 1, 1))

    # multiple layars
    image.draw(0, 0, Colour(2, 2, 2, 0.2))

    assert_equals(get_committed(), {0, 1, 2})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0, 1, 2})
    assert_equals(image.colour_at(0, 0), Colour(2, 2, 2, 0.2))

    image.undo()
    image.undo()

    assert_equals(get_committed(), {0})
    assert_equals(get_uncommitted(), {1, 2})
    assert_equals(get_draws(), {0, 1, 2})
    assert_equals(image.colour_at(0, 0), Colour(0, 0, 0, 0))

    image.redo()

    assert_equals(get_committed(), {0, 1})
    assert_equals(get_uncommitted(), {2})
    assert_equals(get_draws(), {0, 1, 2})
    assert_equals(image.colour_at(0, 0), Colour(1, 1, 1, 1))

    # remove redo on overwrite
    image.undo()
    image.draw(0, 0, BACKGROUND)

    assert_equals(get_committed(), {0, 3})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0, (3, Colour(255, 255, 255, 0))})
    assert_equals(image.colour_at(0, 0), BACKGROUND)

    image.redo()

    assert_equals(get_committed(), {0, 3})
    assert_equals(get_uncommitted(), set())
    assert_equals(get_draws(), {0, (3, Colour(255, 255, 255, 0))})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
示例#12
0
def test_fill():
    """
    Flood fill a pixel
    """
    from painterm.image import Image

    image = Image.new_image(2, 1)
    cursor = image._cursor

    colour = Colour(0, 1, 2, 0.34)

    # out-of-bounds colours
    for x, y in ((0, 1), (-1, 0), (2, 0), (0, -1)):
        with assert_raises(AssertionError):
            image.fill(x, y, colour)

    for bad_colour in ((1, 2, 3), (2, 1, 0, -1)):
        with assert_raises(AssertionError):
            image.fill(0, 0, bad_colour)

    assert_equals(
        cursor.execute('SELECT COUNT(1) FROM transactions;').fetchone(), (1,)
    )

    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 0), BACKGROUND)

    assert_equals(image.fill(1, 0, colour), {(0, 0), (1, 0)})

    assert_equals(
        cursor.execute('SELECT COUNT(1) FROM transactions;').fetchone(), (2,)
    )
    assert_equals(
        cursor.execute(
            'SELECT id FROM transactions ORDER BY time DESC;'
        ).fetchall(),
        [(1,), (0,)]
    )

    # Did it colour?
    results = cursor.execute(
        'SELECT x, y, red, green, blue, alpha FROM draws '
        'WHERE transaction_id = ?;',
        (1,)
    ).fetchall()

    assert_equals(len(results), 2)
    for _, y, *actual_colour in results:
        assert_equals(y, 0)
        assert_equals(Colour(*actual_colour), colour)

    assert_equals(image.colour_at(0, 0), colour)
    assert_equals(image.colour_at(1, 0), colour)

    colour2 = Colour(5, 4, 3, 0.21)
    image.draw(0, 0, BACKGROUND)
    image.fill(1, 0, colour2, continue_transaction=True)

    assert_equals(
        cursor.execute('SELECT COUNT(1) FROM transactions;').fetchone(), (3,)
    )
    assert_equals(
        cursor.execute(
            'SELECT id FROM transactions ORDER BY time DESC;'
        ).fetchall(),
        [(2,), (1,), (0,)]
    )

    # Did it colour?
    results = cursor.execute(
        'SELECT x, y, red, green, blue, alpha FROM draws '
        'WHERE transaction_id = ?;',
        (2,)
    ).fetchall()

    assert_equals(len(results), 2)

    for x, y, *actual_colour in results:
        assert_equals(y, 0)

        if x == 0:
            assert_equals(Colour(*actual_colour), BACKGROUND)
        elif x == 1:
            assert_equals(Colour(*actual_colour), colour2)
        else:
            raise AssertionError

    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour2)

    # full fill test
    def fillable():
        """
        Return the fillable image
        """
        image = Image.new_image(4, 3,)

        image.draw(0, 1, colour)
        image.draw(1, 0, colour)
        image.draw(1, 2, colour)
        image.draw(3, 0, colour)
        image.draw(3, 2, colour)

        return image

    # really test that filling works correctly
    image = fillable()
    assert_equals(image.fill(0, 0, colour2), {(0, 0)})
    assert_equals(image.colour_at(0, 0), colour2)
    assert_equals(image.colour_at(0, 1), colour)
    assert_equals(image.colour_at(0, 2), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour)

    image = fillable()
    assert_equals(image.fill(0, 1, colour2), {(0, 1)})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(0, 1), colour2)
    assert_equals(image.colour_at(0, 2), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour)

    image = fillable()
    assert_equals(image.fill(0, 2, colour2), {(0, 2)})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(0, 1), colour)
    assert_equals(image.colour_at(0, 2), colour2)
    assert_equals(image.colour_at(1, 0), colour)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour)

    image = fillable()
    assert_equals(image.fill(1, 0, colour2), {(1, 0)})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(0, 1), colour)
    assert_equals(image.colour_at(0, 2), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour2)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour)

    image = fillable()
    assert_equals(image.fill(1, 2, colour2), {(1, 2)})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(0, 1), colour)
    assert_equals(image.colour_at(0, 2), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour2)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour)

    image = fillable()
    assert_equals(image.fill(3, 0, colour2), {(3, 0)})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(0, 1), colour)
    assert_equals(image.colour_at(0, 2), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour2)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour)

    image = fillable()
    assert_equals(image.fill(3, 2, colour2), {(3, 2)})
    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(0, 1), colour)
    assert_equals(image.colour_at(0, 2), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)
    assert_equals(image.colour_at(1, 1), BACKGROUND)
    assert_equals(image.colour_at(1, 2), colour)
    assert_equals(image.colour_at(2, 0), BACKGROUND)
    assert_equals(image.colour_at(2, 1), BACKGROUND)
    assert_equals(image.colour_at(2, 2), BACKGROUND)
    assert_equals(image.colour_at(3, 0), colour)
    assert_equals(image.colour_at(3, 1), BACKGROUND)
    assert_equals(image.colour_at(3, 2), colour2)

    fill_group = {(1, 1), (2, 0), (2, 1), (2, 2), (3, 1)}
    for x, y in fill_group:
        image = fillable()
        assert_equals(image.fill(x, y, colour2), fill_group)
        assert_equals(image.colour_at(0, 0), BACKGROUND)
        assert_equals(image.colour_at(0, 1), colour)
        assert_equals(image.colour_at(0, 2), BACKGROUND)
        assert_equals(image.colour_at(1, 0), colour)
        assert_equals(image.colour_at(1, 1), colour2)
        assert_equals(image.colour_at(1, 2), colour)
        assert_equals(image.colour_at(2, 0), colour2)
        assert_equals(image.colour_at(2, 1), colour2)
        assert_equals(image.colour_at(2, 2), colour2)
        assert_equals(image.colour_at(3, 0), colour)
        assert_equals(image.colour_at(3, 1), colour2)
        assert_equals(image.colour_at(3, 2), colour)
示例#13
0
def test_draw():
    """
    Draw a pixel
    """
    from painterm.image import Image

    image = Image.new_image(2, 1)
    cursor = image._cursor

    colour = Colour(0, 1, 2, 1.0)

    # out-of-bounds colours
    for x, y in ((0, 1), (-1, 0), (2, 0), (0, -1)):
        with assert_raises(AssertionError):
            image.draw(x, y, colour)

    for bad_colour in ((1, 2, 3), (2, 1, 0, -1)):
        with assert_raises(AssertionError):
            image.draw(0, 0, bad_colour)

    assert_equals(
        cursor.execute('SELECT COUNT(1) FROM transactions;').fetchone(), (1,)
    )

    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 0), BACKGROUND)

    image.draw(1, 0, colour)

    assert_equals(
        cursor.execute('SELECT COUNT(1) FROM transactions;').fetchone(), (2,)
    )
    assert_equals(
        cursor.execute(
            'SELECT id FROM transactions ORDER BY time DESC;'
        ).fetchall(),
        [(1,), (0,)]
    )

    # Did it colour?
    results = cursor.execute(
        'SELECT x, y, red, green, blue, alpha FROM draws '
        'WHERE transaction_id = ?;',
        (1,)
    ).fetchall()

    assert_equals(len(results), 1)
    x, y, *actual_colour = results[0]

    assert_equals(x, 1)
    assert_equals(y, 0)
    assert_equals(Colour(*actual_colour), colour)

    assert_equals(image.colour_at(0, 0), BACKGROUND)
    assert_equals(image.colour_at(1, 0), colour)

    colour2 = Colour(5, 4, 3, 0.21)
    image.draw(0, 0, colour2)
    image.draw(1, 0, colour2, continue_transaction=True)

    assert_equals(
        cursor.execute('SELECT COUNT(1) FROM transactions;').fetchone(), (3,)
    )
    assert_equals(
        cursor.execute(
            'SELECT id FROM transactions ORDER BY time DESC;'
        ).fetchall(),
        [(2,), (1,), (0,)]
    )

    # Did it colour?
    results = cursor.execute(
        'SELECT x, y, red, green, blue, alpha FROM draws '
        'WHERE transaction_id = ?;',
        (2,)
    ).fetchall()

    assert_equals(len(results), 2)

    for _, y, *actual_colour in results:
        assert_equals(y, 0)
        assert_equals(Colour(*actual_colour), colour2)

    assert_equals(image.colour_at(0, 0), colour2)
    assert_equals(image.colour_at(1, 0), colour2)
示例#14
0
def test_new_image():
    """
    Create a new image
    """
    from painterm.image import Image

    # bad width, height
    for width, height in ((5.5, 5), (-3, 5), (5, '5'), (5, 0)):
        with assert_raises(AssertionError):
            Image.new_image(width, height)

    # in memory
    image = Image.new_image(10, 5)

    cursor = image._cursor

    cursor.execute(
        'SELECT major, minor, micro, width, height, '
        'copyright, description FROM meta;'
    )
    assert_equals(cursor.fetchall(), [(0, 1, 0, 10, 5, None, None)])

    cursor.execute('SELECT id, time FROM transactions;')
    assert_equals(cursor.fetchall(), [(0, 0)])

    cursor.execute('SELECT name FROM authors;')
    assert_equals(cursor.fetchall(), [])

    cursor.execute(
        'SELECT transaction_id, x, y, red, green, blue, alpha FROM draws;'
    )
    assert_equals(
        frozenset(cursor),
        {(0, x, y, *BACKGROUND) for x in range(10) for y in range(5)}
    )

    # with optional args
    background = Colour(1, 2, 3, 1.0)

    image = Image.new_image(3, 4, background=background)

    cursor = image._cursor

    cursor.execute('SELECT major, minor, micro, width, height FROM meta;')
    assert_equals(cursor.fetchall(), [(0, 1, 0, 3, 4)])

    cursor.execute('SELECT id, time FROM transactions;')
    assert_equals(cursor.fetchall(), [(0, 0)])

    cursor.execute(
        'SELECT transaction_id, x, y, red, green, blue, alpha FROM draws;'
    )
    assert_equals(
        frozenset(cursor),
        {(0, x, y, *background) for x in range(3) for y in range(4)}
    )

    # file-based:
    with TemporaryDirectory() as name:
        path = Path(name) / 'named'

        image = Image.new_image(9, 7, path)

        cursor = sqlite3.connect(path.as_uri(), uri=True).cursor()

        cursor.execute('SELECT major, minor, micro, width, height FROM meta;')
        assert_equals(cursor.fetchall(), [(0, 1, 0, 9, 7)])

        cursor.execute('SELECT id, time FROM transactions;')
        assert_equals(cursor.fetchall(), [(0, 0)])

        cursor.execute(
            'SELECT transaction_id, x, y, red, green, blue, alpha FROM draws;'
        )
        assert_equals(
            frozenset(cursor),
            {(0, x, y, *BACKGROUND) for x in range(9) for y in range(7)}
        )

        # don't overwrite an existing file
        with assert_raises(IOError):
            image = Image.new_image(12, 13, path, background)

        cursor.execute('SELECT major, minor, micro, width, height FROM meta;')
        assert_equals(cursor.fetchall(), [(0, 1, 0, 9, 7)])

        cursor.execute('SELECT id, time FROM transactions;')
        assert_equals(cursor.fetchall(), [(0, 0)])

        cursor.execute(
            'SELECT transaction_id, x, y, red, green, blue, alpha FROM draws;'
        )
        assert_equals(
            frozenset(cursor),
            {(0, x, y, *BACKGROUND) for x in range(9) for y in range(7)}
        )