def test_execute_script_and_return_json_with_script_that_takes_multiple_files_using_for_each(): with TempFile('.xcf') as with_white, TempFile('.xcf') as without_white: GimpFile(with_white) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8) * 255) GimpFile(without_white) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('Black', np.zeros(shape=(1, 1), dtype=np.uint8)) collection = GimpFileCollection([with_white, without_white]) script = textwrap.dedent( """ from pgimp.gimp.file import for_each_file from pgimp.gimp.parameter import return_json, get_json matches = [] def layer_matches(image, file): for layer in image.layers: if layer.name == '{0:s}': matches.append(file) for_each_file(layer_matches) return_json(matches) """ ) files = collection.execute_script_and_return_json(script.format(escape_single_quotes('White')), timeout_in_seconds=3) assert len(files) == 1 assert with_white == files[0]
def test_create_from_template(): with TempFile('.xcf') as original, TempFile('.xcf') as created: original_file = GimpFile(original).create( 'Background', np.zeros(shape=(3, 2), dtype=np.uint8)) created_file = GimpFile(created).create_from_template(original_file) assert [] == created_file.layer_names() assert (2, 3) == created_file.dimensions()
def test_execute_script_and_return_json_with_script_that_takes_single_file(): with TempFile('.xcf') as with_white, TempFile('.xcf') as without_white: GimpFile(with_white)\ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8))\ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8)*255) GimpFile(without_white) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('Black', np.zeros(shape=(1, 1), dtype=np.uint8)) collection = GimpFileCollection([with_white, without_white]) script = textwrap.dedent( """ from pgimp.gimp.file import open_xcf from pgimp.gimp.parameter import return_json image = open_xcf('__file__') for layer in image.layers: if layer.name == '{0:s}': return_json(True) return_json(False) """ ) files = collection.execute_script_and_return_json(script.format(escape_single_quotes('White')), timeout_in_seconds=3) assert { with_white: True, without_white: False, } == files
def test_find_files_by_script_with_script_that_takes_multiple_files(): with TempFile('.xcf') as with_white, TempFile('.xcf') as without_white: GimpFile(with_white)\ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8))\ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8)*255) GimpFile(without_white) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('Black', np.zeros(shape=(1, 1), dtype=np.uint8)) collection = GimpFileCollection([with_white, without_white]) script = textwrap.dedent( """ import gimp from pgimp.gimp.file import XcfFile from pgimp.gimp.parameter import return_json, get_json files = get_json('__files__') matches = [] for file in files: with XcfFile(file) as image: for layer in image.layers: if layer.name == '{0:s}': matches.append(file) return_json(matches) """ ) files = collection.find_files_by_script(script.format(escape_single_quotes('White')), timeout_in_seconds=3) assert len(files) == 1 assert with_white == files[0] files = collection.find_files_by_script(script.format(escape_single_quotes('Not existing')), timeout_in_seconds=3) assert len(files) == 0
def test_add_layers_from_numpy(): with TempFile('.xcf') as f: gimp_file = GimpFile(f).create('Background', np.zeros(shape=(1, 2), dtype=np.uint8)) gimp_file.add_layers_from_numpy( ['Layer 1', 'Layer 2'], np.ones(shape=(2, 1, 2), dtype=np.uint8) * 255, opacity=55., visible=False, position='Background') assert gimp_file.layer_names() == ['Layer 1', 'Layer 2', 'Background']
def test_add_layers_from_numpy_with_list_config(): with TempFile('.xcf') as f: gimp_file = GimpFile(f).create('Background', np.zeros(shape=(1, 2), dtype=np.uint8)) gimp_file.add_layers_from_numpy( ['Layer 1', 'Layer 2'], np.ones(shape=(2, 1, 2), dtype=np.uint8) * 255, opacity=[100., 55.], visible=[False, True], position='Background', blend_mode=gimpenums.NORMAL_MODE) assert gimp_file.layer_names() == ['Layer 1', 'Layer 2', 'Background']
def test_create(): filename = file.relative_to(__file__, 'test-resources/test-create.xcf') layer_bg = np.array([ [[255, 255, 255], [0, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) gimp_file = GimpFile(filename) gimp_file.create('Background', layer_bg) exists = os.path.exists(filename) actual = gimp_file.layer_to_numpy('Background') os.remove(filename) assert exists assert np.all(layer_bg == actual)
def test_add_layer_from_numpy(): tmp_file = tempfile.mktemp(suffix='.xcf') layer_bg = np.array([ [[255, 255, 255], [0, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) layer_fg = np.array([ [[255, 255, 255], [255, 255, 255], [255, 255, 255]], [[255, 255, 255], [0, 0, 0], [255, 255, 255]], ], dtype=np.uint8) gimp_file = GimpFile(tmp_file) gimp_file.create('Background', layer_bg) gimp_file.add_layer_from_numpy('Foreground', layer_fg, opacity=55., visible=False) actual_bg = gimp_file.layer_to_numpy('Background') actual_fg = gimp_file.layer_to_numpy('Foreground') os.remove(tmp_file) assert np.all(layer_bg == actual_bg) assert np.all(layer_fg == actual_fg)
def test_layers_to_numpy(): use_temp_file_values = [True, False] for use_temp_file in use_temp_file_values: with TempFile('.xcf') as f: gimp_file = GimpFile(f) \ .create('Red', np.zeros(shape=(1, 2, 3), dtype=np.uint8)) \ .add_layer_from_numpy('Green', np.ones(shape=(1, 2, 3), dtype=np.uint8) * 127) \ .add_layer_from_numpy('Blue', np.ones(shape=(1, 2, 3), dtype=np.uint8) * 255) np_array = gimp_file.layers_to_numpy(['Red', 'Green', 'Blue'], use_temp_file=use_temp_file) assert (1, 2, 9) == np_array.shape assert np.all( np.array([ [[0, 0, 0, 127, 127, 127, 255, 255, 255], [0, 0, 0, 127, 127, 127, 255, 255, 255]], ], dtype=np.uint8) == np_array)
def test_find_files_containing_layer_by_name(): with TempFile('.xcf') as with_white, TempFile('.xcf') as without_white: GimpFile(with_white)\ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8))\ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8)*255) GimpFile(without_white) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('Black', np.zeros(shape=(1, 1), dtype=np.uint8)) collection = GimpFileCollection([with_white, without_white]) files = collection.find_files_containing_layer_by_name('White', timeout_in_seconds=10) assert len(files) == 1 assert with_white == files[0] files = collection.find_files_containing_layer_by_name('Not existing', timeout_in_seconds=10) assert len(files) == 0
def test_add_layer_from_numpy_with_position_layer_name(): data = np.array([[[255, 255, 255]]], dtype=np.uint8) with TempFile('.xcf') as tmp_file: gimp_file = GimpFile(tmp_file) gimp_file.create('Background', data) gimp_file.add_layer_from_numpy('Layer 1', data, position='Background') gimp_file.add_layer_from_numpy('Layer 2', data, position='Background') assert gimp_file.layer_names() == ['Layer 1', 'Layer 2', 'Background']
def test_find_files_containing_layer_by_predictate(): with TempFile('.xcf') as with_white, TempFile('.xcf') as without_white: GimpFile(with_white)\ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8))\ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8)*255) GimpFile(without_white) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('Black', np.zeros(shape=(1, 1), dtype=np.uint8)) collection = GimpFileCollection([with_white, without_white]) files = collection.find_files_containing_layer_by_predictate( lambda layers: 'White' in map(lambda layer: layer.name, layers) ) assert len(files) == 1 assert with_white == files[0] files = collection.find_files_containing_layer_by_predictate( lambda layers: 'Not existing' in map(lambda layer: layer.name, layers) ) assert len(files) == 0
def test_merge_mask_layer_from_with_mask_not_available_in_files_in_both_collections_and_foreground_color_black(): with TemporaryDirectory('_src') as srcdir, TemporaryDirectory('_dst') as dstdir: src_1 = GimpFile(os.path.join(srcdir, 'file1.xcf')) \ .create_empty(2, 1, GimpFileType.GRAY) dst_1 = GimpFile(os.path.join(dstdir, 'file1.xcf')) \ .create_empty(2, 1, GimpFileType.GRAY) src_collection = GimpFileCollection([src_1.get_file()]) dst_collection = GimpFileCollection([dst_1.get_file()]) dst_collection.merge_mask_layer_from(src_collection, 'Mask', MaskForegroundColor.BLACK, timeout_in_seconds=10) assert np.all(dst_1.layer_to_numpy('Mask') == [[255], [255]]) assert ['Mask'] == dst_1.layer_names()
def test_export(): with TempFile('.xcf') as xcf, TempFile('.png') as png, TempFile( '.jpg') as jpg, TempFile('.xcf') as from_png: gimp_file = GimpFile(xcf) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('Foreground', np.ones(shape=(1, 1), dtype=np.uint8) * 255, opacity=50.) \ gimp_file.export( png ) # saved as grayscale with alpha (identify -format '%[channels]' FILE) gimp_file.export(jpg) assert np.all([127, 255] == GimpFile(from_png).create_from_file( png, layer_name='Image').layer_to_numpy('Image')) assert np.all([127] == GimpFile(from_png).create_from_file( jpg, layer_name='Image').layer_to_numpy('Image'))
def test_copy(): with TempFile('.xcf') as original, TempFile('.xcf') as copy: original_file = GimpFile(original).create( 'Background', np.zeros(shape=(2, 2), dtype=np.uint8)) copied_file = original_file.copy(copy) original_file.add_layer_from_numpy( 'New', np.zeros(shape=(2, 2), dtype=np.uint8)) assert ['Background'] == copied_file.layer_names() assert ['New', 'Background'] == original_file.layer_names()
def test_remove_layers_by_name(): data = np.array([[0, 255]], dtype=np.uint8) with TemporaryDirectory('_files') as dir: file1 = GimpFile(os.path.join(dir, 'file1.xcf')) \ .create('Background', data) \ .add_layer_from_numpy('Layer 1', data) \ .add_layer_from_numpy('Layer 2', data) \ .add_layer_from_numpy('Layer 3', data) file2 = GimpFile(os.path.join(dir, 'file2.xcf')) \ .create('Background', data) \ .add_layer_from_numpy('Layer 1', data) \ .add_layer_from_numpy('Layer 2', data) collection = GimpFileCollection([file1.get_file(), file2.get_file()]) collection.remove_layers_by_name(['Layer 1', 'Layer 3'], timeout_in_seconds=10) assert file1.layer_names() == ['Layer 2', 'Background'] assert file2.layer_names() == ['Layer 2', 'Background']
def test_convert_to_indexed_using_predefined_colormap(): tmp_file = tempfile.mktemp(suffix='.xcf') values = np.array([[i for i in range(0, 256)]], dtype=np.uint8) assert (1, 256) == values.shape gimp_file = GimpFile(tmp_file) gimp_file.create_indexed('Background', values, ColorMap.JET) gimp_file.add_layer_from_numpy('Values', values, type=LayerType.INDEXED) layer_bg = gimp_file.layer_to_numpy('Background') layer_values = gimp_file.layer_to_numpy('Values') os.remove(tmp_file) assert (1, 256, 1) == layer_bg.shape assert np.all(values == layer_bg[:, :, 0]) assert (1, 256, 1) == layer_values.shape assert np.all(values == layer_values[:, :, 0])
def test_merge_layer_from_file_with_cleared_selection(): src = file.relative_to(__file__, 'test-resources/selection.xcf') with TempFile('.xcf') as dst: src_file = GimpFile(src) dst_file = GimpFile(dst) dst_file.create('Background', np.zeros(shape=(3, 3, 3), dtype=np.uint8)) dst_file.merge_layer_from_file(src_file, 'Background') new_layer_contents = dst_file.layer_to_numpy('Background') assert np.all( np.array([ [[255, 255, 255], [255, 255, 255], [255, 255, 255]], [[255, 0, 0], [255, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) == new_layer_contents)
def test_merge_mask_layer_from_with_color(): with TemporaryDirectory('_src') as srcdir, TemporaryDirectory('_dst') as dstdir: src_1 = GimpFile(os.path.join(srcdir, 'file1.xcf'))\ .create('Mask', np.array([[[255, 255, 255], [0, 0, 0]]], dtype=np.uint8)) dst_1 = GimpFile(os.path.join(dstdir, 'file1.xcf')) \ .create('Mask', np.array([[[0, 0, 0], [255, 255, 255]]], dtype=np.uint8)) dst_2 = GimpFile(os.path.join(dstdir, 'file2.xcf')) \ .create('Mask', np.array([[[0, 0, 0], [255, 255, 255]]], dtype=np.uint8)) src_collection = GimpFileCollection([src_1.get_file()]) dst_collection = GimpFileCollection([dst_1.get_file(), dst_2.get_file()]) dst_collection.merge_mask_layer_from(src_collection, 'Mask', MaskForegroundColor.WHITE, timeout_in_seconds=10) assert np.all(dst_1.layer_to_numpy('Mask') == [[255, 255, 255], [255, 255, 255]]) assert ['Mask'] == dst_1.layer_names() assert 'Mask' in dst_2.layer_names() assert np.all(dst_2.layer_to_numpy('Mask') == [[0, 0, 0], [255, 255, 255]]) assert ['Mask'] == dst_2.layer_names()
def test_create_empty(): with TempFile('.xcf') as f: gimp_file = GimpFile(f).create_empty(3, 2, GimpFileType.RGB) assert (3, 2) == gimp_file.dimensions() assert [] == gimp_file.layer_names()
# Copyright 2018 Mathias Burger <*****@*****.**> # # SPDX-License-Identifier: MIT import os import tempfile import numpy as np from pytest import approx import gimpenums from pgimp.GimpFile import GimpFile, LayerType, ColorMap, GimpFileType from pgimp.util import file from pgimp.util.TempFile import TempFile rgb_file = GimpFile(file.relative_to(__file__, 'test-resources/rgb.xcf')) """ The file rgb.xcf contains a 3x2 image with white 'Background' layer and 'Red', 'Green', 'Blue' layers with differing opacity. The layer 'Background' contains a black pixel at y=0, x=1, the others pixels are white. """ def test_layer_to_numpy(): actual = rgb_file.layer_to_numpy('Background') expected = np.array([ [[255, 255, 255], [0, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) assert np.all(expected == actual)
def test_merge_layer_from_file(): with TempFile('.xcf') as dst, TempFile('.xcf') as src: layer_bg = np.array([ [[255, 255, 255], [0, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) src_file = GimpFile(src) src_file.create('Background', np.zeros(shape=(2, 3, 3), dtype=np.uint8)) src_file.add_layer_from_numpy( 'Yellow', np.array([ [[240, 255, 0], [240, 255, 0], [240, 255, 0]], [[240, 255, 0], [240, 255, 0], [240, 255, 0]], ], dtype=np.uint8)) dst_file = GimpFile(dst) dst_file.create('Yellow', layer_bg) dst_file.merge_layer_from_file(src_file, 'Yellow') new_layer_contents = dst_file.layer_to_numpy('Yellow') assert np.all([240, 255, 0] == new_layer_contents)
def test_add_layer_from_file(): with TempFile('.xcf') as dst, TempFile('.xcf') as src: layer_bg = np.array([ [[255, 255, 255], [0, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) position = 1 src_file = GimpFile(src) src_file.create('Background', np.zeros(shape=(2, 3, 3), dtype=np.uint8)) src_file.add_layer_from_numpy( 'Yellow', np.array([ [[240, 255, 0], [240, 255, 0], [240, 255, 0]], [[240, 255, 0], [240, 255, 0], [240, 255, 0]], ], dtype=np.uint8)) dst_file = GimpFile(dst) dst_file.create('Background', layer_bg) dst_file.add_layer_from_file(src_file, 'Yellow', new_name='Yellow (copied)', new_position=position) assert 'Yellow (copied)' == dst_file.layers()[position].name assert np.all( [240, 255, 0] == dst_file.layer_to_numpy('Yellow (copied)'))
import os import numpy as np from pgimp.GimpFile import GimpFile from pgimp.util import file from pgimp.util.TempFile import TempFile if __name__ == '__main__': img_path = file.relative_to(__file__, '../../../doc/source/_static/img') png_file = os.path.join(img_path, 'sphere.png') # generate sphere data x = np.arange(-1, 1, 0.01) y = np.arange(-1, 1, 0.01) xx, yy = np.meshgrid(x, y, sparse=True) z = np.sin(xx**2 + yy**2) # generate rgb image data img = np.zeros(shape=(200, 200, 3), dtype=np.uint8) img[:, :, 0] = (1 - z) * 255 # create temporary gimp file an export to png with TempFile('.xcf') as tmp: GimpFile(tmp).create('Background', img).export(png_file)
def test_copy_layer_from(): with TemporaryDirectory('_src') as srcdir, TemporaryDirectory('_dst') as dstdir: src_1 = GimpFile(os.path.join(srcdir, 'file1.xcf'))\ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8))\ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8)*255) src_2 = GimpFile(os.path.join(srcdir, 'file2.xcf'))\ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('White', np.ones(shape=(1, 1), dtype=np.uint8)*255) dst_1 = GimpFile(os.path.join(dstdir, 'file1.xcf')) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) \ .add_layer_from_numpy('White', np.zeros(shape=(1, 1), dtype=np.uint8)*255) dst_2 = GimpFile(os.path.join(dstdir, 'file2.xcf')) \ .create('Background', np.zeros(shape=(1, 1), dtype=np.uint8)) src_collection = GimpFileCollection([src_1.get_file(), src_2.get_file()]) dst_collection = GimpFileCollection([dst_1.get_file(), dst_2.get_file()]) dst_collection.copy_layer_from(src_collection, 'White', layer_position=1, timeout_in_seconds=10) assert np.all(dst_1.layer_to_numpy('White') == 255) assert ['Background', 'White'] == dst_1.layer_names() assert 'White' in dst_2.layer_names() assert np.all(dst_2.layer_to_numpy('White') == 255) assert ['Background', 'White'] == dst_2.layer_names()
def test_remove_layer(): tmp_file = tempfile.mktemp(suffix='.xcf') layer = np.array([ [[255, 255, 255], [0, 0, 0], [255, 255, 255]], [[255, 255, 255], [255, 255, 255], [255, 255, 255]], ], dtype=np.uint8) gimp_file = GimpFile(tmp_file) gimp_file.create('Background', layer) gimp_file.add_layer_from_numpy('Layer', layer) all_layers = gimp_file.layer_names() gimp_file.remove_layer('Background') remaining_layers1 = gimp_file.layer_names() gimp_file.remove_layer('Layer') remaining_layers2 = gimp_file.layer_names() os.remove(tmp_file) assert ['Layer', 'Background'] == all_layers assert ['Layer'] == remaining_layers1 assert [] == remaining_layers2
def __init__(self, files: List[str], gimp_file_factory=lambda file: GimpFile(file)) -> None: super().__init__() self._files = files self._gimp_file_factory = gimp_file_factory self._gsr = GimpScriptRunner()
img_path = file.relative_to(__file__, '../../../doc/source/_static/img') png_file = os.path.join(img_path, 'mask_applied.png') height = 100 width = 200 # layer content bg = np.zeros(shape=(height, width), dtype=np.uint8) fg = np.ones(shape=(height, width), dtype=np.uint8) * 255 mask = np.zeros(shape=(height, width), dtype=np.uint8) mask[:, width//4:3*width//4+1] = 255 with TempFile('.xcf') as xcf, TempFile('.npz') as npz: # create gimp file gimp_file = GimpFile(xcf) \ .create('Background', bg) \ .add_layer_from_numpy('Foreground', fg) \ .add_layer_from_numpy('Mask', mask) # save layer data to numpy arrays arr_bg = gimp_file.layer_to_numpy('Background') arr_fg = gimp_file.layer_to_numpy('Foreground') arr_mask = gimp_file.layer_to_numpy('Mask') # save data as npz np.savez_compressed(npz, bg=arr_bg, fg=arr_fg, mask=arr_mask) # load data from npz loaded = np.load(npz) loaded_bg = loaded['bg'] loaded_fg = loaded['fg'] loaded_mask = loaded['mask']