Skip to content

Conversation

@Twice22
Copy link

@Twice22 Twice22 commented Jan 10, 2020

When creating a PSD file from numpy arrays. According to the documentation we should use the -2 index to precise the user_mask (a.k.a the raster mask in Photoshop).
For example. Let's say I want to create a RGB image with Alpha channel fully opaque and with a gradient on the raster mask. Here is what I will do:

        channels = {}
	channels[-2] = (255 * np.tile(np.linspace(0, 1, 600), [500, 1])).astype(np.uint8)  # Raster mask
	channels[-1] = 255 * np.ones((500, 600), dtype=np.uint8)  # Alpha
	channels[0] = np.zeros((500, 600), dtype=np.uint8)  # Red
	channels[1] = 255 * np.ones((500, 600), dtype=np.uint8)  # Green
	channels[2] = np.zeros((500, 600), dtype=np.uint8)  # Blue

	over = nested_layers.Image(
	        name="overlay_image", visible=True, opacity=255, group_id=0,
	        blend_mode=enums.BlendMode.normal, top=0, left=0, channels=channels,
	        metadata=None, layer_color=0, color_mode=3)

For example let's create a group containing 2 layers:

  • bottom layer: Red layer
  • upper layer: Green layer with gradient on the raster mask
	from pytoshop.user import nested_layers
	from pytoshop import enums
	import numpy as np

	# channels for the bottom layer (RGBA) with full red and alpha fully opaque
	channels = {
		0: 255 * np.ones((500, 600), dtype=np.uint8),
		1: np.zeros((500, 600), dtype=np.uint8),
		2: np.zeros((500, 600), dtype=np.uint8),
		-1: 255 * np.ones((500, 600), dtype=np.uint8)
	}

        # color_mode=3 specifies RGB color
	base = nested_layers.Image(
		name="base_image", visible=True, opacity=255, group_id=0,
		blend_mode=enums.BlendMode.normal, top=0, left=0, channels=channels,
		metadata=None, layer_color=0, color_mode=3)


        # upper layer with RGBA + gradient on the raster mask
        channels = {}
	channels[-2] = (255 * np.tile(np.linspace(0, 1, 600), [500, 1])).astype(np.uint8)  # Raster mask
	channels[-1] = 255 * np.ones((500, 600), dtype=np.uint8)  # Alpha
	channels[0] = np.ones((500, 600), dtype=np.uint8)  # Red
	channels[1] = 255 * np.ones((500, 600), dtype=np.uint8)  # Green
	channels[2] = np.ones((500, 600), dtype=np.uint8)  # Blue

	over = nested_layers.Image(
		name="overlay_image", visible=True, opacity=255, group_id=0,
		blend_mode=enums.BlendMode.normal, top=0, left=0, channels=channels,
		metadata=None, layer_color=0, color_mode=3)

        # group the `base` and the `over` layers
	group = nested_layers.Group(
		name="overlay", visible=True, opacity=255,
		group_id=0, blend_mode=enums.BlendMode.normal, layers=[over, base], closed=True,
		metadata=None, layer_color=0
	)

	with open('my_output.psd', 'wb') as fd:
		output = nested_layers.nested_layers_to_psd([group], color_mode=3)
		output.write(fd)

This, will, unfortunately not work with the current version of pytoshop as the mask of the layer containing the raster mask will have bottom=0 and right=0. To fix this issue we need to precise both the right and the bottom when creating the LayerMask from the LayerRecord object instance.

This Pull Request fix this issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant