{"id":27998494,"url":"https://github.com/w3labkr/py-image-toolkit","last_synced_at":"2025-10-29T12:39:48.497Z","repository":{"id":292011449,"uuid":"975534293","full_name":"w3labkr/py-image-toolkit","owner":"w3labkr","description":"Python CLI toolkit for fast and smart image resizing and cropping with face detection","archived":false,"fork":false,"pushed_at":"2025-05-07T16:49:17.000Z","size":259,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-08T22:53:32.063Z","etag":null,"topics":["cli","face-detection","image-crop","image-processing","image-resize","py","python"],"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/w3labkr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2025-04-30T13:23:56.000Z","updated_at":"2025-05-07T16:49:23.000Z","dependencies_parsed_at":"2025-05-07T17:55:45.705Z","dependency_job_id":null,"html_url":"https://github.com/w3labkr/py-image-toolkit","commit_stats":null,"previous_names":["w3labkr/py-image-toolkit"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w3labkr%2Fpy-image-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w3labkr%2Fpy-image-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w3labkr%2Fpy-image-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w3labkr%2Fpy-image-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/w3labkr","download_url":"https://codeload.github.com/w3labkr/py-image-toolkit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253160818,"owners_count":21863624,"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":["cli","face-detection","image-crop","image-processing","image-resize","py","python"],"created_at":"2025-05-08T22:53:34.703Z","updated_at":"2025-10-29T12:39:48.480Z","avatar_url":"https://github.com/w3labkr.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# py-image-toolkit\n\nA fast and easy-to-use Python toolkit for image processing with CLI tools for resizing, cropping, OCR, and optimization, including batch processing support.\n\n---\n\n## Folder and File Structure\n\n```plaintext\npy-image-toolkit/\n├── models/            # Directory for storing models\n│   ├── face_detection_yunet_2023mar.onnx # YuNet model for face detection\n│   ├── ch_PP-OCRv3_det_infer/           # Example: PaddleOCR detection model\n│   ├── ko_PP-OCRv3_rec_infer/           # Example: PaddleOCR Korean recognition model\n│   └── ch_ppocr_mobile_v2.0_cls_infer/  # Example: PaddleOCR classification model\n├── resize.py          # CLI script for image resizing logic\n├── crop.py            # CLI script for face detection and auto-cropping logic\n├── ocr.py             # CLI script for Optical Character Recognition (OCR)\n├── optimize.py        # CLI script for image optimization and compression\n├── resizes.py    # CLI script for batch image resizing\n├── crops.py      # CLI script for batch image cropping\n├── ocrs.py       # CLI script for batch Optical Character Recognition (OCR)\n├── optimizes.py  # CLI script for batch image optimization\n├── requirements.txt   # List of required libraries\n└── README.md          # Project documentation\n```\n\n---\n\n## Installation\n\n### Requirements\n\n- Python 3.8 or higher\n- Required libraries (see `requirements.txt`):\n  - `opencv-python`\n  - `Pillow`\n  - `tqdm`\n  - `piexif`\n  - `numpy`\n  - `paddleocr` (for `ocr.py` script)\n  - `paddlepaddle` or `paddlepaddle-gpu` (for `ocr.py` script)\n\n### Installation Guide\n\nClone the repository and set up a virtual environment:\n\n```bash\ngit clone https://github.com/w3labkr/py-image-toolkit.git\ncd py-image-toolkit\n# Example using pyenv (adjust to your Python version management)\n# pyenv install 3.12.9\n# pyenv virtualenv 3.12.9 py-image-toolkit-3.12.9\n# pyenv local py-image-toolkit-3.12.9\n```\n\nInstall the required dependencies:\n\n```bash\npip install -r requirements.txt\n```\n\nTo use the `ocr.py` script with GPU acceleration, ensure you install `paddlepaddle-gpu` instead of `paddlepaddle` and have the necessary CUDA drivers and toolkit installed.\n\nTo deactivate and remove the virtual environment created with pyenv, use the following commands:\n\n```bash\n# Deactivate the current pyenv virtual environment\npyenv deactivate\n\n# Remove the local virtual environment setting for the project directory\npyenv local --unset\n\n# Delete the virtual environment\n# Replace py-image-toolkit-3.12.9 with your virtual environment name if different\npyenv virtualenv-delete py-image-toolkit-3.12.9\n\n# Optional: Uninstall the Python version if it's no longer needed by other projects\n# pyenv uninstall 3.12.9 # Be cautious with this command\n\n# Verify the changes\npyenv versions\n```\n\n---\n\n## General CLI Options\n\nEach script (`resize.py`, `crop.py`, `ocr.py`, `optimize.py`) and their batch counterparts (`resizes.py`, `crops.py`, `ocrs.py`, `optimizes.py`) are run directly and have their own set of options.\n\n- Individual scripts generally take a single `input_file` as an argument.\n- Batch scripts generally take an `input_dir` as an argument to process multiple files.\n- `ocr.py` and `batch_ocr.py` provide CLI options for PaddleOCR configuration, and `--show_log` can be used to display PaddleOCR's internal logs. See the `Optical Character Recognition (OCR)` section below for details.\n\n---\n\n## Image Resizing\n\nThe `resize.py` script processes a single image file by resizing it. It preserves EXIF metadata where possible (this is the default behavior of the underlying Pillow library) and saves images in their original format. It offers detailed logging for errors.\n\n- Aspect Ratio Resizing: Maintains aspect ratio while resizing.\n- Fixed Size Resizing: Forces images to fit specific dimensions.\n- EXIF Metadata Preservation: Preserves original EXIF metadata where possible.\n\nSyntax:\n\n```bash\npython resize.py \u003cinput_file\u003e [options]\n```\n\nKey Options for `resize`:\n\n- `input_file`: Path to the source image file.\n- `-o, --output-dir`: Directory to save processed images (default: `output`).\n- `-r, --ratio`: Resize ratio behavior (`aspect_ratio`, `fixed`, `none`). (default: `aspect_ratio`).\n  - `aspect_ratio`: Maintain aspect ratio to fit the target size. Requires at least one of `--width` or `--height` to be positive.\n  - `none`: No resizing. If `width` or `height` are specified with `none`, a warning will be shown as they are ignored.\n- `-w, --width`: Target width for resizing in pixels (default: `0`).\n- `-H, --height`: Target height for resizing in pixels (default: `0`).\n- `--filter`: Resampling filter to use when resizing (`lanczos`, `bicubic`, `bilinear`, `nearest`). (default: `lanczos`).\n- `--overwrite`: Overwrite existing output files. If not specified, existing files will be skipped.\n\nExamples for `resize`:\n\n- Resize an image `./input/sample.jpg` to a width of 1280px, maintaining aspect ratio:\n\n  ```bash\n  python resize.py ./input/sample.jpg -w 1280\n  ```\n\n- Resize an image to fixed 720x600 dimensions:\n\n  ```bash\n  python resize.py ./input/sample.jpg -o ./output_resized -r fixed -w 720 -H 600\n  ```\n\n- Process an image `./input/sample.jpg` without resizing (e.g., to copy to output directory, useful with `--overwrite`):\n\n  ```bash\n  python resize.py ./input/sample.jpg -r none --overwrite\n  ```\n\n---\n\n## Batch Image Resizing\n\nThe `resizes.py` script processes all images within a specified input directory, applying the same resizing logic as `resize.py` to each image.\n\nSyntax:\n\n```bash\npython resizes.py \u003cinput_dir\u003e [options]\n```\n\nKey Options for `batch_resize`:\n\n- `input_dir`: Path to the directory containing source image files.\n- `-o, --output-dir`: Directory to save processed images (default: `output`).\n- `-r, --ratio`: Resize ratio behavior (`aspect_ratio`, `fixed`, `none`). (default: `aspect_ratio`).\n  - `aspect_ratio`: Maintain aspect ratio to fit the target size. Requires at least one of `--width` or `--height` to be positive.\n  - `none`: No resizing. If `width` or `height` are specified with `none`, a warning will be shown as they are ignored.\n- `-w, --width`: Target width for resizing in pixels (default: `0`).\n- `-H, --height`: Target height for resizing in pixels (default: `0`).\n- `--filter`: Resampling filter to use when resizing (`lanczos`, `bicubic`, `bilinear`, `nearest`). (default: `lanczos`).\n- `--overwrite`: Overwrite existing output files. If not specified, existing files will be skipped.\n\nExamples for `batch_resize`:\n\n- Resize all images in `./input_images` to a width of 1280px, maintaining aspect ratio, and save to `./output_resized_batch`:\n\n  ```bash\n  python resizes.py ./input_images -o ./output_resized_batch -w 1280\n  ```\n\n- Resize all images in `./input_images` to fixed 720x600 dimensions:\n\n  ```bash\n  python resizes.py ./input_images -r fixed -w 720 -H 600\n  ```\n\n---\n\n## Image Cropping\n\nThe `crop.py` script is designed to detect faces in a single image and automatically crop it based on composition rules like the rule of thirds or the golden ratio. It identifies subjects in the image, determines the main subject, and then calculates the optimal crop area. It automatically downloads the face detection model if needed.\n\nSyntax:\n\n```bash\npython crop.py \u003cinput_file\u003e [options]\n```\n\nKey Options for `crop`:\n\n- `input_file`: (Required) Path to the image file to process.\n- `-o, --output-dir`: Directory to save results (Default: `output`).\n- `--overwrite`: Overwrite existing output files (Default: False).\n- `-v, --verbose`: Enable detailed (DEBUG level) logging for the crop operation (Default: False).\n- `-m, --method`: Method to select main subject (`largest`, `center`). (Default: `largest`).\n- `--ref, --reference`: Reference point for composition (`eye`, `box`). (Default: `box`).\n- `-c, --confidence`: Min face detection confidence (Default: `0.6`).\n- `-n, --nms`: Face detection NMS threshold (Default: `0.3`).\n- `--min-face-width`: Min face width in pixels (Default: `30`).\n- `--min-face-height`: Min face height in pixels (Default: `30`).\n- `-r, --ratio`: Target crop aspect ratio (e.g., '16:9', '1.0', 'None') (Default: `None`).\n- `--rule`: Composition rule(s) (`thirds`, `golden`, `both`, `none`). (Default: `both`).\n- `-p, --padding-percent`: Padding percentage around crop (%) (Default: `5.0`).\n- `--yunet-model-path`: Path to the YuNet ONNX model file. If not specified, it defaults to `models/face_detection_yunet_2023mar.onnx` and will be downloaded if missing.\n\nExamples for `crop`:\n\n- Crop an image using default settings:\n\n  ```bash\n  python crop.py ./input/sample.jpg\n  ```\n\n- Crop an image, saving to `./cropped_images`, using the 'thirds' rule and a 16:9 aspect ratio:\n\n  ```bash\n  python crop.py ./input/sample.jpg -o ./cropped_images --rule thirds --ratio 16:9\n  ```\n\n- Crop an image, focusing on the 'eye' as reference, with 10% padding and overwriting existing files:\n\n  ```bash\n  python crop.py ./input/sample.png --reference eye --padding-percent 10 --overwrite\n  ```\n\n---\n\n## Batch Image Cropping\n\nThe `crops.py` script processes all images within a specified input directory, applying the same face detection and auto-cropping logic as `crop.py` to each image.\n\nSyntax:\n\n```bash\npython crops.py \u003cinput_dir\u003e [options]\n```\n\nKey Options for `batch_crop`:\n\n- `input_dir`: (Required) Path to the directory containing image files to process.\n- `-o, --output-dir`: Directory to save results (Default: `output`).\n- `--overwrite`: Overwrite existing output files (Default: False).\n- `-v, --verbose`: Enable detailed (DEBUG level) logging for the crop operation (Default: False).\n- `-m, --method`: Method to select main subject (`largest`, `center`). (Default: `largest`).\n- `--ref, --reference`: Reference point for composition (`eye`, `box`). (Default: `box`).\n- `-c, --confidence`: Min face detection confidence (Default: `0.6`).\n- `-n, --nms`: Face detection NMS threshold (Default: `0.3`).\n- `--min-face-width`: Min face width in pixels (Default: `30`).\n- `--min-face-height`: Min face height in pixels (Default: `30`).\n- `-r, --ratio`: Target crop aspect ratio (e.g., '16:9', '1.0', 'None') (Default: `None`).\n- `--rule`: Composition rule(s) (`thirds`, `golden`, `both`, `none`). (Default: `both`).\n- `-p, --padding-percent`: Padding percentage around crop (%) (Default: `5.0`).\n- `--yunet-model-path`: Path to the YuNet ONNX model file. If not specified, it defaults to `models/face_detection_yunet_2023mar.onnx` and will be downloaded if missing.\n\nExamples for `batch_crop`:\n\n- Crop all images in `./input_folder` using default settings:\n\n  ```bash\n  python crops.py ./input_folder\n  ```\n\n- Crop all images in `./input_folder`, saving to `./cropped_batch`, using the 'thirds' rule and a 16:9 aspect ratio:\n\n  ```bash\n  python crops.py ./input_folder -o ./cropped_batch --rule thirds --ratio 16:9\n  ```\n\n---\n\n## Image Optimization\n\nThe `optimize.py` script allows you to compress and optimize a single image without significant visible quality loss. It supports various formats including JPEG, PNG, WebP, and TIFF, each with format-specific optimizations.\n\nSyntax:\n\n```bash\npython optimize.py \u003cinput_file\u003e [options]\n```\n\nKey Options for `optimize`:\n\n- `input_file`: Path to the image file to process.\n- `-o, --output-dir`: Directory to save optimized images (default: `output`).\n- `--overwrite`: Overwrite existing files if they already exist in the output directory (Default: False).\n- `--jpg-quality`: JPEG image quality setting (1-100, default: `85`). Lower values produce smaller files but may reduce quality.\n- `--webp-quality`: WebP image quality (1-100, default: `85`, ignored when `--lossless` option is used).\n- `--lossless`: Use lossless compression for WebP (ignores WebP quality setting).\n\nExamples for `optimize`:\n\n- Optimize an image `./input/sample.jpg` with default settings:\n\n  ```bash\n  python optimize.py ./input/sample.jpg\n  ```\n\n- Optimize a single image with custom JPEG quality (70%) and save to a specific directory:\n\n  ```bash\n  python optimize.py ./input/large_image.jpg -o ./optimized_images --jpg-quality 70\n  ```\n\n- Optimize a WebP image with lossless compression:\n\n  ```bash\n  python optimize.py ./input/sample.webp -o ./optimized_output --lossless\n  ```\n\n- Process an image `./photos/another.png` and overwrite any existing file:\n\n  ```bash\n  python optimize.py ./photos/another.png -o ./photos_optimized --overwrite\n  ```\n\n---\n\n## Batch Image Optimization\n\nThe `optimizes.py` script processes all images within a specified input directory, applying the same optimization logic as `optimize.py` to each image.\n\nSyntax:\n\n```bash\npython optimizes.py \u003cinput_dir\u003e [options]\n```\n\nKey Options for `batch_optimize`:\n\n- `input_dir`: Path to the directory containing image files to process.\n- `-o, --output-dir`: Directory to save optimized images (default: `output`).\n- `--overwrite`: Overwrite existing files if they already exist in the output directory (Default: False).\n- `--jpg-quality`: JPEG image quality setting (1-100, default: `85`).\n- `--webp-quality`: WebP image quality (1-100, default: `85`, ignored when `--lossless` option is used).\n- `--lossless`: Use lossless compression for WebP (ignores WebP quality setting).\n- `--max-workers`: Maximum number of processes to use for parallel processing (default: number of CPUs).\n\nExamples for `batch_optimize`:\n\n- Optimize all images in `./source_images` with default settings:\n\n  ```bash\n  python optimizes.py ./source_images\n  ```\n\n- Optimize all images in `./source_images` with custom JPEG quality (70%) and save to `./optimized_batch`:\n\n  ```bash\n  python optimizes.py ./source_images -o ./optimized_batch --jpg-quality 70\n  ```\n\n---\n\n## Optical Character Recognition (OCR)\n\nThe `ocr.py` script uses PaddleOCR to extract text from a single image. It then attempts to identify and label key information such as document title, name, address, resident registration number, issue date, and issuer.\n\nSyntax:\n\n```bash\npython ocr.py \u003cinput_file\u003e [options]\n```\n\nKey Options for `ocr`:\n\n- `input_file`: (Required) Path to the image file to process.\n- `--lang`: OCR language (default: `korean`). Refer to PaddleOCR documentation for supported languages.\n- `--rec_model_dir`: Path to the recognition model directory (default: `./models/ko_PP-OCRv3_rec_infer`).\n- `--det_model_dir`: Path to the detection model directory (default: `./models/ch_PP-OCRv3_det_infer`).\n- `--cls_model_dir`: Path to the direction classification model directory (default: `./models/ch_ppocr_mobile_v2.0_cls_infer`).\n- `--use_gpu`: Whether to use GPU for OCR processing (default: `False`).\n- `--rec_char_dict_path`: Path to recognition character dictionary (default: `None`, uses PaddleOCR default).\n- `--rec_batch_num`: Recognition batch size (default: `6`).\n- `--det_db_thresh`: Detection DB threshold (default: `0.4`).\n- `--det_db_box_thresh`: Detection DB box threshold (default: `0.6`).\n- `--det_db_unclip_ratio`: Detection DB unclip ratio (default: `1.8`).\n- `--drop_score`: Drop score for text detection (default: `0.6`).\n- `--cls_thresh`: Classification threshold (default: `0.9`).\n- `--use_angle_cls`: Whether to use angle classification (default: `False`).\n- `--use_space_char`: Whether to use space character (default: `True`).\n- `--use_dilation`: Whether to use dilation on text regions (default: `True`).\n- `--show_log`: Whether to display PaddleOCR's internal logs (default: `False`).\n\nExamples for `ocr`:\n\n- Extract text from a single image file:\n\n  ```bash\n  python ocr.py ./input/sample.png\n  ```\n\n- Extract Korean text from an image (using GPU and specifying a custom Korean recognition model):\n\n  ```bash\n  python ocr.py ./input_images/my_document.jpg --lang korean --use_gpu --rec_model_dir ./models/my_custom_korean_ocr_model\n  ```\n\nThe script will output extracted fields like \"문서 제목\", \"이름\", \"주소\", \"주민등록번호\", \"발급일\", \"발급기관\".\n\n---\n\n## Batch Optical Character Recognition (OCR)\n\nThe `ocrs.py` script processes all images within a specified input directory, applying the same OCR logic as `ocr.py` to each image and saving the results.\n\nSyntax:\n\n```bash\npython ocrs.py \u003cinput_dir\u003e [options]\n```\n\nKey Options for `batch_ocr`:\n\n- `input_dir`: (Required) Path to the directory containing image files to process.\n- `-o, --output-dir`: Directory to save the output CSV files (passed to `ocr.py`). `ocr.py` default: `output`.\n- `--lang`: OCR language (default: `korean`). (`ocr.py` default)\n- `--rec_model_dir`: Path to the recognition model directory (default: `./models/ko_PP-OCRv3_rec_infer`). (`ocr.py` default)\n- `--det_model_dir`: Path to the detection model directory (default: `./models/ch_PP-OCRv3_det_infer`). (`ocr.py` default)\n- `--cls_model_dir`: Path to the direction classification model directory (default: `./models/ch_ppocr_mobile_v2.0_cls_infer`). (`ocr.py` default)\n- `--use_gpu`: Whether to use GPU for OCR processing (default: `False`). (`ocr.py` default)\n- `--rec_char_dict_path`: Path to recognition character dictionary (default: `None`, uses PaddleOCR default). (`ocr.py` default)\n- `--rec_batch_num`: Recognition batch size (default: `6`). (`ocr.py` default)\n- `--det_db_thresh`: Detection DB threshold (default: `0.4`). (`ocr.py` default)\n- `--det_db_box_thresh`: Detection DB box threshold (default: `0.6`). (`ocr.py` default)\n- `--det_db_unclip_ratio`: Detection DB unclip ratio (default: `1.8`). (`ocr.py` default)\n- `--drop_score`: Drop score for text detection (default: `0.6`). (`ocr.py` default)\n- `--cls_thresh`: Classification threshold (default: `0.9`). (`ocr.py` default)\n- `--use_angle_cls`: Whether to use angle classification (default: `False`). (`ocr.py` default)\n- `--use_space_char`: Whether to use space character (default: `True`). (`ocr.py` default)\n- `--use_dilation`: Whether to use dilation on text regions (default: `True`). (`ocr.py` default)\n- `--show_log`: Whether to display PaddleOCR's internal logs (default: `False`). (`ocr.py` default)\n\nExamples for `batch_ocr`:\n\n- Extract text from all images in `./scan_docs`:\n\n  ```bash\n  python ocrs.py ./scan_docs\n  ```\n\n- Extract Korean text from all images in `./id_cards` (using GPU):\n\n  ```bash\n  python ocrs.py ./id_cards --lang korean --use_gpu\n  ```\n\nThe script will save extracted text or structured data for each image in the specified output directory.\n\n---\n\n## Troubleshooting\n\nIf you encounter issues while using the toolkit, refer to the following common problems and solutions:\n\n### Missing Libraries\n\nEnsure all dependencies are installed:\n\n```bash\npip install -r requirements.txt\n```\n\n### Missing Model File\n\n- **YuNet Model (for `crop.py` script)**: The `crop.py` script will automatically attempt to download the YuNet model if it is not found in the `models/` directory. Ensure you have an active internet connection during the first run or if the model is missing.\n- **PaddleOCR Models (for `ocr.py` script)**: The `ocr.py` script requires PaddleOCR models.\n  - Ensure you have downloaded the necessary detection, recognition (e.g., for Korean), and classification models.\n  - By default, the script looks for models in subdirectories under `./models/` (e.g., `./models/ko_PP-OCRv3_rec_infer`). You may need to create these directories and place the model files there, or specify custom model paths using options like `--rec_model_dir`, `--det_model_dir`, and `--cls_model_dir`.\n  - If using GPU (`--use_gpu`), ensure `paddlepaddle-gpu` is installed and your CUDA environment is correctly configured.\n\n### Image Not Processed\n\n- Verify that the input path is correct and points to a valid image file with supported extensions.\n- For `ocr.py`: `python ocr.py ./input_image.png --show_log` (for PaddleOCR logs)\n- If `python resize.py` command fails due to invalid arguments or critical processing errors, it will exit with a non-zero status code. Check terminal output for specific error messages.\n- If `python crop.py` command encounters critical setup issues (e.g., model download failure, output directory problems, invalid input path) or unhandled processing errors, it will exit with a non-zero status code. `CropSetupError` indicates a problem that prevented the operation from starting. Check terminal output and logs for details.\n- If `python ocr.py` command fails, check for PaddleOCR model availability, correct paths, and library installation. Error messages in the terminal or logs should provide more details.\n- If `python optimize.py` command fails, ensure that the image files are valid and that you have appropriate file access permissions. Check terminal output for specific error messages.\n\n---\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fw3labkr%2Fpy-image-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fw3labkr%2Fpy-image-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fw3labkr%2Fpy-image-toolkit/lists"}