{"id":22303983,"url":"https://github.com/affromero/pixelcache","last_synced_at":"2025-06-25T10:31:51.774Z","repository":{"id":266121835,"uuid":"896252603","full_name":"affromero/PixelCache","owner":"affromero","description":"A versatile image processing library for Python with built-in support for caching, using Pillow, NumPy, and PyTorch.","archived":false,"fork":false,"pushed_at":"2025-03-21T11:23:40.000Z","size":4398,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T12:28:52.459Z","etag":null,"topics":["image-processing","numpy","opencv","pillow","pytorch","torchvision"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/affromero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-29T22:07:39.000Z","updated_at":"2025-03-21T11:23:44.000Z","dependencies_parsed_at":"2024-12-23T20:28:06.033Z","dependency_job_id":"c9415f06-f404-4cec-8761-be7b6e8da90e","html_url":"https://github.com/affromero/PixelCache","commit_stats":null,"previous_names":["affromero/pixelcache"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affromero%2FPixelCache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affromero%2FPixelCache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affromero%2FPixelCache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affromero%2FPixelCache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/affromero","download_url":"https://codeload.github.com/affromero/PixelCache/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245999321,"owners_count":20707554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["image-processing","numpy","opencv","pillow","pytorch","torchvision"],"created_at":"2024-12-03T18:53:37.121Z","updated_at":"2025-06-25T10:31:51.768Z","avatar_url":"https://github.com/affromero.png","language":"Python","readme":"[![Publish to PyPI](https://github.com/affromero/PixelCache/actions/workflows/publish.yml/badge.svg)](https://github.com/affromero/PixelCache/actions/workflows/publish.yml)\n![PyPI - Version](https://img.shields.io/pypi/v/pixelcache)\n\n# PixelCache\n\n\u003cimg src=\"pixelcache/assets/pixel_cache.png\" width=\"100\" height=\"100\"/\u003e\n\n**Sometimes you do not care whether the image processing is done using NumPy or PyTorch or Pillow, and transfering between these libraries can be cumbersome. PixelCache provides a simple interface to perform image processing and transformation using these libraries, allowing you to focus on the task at hand.**\n\nPixelCache is a Python library designed for versatile image processing and transformation, integrating the power of Pillow, NumPy, and PyTorch while supporting LRU caching.\n\nPixelCache also supports LRU caching, which can be useful when you need to reuse the results of previously computed operations. This can be particularly helpful when working with large images or when you need to apply the same operation multiple times.\n\n## Features\n\n- **Image Manipulation:** Transform and process images using a simple interface that supports Pillow, NumPy, and PyTorch.\n- **Smart Caching:** Utilize LRU caching to enhance performance by reusing previously computed results. It can be easily disable for whatever reason using the environment variable `DISABLE_LRU_CACHE=True`.\n- **Versatile:** PixelCache supports a wide range of image processing operations, including resizing, cropping, blending, transform to RGB/Binary, flipping, bounding box extraction from binary masks, several operations suitable for binary masks, and more.\n\n## Installation\n\nYou can install PixelCache using pip:\n\n```bash\npip install pixelcache\n```\n\nOr poetry:\n\n```bash\npoetry add pixelcache\n```\n\nOr from source:\n\n```bash\npoetry add git+ssh://git@github.com:affromero/pixelcache.git\n```\n\n## Basic Usage\n\nHashableImage receives as input several types of inputs, such as URLs, paths, or Pillow images, Numpy arrays, or PyTorch tensors in the following form or shape:\n\n### Valdid inputs:\n\n- Paths: `str` | `Path`\n- Pillow: `Image.Image`\n- Numpy Arrays: `UInt8[np.ndarray, \"h w 3\"]` | `UInt8[np.ndarray, \"h w\"]` | `Bool[np.ndarray, \"h w\"]`\n- Torch Tensors: `Float[torch.Tensor, \"1 c h w\"]` | `Bool[torch.Tensor, \"1 1 h w\"]`\n\nExample:\n\n```python\nfrom pixelcache.main import HashableImage\nimport torch\nimage = HashableImage(torch.rand(1, 3, 256, 256).float())\nimage_pil = image.pil()\nimage_numpy_bool = image.to_binary(0.5).numpy()\n```\n\n### Basic Transformations:\n\nAt all times, it is possible to transform between them using the following methods:\n\n- `pil()`: Returns a Pillow Image object\n- `numpy()`: Returns a Numpy Array object\n- `tensor()`: Returns a PyTorch Tensor object\n\nAdditionally, there is a method to convert the image to 3 channels RGB or binary:\n\n- `to_rgb()`: Convert to RGB, which returns another HashableImage\n- `to_binary(threshold: float)`: Convert to Boolean, which returns another HashableImage\n\nFinally, there is a method to save the image to disk:\n\n- `save(path: str | Path)`: Save the image to disk\n\n## Usage Example 1\n\nBlending two images using PixelCache:\n\n```python\nfrom pathlib import Path\n\nfrom pixelcache.main import HashableDict, HashableImage, HashableList\nfrom pixelcache.tools.logger import get_logger\n\nlogger = get_logger()\n\nimage0 = \"https://images.pexels.com/photos/28811907/pexels-photo-28811907/free-photo-of-majestic-elk-standing-in-forest-clearing.jpeg\"\nimage1 = Path(\"pixelcache\") / \"assets\" / \"pixel_cache.png\"\nimages_hash = [HashableImage(image) for image in [image0, image1]]\nfor image in images_hash:\n    logger.info(f\"Image: {image} - Hash: {hash(image)}\")\nlogger.info(f\"Hash for list of images: {hash(HashableList(images_hash))}\")\nimage_size = images_hash[1].size()\nlogger.info(f\"Image size: {image_size} - Resizing all to this size\")\nresized_images = [image.resize(image_size) for image in images_hash]\n# blend images\nblended_image = resized_images[0].blend(\n    resized_images[1], alpha=0.5, with_bbox=False\n)\n# binarize second image\nblended_image_binarized = resized_images[0].blend(\n    resized_images[1].to_binary(0.5).invert_binary(),\n    alpha=0.2,\n    with_bbox=True,\n)\noutput_debug = HashableDict(\n    {\n        \"image base\": HashableList([resized_images[0]]),\n        \"image reference\": HashableList([resized_images[1]]),\n        \"blended_image\": HashableList([blended_image]),\n        \"blended_image_binarized\": HashableList([blended_image_binarized]),\n    }\n)\noutput = image1.parent / (str(image1.stem) + \"_demo_blend.jpg\")\nHashableImage.make_image_grid(\n    output_debug, orientation=\"horizontal\", with_text=True\n).save(output)\nlogger.success(f\"Output saved to: {output}\")\n\n```\n\n![Output](pixelcache/assets/pixel_cache_demo_blend.jpg)\n\n## Usage Example 2\n\nExtracting bounding boxes for cropping / unpadding from binary masks using PixelCache:\n\n```python\nfrom pathlib import Path\n\nfrom pixelcache.main import HashableDict, HashableImage, HashableList, ImageSize\nfrom pixelcache.tools.logger import get_logger\n\nlogger = get_logger()\n\nimage0 = \"https://images.pexels.com/photos/18624700/pexels-photo-18624700/free-photo-of-a-vintage-typewriter.jpeg\"\nimage1 = Path(\"pixelcache\") / \"assets\" / \"pixel_cache.png\"\nimages_hash = [HashableImage(image) for image in [image0, image1]]\nfor image in images_hash:\n    logger.info(f\"Image: {image} - Hash: {hash(image)}\")\nlogger.info(f\"Hash for list of images: {hash(HashableList(images_hash))}\")\nimage_size = images_hash[1].size()\nlogger.info(f\"Image size: {image_size} - Resizing all to this size\")\nresized_images = [image.resize(image_size) for image in images_hash]\n# crop images\nincreased_size_pad = ImageSize(\n    width=image_size.width + 1000, height=image_size.height + 1000\n)\nmask = (\n    images_hash[1]\n    .center_pad(increased_size_pad, fill=255)\n    .resize(image_size)\n    .to_space_color(\"HSV\", getchannel=\"S\")\n    .to_binary(0.3)\n)\ncropped = resized_images[1].crop_from_mask(mask)\nuncropped = cropped.uncrop_from_bbox(\n    base=resized_images[0], bboxes=mask.mask2bbox(margin=0.0), resize=True\n)\noutput_debug = HashableDict(\n    {\n        \"image base\": HashableList([resized_images[0]]),\n        \"image reference\": HashableList([resized_images[1]]),\n        \"cropped_image\": HashableList([cropped.resize(image_size)]),\n        \"uncropped_image\": HashableList([uncropped]),\n    }\n)\noutput = image1.parent / (str(image1.stem) + \"_demo_cropUncrop.jpg\")\nHashableImage.make_image_grid(\n    output_debug, orientation=\"horizontal\", with_text=True\n).save(output)\nlogger.success(f\"Output saved to: {output}\")\n\n```\n\n![Output](pixelcache/assets/pixel_cache_demo_cropUncrop.jpg)\n\n### Both examples can be found in the `examples` folder.\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n## License\n\nThis project is licensed under the MIT License\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faffromero%2Fpixelcache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faffromero%2Fpixelcache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faffromero%2Fpixelcache/lists"}