Compare commits
8 Commits
feat/api-f
...
feature/as
| Author | SHA1 | Date | |
|---|---|---|---|
| ffd13421ca | |||
| cf07ab9d88 | |||
| 8c4c093d49 | |||
| 5803891b60 | |||
| 7d78cc8058 | |||
| 1c642ee207 | |||
| a1f3c0638d | |||
| 275d53d1dc |
@@ -3,3 +3,4 @@
|
||||
My personal set of tools to ease and speed up my development experience.
|
||||
|
||||
1. `colorizer`: color model converter.
|
||||
2. `image-converter`: simple image formate and size converter.
|
||||
|
||||
16
image-converter/.editorconfig
Normal file
16
image-converter/.editorconfig
Normal file
@@ -0,0 +1,16 @@
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{md,py}]
|
||||
charset = utf-8
|
||||
|
||||
[*.py]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
6
image-converter/.gitignore
vendored
Normal file
6
image-converter/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/venv
|
||||
/venv/*
|
||||
__pycache__/
|
||||
/build
|
||||
/dist
|
||||
*.spec
|
||||
16
image-converter/Makefile
Normal file
16
image-converter/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
install:
|
||||
echo ">>> Installing dependencies"
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
|
||||
build:
|
||||
pyinstaller src/main.py --onefile
|
||||
|
||||
save:
|
||||
pip freeze > requirements.txt
|
||||
|
||||
run:
|
||||
python src/main.py
|
||||
|
||||
setenv:
|
||||
python -m venv venv
|
||||
21
image-converter/README.md
Normal file
21
image-converter/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Image converter
|
||||
|
||||
Simple tool to convert images on mass.
|
||||
|
||||
- Resize
|
||||
- Format
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
- `-H <height>` : max height of vertical images.
|
||||
- `-W <width>` : max width of horizontal images.
|
||||
- `-e <extension>` : extension of the output files.
|
||||
- `-d <directory>` : input directory path.
|
||||
- `-f <file/s>` : file or list of files (paths) to parse.
|
||||
- `-o <directory>` : output directory path.
|
||||
- `-h` : print help.
|
||||
|
||||
### Examples of usage
|
||||
|
||||
- `python converter.py -d ./assets -f ./another/file.png ./yet\ one\ more/file2.CR2 -e png -W 1000` : convert every file inside assets plus both `file.png` and `file2.CR2` into `PNG` with a with of 1000.
|
||||
6
image-converter/requirements.txt
Normal file
6
image-converter/requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
iniconfig==2.3.0
|
||||
packaging==25.0
|
||||
pillow==12.1.0
|
||||
pluggy==1.6.0
|
||||
Pygments==2.19.2
|
||||
pytest==9.0.2
|
||||
BIN
image-converter/src/assets/clear.jpg
Normal file
BIN
image-converter/src/assets/clear.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 931 KiB |
BIN
image-converter/src/assets/fee.jpg
Normal file
BIN
image-converter/src/assets/fee.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 248 KiB |
BIN
image-converter/src/assets/foo.CR2
Normal file
BIN
image-converter/src/assets/foo.CR2
Normal file
Binary file not shown.
18
image-converter/src/main.py
Normal file
18
image-converter/src/main.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from modules.image_parser import (parse_image, parse_whole_directory)
|
||||
from modules.argument_parser import (generate_argument_parser)
|
||||
|
||||
if __name__ == "__main__":
|
||||
arg_parser = generate_argument_parser()
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
print(args, args.extension)
|
||||
|
||||
# Parse directory
|
||||
if (args.directory != None):
|
||||
parse_whole_directory(args.directory, args.output, args.height, args.width, args.extension)
|
||||
|
||||
# Parse individual files
|
||||
if (args.files != None):
|
||||
for file in args.files:
|
||||
parse_image(file, args.output, args.height, args.width, args.extension)
|
||||
|
||||
11
image-converter/src/modules/argument_parser.py
Normal file
11
image-converter/src/modules/argument_parser.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import argparse
|
||||
|
||||
def generate_argument_parser():
|
||||
parser = argparse.ArgumentParser(prog="Image Processor", description="A simple image format convert and resize tool.", epilog="Use any combination of arguments.")
|
||||
parser.add_argument("-H", "--height", type=int, help="max height for vertical images")
|
||||
parser.add_argument("-W", "--width", type=int, help="max width for horizontal images")
|
||||
parser.add_argument("-e", "--extension", type=str, default="png",help="extension of the processed files")
|
||||
parser.add_argument("-d", "--directory", type=str, help="directory of files to process")
|
||||
parser.add_argument("-f", "--files", nargs="+", help="list of files to process")
|
||||
parser.add_argument("-o", "--output", type=str, default="./",help="directory for the output files")
|
||||
return parser
|
||||
36
image-converter/src/modules/ascii_parser.py
Normal file
36
image-converter/src/modules/ascii_parser.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from PIL import Image
|
||||
|
||||
def convert_ascii(src: str, width: int, weight: int, charset: [str]):
|
||||
# Open an image file
|
||||
img = Image.open(src)
|
||||
|
||||
gray_scale = len(charset)
|
||||
print("__char", charset, gray_scale)
|
||||
|
||||
img_width, img_height = img.size
|
||||
px = img.load()
|
||||
|
||||
# Use image parser to take resolution down
|
||||
# Convert to grayscale
|
||||
# Calc color differences
|
||||
# Stablish defined character based on the color variance
|
||||
|
||||
min_color = 255
|
||||
max_color = 0
|
||||
|
||||
for x in range(img_width):
|
||||
for y in range(img_height):
|
||||
# r, g, b = px[x, y]
|
||||
gray_px = sum(px[x, y]) // 3
|
||||
px[x,y] = (gray_px, gray_px, gray_px)
|
||||
|
||||
if (min_color > gray_px):
|
||||
min_color = gray_px
|
||||
elif (max_color < gray_px):
|
||||
max_color = gray_px
|
||||
|
||||
print("Pixels", px[0,0], min_color, max_color) # --> outputs a three-dimensional array, rgb
|
||||
|
||||
|
||||
convert_ascii('src/assets/fee.jpg', 100, 100, ["a", "b", "c"])
|
||||
convert_ascii('src/assets/clear.jpg', 100, 100, ["a", "b", "c"])
|
||||
43
image-converter/src/modules/image_parser.py
Normal file
43
image-converter/src/modules/image_parser.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from PIL import Image
|
||||
|
||||
import os
|
||||
import math
|
||||
|
||||
def parse_image(src: str, target_src: str, max_vertical_size_px: int, max_horizontal_size_px: int, target_extension: str):
|
||||
if (src == None):
|
||||
return
|
||||
if (target_extension == None):
|
||||
target_extension = "png"
|
||||
rawImage = Image.open(src)
|
||||
|
||||
if (rawImage.height > rawImage.width):
|
||||
if (max_vertical_size_px == None or max_vertical_size_px < 1):
|
||||
max_vertical_size_px = rawImage.height
|
||||
target_height = max_vertical_size_px
|
||||
target_width = math.ceil(rawImage.width * max_vertical_size_px / rawImage.height)
|
||||
else:
|
||||
if (max_horizontal_size_px == None or max_horizontal_size_px < 1):
|
||||
max_horizontal_size_px = rawImage.width
|
||||
target_width = max_horizontal_size_px
|
||||
target_height = math.ceil(rawImage.height * max_horizontal_size_px / rawImage.width)
|
||||
|
||||
rawImage = rawImage.resize((target_width, target_height))
|
||||
|
||||
filename = os.path.basename(src)
|
||||
last_dot = filename.rfind(".")
|
||||
filename = filename[:last_dot] + "." + target_extension
|
||||
if (target_src == None):
|
||||
target_src = os.path.abspath(os.path.dirname(src))
|
||||
else:
|
||||
target_src = os.path.abspath(target_src)
|
||||
full_path = os.path.join(target_src, filename)
|
||||
rawImage.save(full_path)
|
||||
|
||||
def parse_whole_directory(dir_src: str, target_src: str, max_vertical_size_px: int, max_horizontal_size_px: int, target_extension: str):
|
||||
for file_path in get_file_path_iter(dir_src):
|
||||
parse_image(file_path,target_src, max_vertical_size_px, max_horizontal_size_px, target_extension)
|
||||
|
||||
def get_file_path_iter(directory):
|
||||
for dirpath,_,filenames in os.walk(directory):
|
||||
for f in filenames:
|
||||
yield os.path.abspath(os.path.join(dirpath, f))
|
||||
4
image-converter/src/modules/test/test_ascii.py
Normal file
4
image-converter/src/modules/test/test_ascii.py
Normal file
@@ -0,0 +1,4 @@
|
||||
class TestAsciiConvert:
|
||||
def test_pixel_parse(self):
|
||||
print("__testing")
|
||||
assert 1 + 1 == 2
|
||||
Reference in New Issue
Block a user