{ "info": { "author": "Ye Joo Park", "author_email": "subwaymatch@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "

\n\n

\n\n# Layer.is\nA library that supports all blend modes in Photoshop, brightness, contrast, hue, saturation, lightness adjustments, and curve adjustments on separate RGB channels. \n\n## Why use Layer.is? \n\n- Supports all frequently used blend modes in Photoshop\n- Chain operations (like jQuery)\n- Straightforward API to manipulate images\n- Load sequence of operations from JSON\n- Can apply curve adjustment selectively to RGB channels\n\n## Requirements\nLayer.is requires Python 3.6 or higher. \n\n## Quick Start\n\n### Installation\nInstall layer-is from PyPI repository. \n```sh\n$ pip install layeris\n```\n\n### Load/Save an image\n\n#### Loading an image from file\n```python\nfrom layeris.layer_image import LayerImage\n\nimage = LayerImage.from_file('/path/to/your/image.jpg')\n```\n\n#### Loading an image from URL\n```python\nfrom layeris.layer_image import LayerImage\n\nimage = LayerImage.from_url('https://your-image-url')\n```\n\n#### Saving an image\n```python\nimage.save('output.jpg')\n```\n\nYou can also specify the image quality between 0 - 100 by passing in the optional `quality` parameter. By default, `quality` is set to 75. \n```python\nimage.save('output.jpg', 90)\n```\n\n\n### Basic operations\n\n#### Grayscale\n```python\nimage.grayscale()\n```\n![sample_grayscale](https://user-images.githubusercontent.com/1064036/66761386-e2fea380-eede-11e9-8c62-3ef88d6ee289.jpg)\n\n### Blend mode operations\n\nThe descriptions for each blend mode operation are copied from [https://helpx.adobe.com/photoshop/using/blending-modes.html](https://helpx.adobe.com/photoshop/using/blending-modes.html).\n\n#### Darken\nLooks at the color information in each channel and selects the base or blend color\u00e2\u20ac\u201dwhichever is darker\u00e2\u20ac\u201das the result color. Pixels lighter than the blend color are replaced, and pixels darker than the blend color do not change.\n```python\ngrayscale_image.darken('#3fe28f')\n```\n![sample_darken](https://user-images.githubusercontent.com/1064036/66762165-6b317880-eee0-11e9-960c-560d4f021aa2.jpg)\n\n#### Multiply\nLooks at the color information in each channel and multiplies the base color by the blend color. The result color is always a darker color. Multiplying any color with black produces black. Multiplying any color with white leaves the color unchanged. When you\u00e2\u20ac\u2122re painting with a color other than black or white, successive strokes with a painting tool produce progressively darker colors. The effect is similar to drawing on the image with multiple marking pens.\n```python\ngrayscale_image.multiply('#3fe28f')\n```\n![sample_multiply](https://user-images.githubusercontent.com/1064036/66762301-af247d80-eee0-11e9-928d-4fa4a826f167.jpg)\n\n#### Color Burn\nLooks at the color information in each channel and darkens the base color to reflect the blend color by increasing the contrast between the two. Blending with white produces no change.\n```python\ngrayscale_image.color_burn('#7fe3f8')\n```\n![sample_color_burn](https://user-images.githubusercontent.com/1064036/66762811-9f596900-eee1-11e9-961c-d673a6009a49.jpg)\n\n\n#### Linear Burn\nLooks at the color information in each channel and darkens the base color to reflect the blend color by decreasing the brightness. Blending with white produces no change.\n```python\ngrayscale_image.linear_burn('#e1a8ff')\n```\n![sample_linear_burn](https://user-images.githubusercontent.com/1064036/66762820-a2ecf000-eee1-11e9-95df-6625e2da712c.jpg)\n\n#### Lighten\nLooks at the color information in each channel and selects the base or blend color\u00e2\u20ac\u201dwhichever is lighter\u00e2\u20ac\u201das the result color. Pixels darker than the blend color are replaced, and pixels lighter than the blend color do not change.\n```python\nimage.lighten('#ff3ce1')\n```\n![sample_lighten](https://user-images.githubusercontent.com/1064036/66764586-117f7d00-eee5-11e9-96b6-e387e46d93e2.jpg)\n\n#### Screen\nLooks at each channel\u00e2\u20ac\u2122s color information and multiplies the inverse of the blend and base colors. The result color is always a lighter color. Screening with black leaves the color unchanged. Screening with white produces white. The effect is similar to projecting multiple photographic slides on top of each other.\n```python\nimage.screen('#e633ba')\n```\n![sample_screen](https://user-images.githubusercontent.com/1064036/66764718-59060900-eee5-11e9-9539-23428676b4de.jpg)\n\n#### Color Dodge\nLooks at the color information in each channel and brightens the base color to reflect the blend color by decreasing contrast between the two. Blending with black produces no change.\n```python\nimage.color_dodge('#490cc7')\n```\n![sample_color_dodge](https://user-images.githubusercontent.com/1064036/66764854-a7b3a300-eee5-11e9-968c-cff40b1ea524.jpg)\n\n#### Linear Dodge\nLooks at the color information in each channel and brightens the base color to reflect the blend color by increasing the brightness. Blending with black produces no change.\n```python\nimage.linear_dodge('#490cc7')\n```\n![sample_linear_dodge](https://user-images.githubusercontent.com/1064036/66764998-efd2c580-eee5-11e9-9795-f56976c639b2.jpg)\n\n#### Overlay\nMultiplies or screens the colors, depending on the base color. Patterns or colors overlay the existing pixels while preserving the highlights and shadows of the base color. The base color is not replaced, but mixed with the blend color to reflect the lightness or darkness of the original color.\n```python\nimage.overlay('#ffb956')\n```\n![sample_overlay](https://user-images.githubusercontent.com/1064036/66765248-78e9fc80-eee6-11e9-99ff-7b1df141ac40.jpg)\n\n#### Soft Light\nDarkens or lightens the colors, depending on the blend color. The effect is similar to shining a diffused spotlight on the image. If the blend color (light source) is lighter than 50% gray, the image is lightened as if it were dodged. If the blend color is darker than 50% gray, the image is darkened as if it were burned in. Painting with pure black or white produces a distinctly darker or lighter area, but does not result in pure black or white.\n```python\nimage.soft_light('#ff3cbc')\n```\n![sample_soft_light](https://user-images.githubusercontent.com/1064036/66765355-b77fb700-eee6-11e9-844a-5adb3b47b9cd.jpg)\n\n#### Hard Light\nMultiplies or screens the colors, depending on the blend color. The effect is similar to shining a harsh spotlight on the image. If the blend color (light source) is lighter than 50% gray, the image is lightened, as if it were screened. This is useful for adding highlights to an image. If the blend color is darker than 50% gray, the image is darkened, as if it were multiplied. This is useful for adding shadows to an image. Painting with pure black or white results in pure black or white.\n```python\nimage.hard_light('#df5dff')\n```\n![sample_hard_light](https://user-images.githubusercontent.com/1064036/66765542-16453080-eee7-11e9-8a14-7fb1b6076618.jpg)\n\n#### Vivid Light\nBurns or dodges the colors by increasing or decreasing the contrast, depending on the blend color. If the blend color (light source) is lighter than 50% gray, the image is lightened by decreasing the contrast. If the blend color is darker than 50% gray, the image is darkened by increasing the contrast.\n```python\nimage.vivid_light('#ac5b7f')\n```\n![sample_vivid_light](https://user-images.githubusercontent.com/1064036/66765734-818f0280-eee7-11e9-8fce-1f03a2d08675.jpg)\n\n#### Linear Light\nBurns or dodges the colors by decreasing or increasing the brightness, depending on the blend color. If the blend color (light source) is lighter than 50% gray, the image is lightened by increasing the brightness. If the blend color is darker than 50% gray, the image is darkened by decreasing the brightness.\n```python\nimage.linear_light('#9fa500')\n```\n![sample_linear_light](https://user-images.githubusercontent.com/1064036/66765909-d29ef680-eee7-11e9-99ac-a088c4d2ae95.jpg)\n\n#### Pin Light\nReplaces the colors, depending on the blend color. If the blend color (light source) is lighter than 50% gray, pixels darker than the blend color are replaced, and pixels lighter than the blend color do not change. If the blend color is darker than 50% gray, pixels lighter than the blend color are replaced, and pixels darker than the blend color do not change. This is useful for adding special effects to an image.\n```python\nimage.pin_light('#005546')\n```\n![sample_pin_light](https://user-images.githubusercontent.com/1064036/66766030-185bbf00-eee8-11e9-998a-8c44b6d34132.jpg)\n\n### Non-blend mode operations\n\n#### Brightness\n\nPlease note that this operation has yet to discover the exact algorithm (formula) used by Photoshop. However, the method used here is very close and extremely fast. \n\n```python\nimage.brightness(0.2)\n```\n\n\n#### Contrast\n```python\nimage.contrast(1.15)\n```\n\n#### Hue\n```python\nimage.hue(0.2)\n```\n\n#### Saturation\n```python\nimage.saturation(-0.5)\n```\n\n#### Lightness\n```python\nimage.lightness(-0.8)\n```\n\n### Other utility methods\n\n#### Getting image as NumPy array\n```python\nimage.get_image_as_array()\n```\nThis will return a NumPy array with shape (`height`, `width`, 3). Note that the each pixel value is \n\n\n#### Cloning a LayerImage instance\n```python\nimage.clone()\n```\n\n\n## Roadmap\n\n- Add resizing capabilities using scikit-image.\n- Imitate Photoshop's auto brightness & auto contrast features\n- Add presets of filters\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/subwaymatch/layer-is-python", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "layeris", "package_url": "https://pypi.org/project/layeris/", "platform": "", "project_url": "https://pypi.org/project/layeris/", "project_urls": { "Homepage": "https://github.com/subwaymatch/layer-is-python" }, "release_url": "https://pypi.org/project/layeris/0.1.3/", "requires_dist": null, "requires_python": ">=3.6", "summary": "An open source image processing library that supports blend modes, curve adjustment, and other adjustments that graphic designers or photographers frequently use", "version": "0.1.3", "yanked": false, "yanked_reason": null }, "last_serial": 6050409, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "790ba77c9e0610cdd173477238dc87a1", "sha256": "fdab7401823c8a817ae3b30f0799da9e1a24562c9064cf5955b5b8894e11a458" }, "downloads": -1, "filename": "layeris-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "790ba77c9e0610cdd173477238dc87a1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 7342, "upload_time": "2019-10-06T12:06:40", "upload_time_iso_8601": "2019-10-06T12:06:40.316554Z", "url": "https://files.pythonhosted.org/packages/bd/9c/341bb91535752e9aa5ace58ce73935c37fd592ee210cc5ded44751b0dd70/layeris-0.1.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "44e6a00d776529c3fb494f82f5313ff3", "sha256": "a1e2e4da04e50e69bdb04d1eb7699d9afa0c3661b7f725a45086dda52a1632bc" }, "downloads": -1, "filename": "layeris-0.1.0.tar.gz", "has_sig": false, "md5_digest": "44e6a00d776529c3fb494f82f5313ff3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 4834, "upload_time": "2019-10-06T12:06:42", "upload_time_iso_8601": "2019-10-06T12:06:42.382009Z", "url": "https://files.pythonhosted.org/packages/d6/17/31244ed4bdc735388a7ea6fb032d240ef66106d56b4c68002cc6f4683df2/layeris-0.1.0.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "5f50a929f0e8e379e04f320e7dff571f", "sha256": "9d7f2ebaba6e40d28b385819e5c6f6c654a54c3421c3d20a84940a2ed584b7a1" }, "downloads": -1, "filename": "layeris-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5f50a929f0e8e379e04f320e7dff571f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 7883, "upload_time": "2019-10-06T23:16:53", "upload_time_iso_8601": "2019-10-06T23:16:53.742779Z", "url": "https://files.pythonhosted.org/packages/9f/5d/2a092ec36fb23e1b921da8fe6a556cf46df56a005441cb8db3ae4c91fe6a/layeris-0.1.1-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3aff25582cd0c83384e6449a1eef94cb", "sha256": "b3d3c57f2ca0caf1f6e602253f9a46d11b1e46add5999e10fd512318dc57b825" }, "downloads": -1, "filename": "layeris-0.1.1.tar.gz", "has_sig": false, "md5_digest": "3aff25582cd0c83384e6449a1eef94cb", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 5338, "upload_time": "2019-10-06T23:16:56", "upload_time_iso_8601": "2019-10-06T23:16:56.534738Z", "url": "https://files.pythonhosted.org/packages/db/af/d280f61b31c90138734972c320751131571abc537ea711f3308f32bfdcca/layeris-0.1.1.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "e1b3c2fa281dc29c08295a863e2e8627", "sha256": "cc2d5fb43e74033bc59cd2d0c8b732887aecb11d2656b0d2e7060bae553dad7a" }, "downloads": -1, "filename": "layeris-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "e1b3c2fa281dc29c08295a863e2e8627", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 7883, "upload_time": "2019-10-30T03:06:49", "upload_time_iso_8601": "2019-10-30T03:06:49.581236Z", "url": "https://files.pythonhosted.org/packages/23/fd/a5dff5d75012ace03344925bc093a7429565a929077cf5eef21b312bb9ff/layeris-0.1.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "aabf3d8a51d1093a3296f598b4cf40f0", "sha256": "1b95667d597f101f47aa3cc9153cfff491bab24df747588d58a8ca5255d2d606" }, "downloads": -1, "filename": "layeris-0.1.2.tar.gz", "has_sig": false, "md5_digest": "aabf3d8a51d1093a3296f598b4cf40f0", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 5349, "upload_time": "2019-10-30T03:06:50", "upload_time_iso_8601": "2019-10-30T03:06:50.964875Z", "url": "https://files.pythonhosted.org/packages/34/5d/5aa941c1123cc41343d8bd92fdc9e91b409c3671e3e8c60d24d3506ddeef/layeris-0.1.2.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "10b4580457e4537e7428db05e158d1fb", "sha256": "f4581ba45bdd461e1590fa02b4f38da7ffd95624f75e9d6a28a2bfb07bb73069" }, "downloads": -1, "filename": "layeris-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "10b4580457e4537e7428db05e158d1fb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 10280, "upload_time": "2019-10-30T03:08:03", "upload_time_iso_8601": "2019-10-30T03:08:03.290787Z", "url": "https://files.pythonhosted.org/packages/10/07/a4ca5265c1e3a5a6c0d83dbaae12b46047bfebeac855a7a9742b1a5edd7e/layeris-0.1.3-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "fc93f776c39d0fe33784594fcea7eb91", "sha256": "575e1ea1510444bab2cc7dd2e7b507665c315e5d289681cd702799e36e0b1494" }, "downloads": -1, "filename": "layeris-0.1.3.tar.gz", "has_sig": false, "md5_digest": "fc93f776c39d0fe33784594fcea7eb91", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 11109, "upload_time": "2019-10-30T03:08:05", "upload_time_iso_8601": "2019-10-30T03:08:05.084393Z", "url": "https://files.pythonhosted.org/packages/b8/7d/8ea929a3e4f8c9ba74f44a29f2983054c9d2fcdea503d5693113b0bc2ffe/layeris-0.1.3.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "10b4580457e4537e7428db05e158d1fb", "sha256": "f4581ba45bdd461e1590fa02b4f38da7ffd95624f75e9d6a28a2bfb07bb73069" }, "downloads": -1, "filename": "layeris-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "10b4580457e4537e7428db05e158d1fb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 10280, "upload_time": "2019-10-30T03:08:03", "upload_time_iso_8601": "2019-10-30T03:08:03.290787Z", "url": "https://files.pythonhosted.org/packages/10/07/a4ca5265c1e3a5a6c0d83dbaae12b46047bfebeac855a7a9742b1a5edd7e/layeris-0.1.3-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "fc93f776c39d0fe33784594fcea7eb91", "sha256": "575e1ea1510444bab2cc7dd2e7b507665c315e5d289681cd702799e36e0b1494" }, "downloads": -1, "filename": "layeris-0.1.3.tar.gz", "has_sig": false, "md5_digest": "fc93f776c39d0fe33784594fcea7eb91", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 11109, "upload_time": "2019-10-30T03:08:05", "upload_time_iso_8601": "2019-10-30T03:08:05.084393Z", "url": "https://files.pythonhosted.org/packages/b8/7d/8ea929a3e4f8c9ba74f44a29f2983054c9d2fcdea503d5693113b0bc2ffe/layeris-0.1.3.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }