python-2.7 - 添加命令行参数以读取所有图像以创建调色板

标签 python-2.7 colors python-imaging-library glob

我的图像与 python 文件位于同一目录中,如下所示。 - 猫.png - 狗.png - 海龟.png - 花.png

目前我可以一次运行一个程序,如下所示 os.system('picol.py cat.png -s -d')

输出: color_cat.png(图像内有调色板)

但是我想对目录中的所有图像执行相同的操作,而不必在 shell 命令中逐一键入图像名称。如果文件夹中有 100 多个图像,我将必须键入所有 100 个图像一一命名,真是可笑。如果我可以双击 py 文件(下面附有)并立即运行所有内容,那就太方便了。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import sys
import colorgram
import argparse
from PIL import Image, ImageDraw, ImageFont
import os
from glob import glob


# The font directory is one level higher than this file.
FONT_DIR = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'fonts'
)


def get_font(fontname, size):
    try:
        font_object = ImageFont.truetype(
            os.path.join(FONT_DIR, fontname),
            size
        )
        return font_object
    except(OSError):
        print('Couldn\'t find font \'{}\''.format(fontname))
        print('Searched {}'.format(FONT_DIR))
        sys.exit()


def rgb_to_hex(value1, value2, value3):
    """
    Convert RGB color to hex color
    """
    for value in (value1, value2, value3):
        if not 0 <= value <= 255:
            raise ValueError('Value each slider must be ranges from 0 to 255')
    return {'hex_color': '#{0:02X}{1:02X}{2:02X}'.format(value1, value2,
            value3), 'link': 'http://www.color-hex.com/color/{0:02X}{1:02X}'
            '{2:02X}'.format(value1, value2, value3)}


def get_center_position_hor(canvas_height, image_in_h):
    """
    Get the correct position for an image to center it horizontally
    """
    if image_in_h < canvas_height:
        _canvas_mid = int(canvas_height / 2)
        _image_in_mid = int(image_in_h / 2)
        return _canvas_mid - _image_in_mid
    else:
        return 0


def get_center_position_ver(canvas_width, canvas_height, image_h_in):
    """
    Get the correct position for an image to center it vertically
    """
    _canvas_mid = int(canvas_height / 2)
    _image_in_mid = int(image_h_in / 2)
    return _canvas_mid - _image_in_mid


def write_out(out, filename):
    """
    Write 'out' to 'filename'
    """
    with open(filename, 'w') as fout:
        fout.write(out)


def main():
    parser = argparse.ArgumentParser()
    parser.prog = 'piccol'
    parser.description = 'Extract the ten most used colors in an image.'
    parser.add_argument('image', action='store')
    parser.add_argument('-s', '--save-image', help='Save image to a given file',
                        action='store_true', dest='save_image')
    parser.add_argument('-d', '--do-not-show', help='Do not show the image that '
                        'is made', action='store_false', dest='do_not_show_image')
    parser.add_argument('-st', '--save-text', help='Save text to a given file',
                        action='store_true', dest='save_text')
    args = parser.parse_args()


    # Get filename of input file
    _file_name = args.image.split('/')
    file_name = _file_name[len(_file_name) - 1]

    # Extract colors from an image.
    colors = colorgram.extract(args.image, 10)

    # Make a smaller version of the received image
    image_in = Image.open(args.image)
    image_in.thumbnail((500, 500))
    image_in_w, image_in_h = image_in.size

    # Set height for canvas. This is dynamic, but has no effect until one can
    # increase/decrease the number of colors to output
    canvas_height = int(len(colors)) * 50
    # ...but if the canvas height is smaller than image_in height, set canvas
    # height to image_in height
    if canvas_height < image_in_h:
        canvas_height = image_in_h

    # Testing shows that 750px wide should be enough
    canvas_width = 750
    img = Image.new('RGB', (canvas_width, canvas_height), 'white')
    # Paste image_in into canvas and find out center position
    center_hor = get_center_position_hor(canvas_height, image_in_h)
    img.paste(image_in, (0, center_hor))
    out = ImageDraw.Draw(img)

    # Get fonts
    title_fnt = get_font('OpenSans-Light.ttf', 30)
    hex_fnt = get_font('OpenSans-LightItalic.ttf', 24)

    # Write header
    title_w, title_h = title_fnt.getsize(file_name)
    center_ver = get_center_position_ver(canvas_width, canvas_height, title_w)
    out.text((center_ver, 7), file_name, font=title_fnt, fill=(0, 0, 0))

    write_output = 'Colors for \'{}\':'.format(file_name)

    hor = 0
    ver = 120

    i = 0
    for color in colors:
        color_out = rgb_to_hex(color.rgb.r, color.rgb.g, color.rgb.b)
        if i == 0:
            pass
        else:
            hor += 50
            ver += 50
        # rectangle(())
        out.rectangle((550, hor, 600, ver), fill=color_out['hex_color'])
        out.text((610, 7 + hor), color_out['hex_color'], font=hex_fnt,
                 fill=(0, 0, 0))
        i += 1
        if args.save_text:
            write_output += '\n{} - {}'.format(color_out['hex_color'],
                                               color_out['link'])
    out_file_name = file_name.split('.')[0]
    out_file_name = 'colors_{}'.format(out_file_name)
    if args.save_text:
        out_file_name += '.txt'
        write_out(write_output, out_file_name)
    if args.save_image:
        out_file_name += '.jpg'
        img.save(out_file_name)
    if args.do_not_show_image is not False:
        img.show()


if __name__ == '__main__':
    main()

最佳答案

将以下代码保存为同一文件夹中的 bulk_upload.py 并像这样调用它 os.system('bulk_upload.py *.png -s -d')

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import sys
import colorgram
import argparse
from PIL import Image, ImageDraw, ImageFont
import os
import glob

# The font directory is one level higher than this file.
FONT_DIR = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'fonts'
)


def get_font(fontname, size):
    try:
        font_object = ImageFont.truetype(
            os.path.join(FONT_DIR, fontname),
            size
        )
        return font_object
    except(OSError):
        print('Couldn\'t find font \'{}\''.format(fontname))
        print('Searched {}'.format(FONT_DIR))
        sys.exit()


def rgb_to_hex(value1, value2, value3):
    """
    Convert RGB color to hex color
    """
    for value in (value1, value2, value3):
        if not 0 <= value <= 255:
            raise ValueError('Value each slider must be ranges from 0 to 255')
    return {'hex_color': '#{0:02X}{1:02X}{2:02X}'.format(value1, value2,
            value3), 'link': 'http://www.color-hex.com/color/{0:02X}{1:02X}'
            '{2:02X}'.format(value1, value2, value3)}


def get_center_position_hor(canvas_height, image_in_h):
    """
    Get the correct position for an image to center it horizontally
    """
    if image_in_h < canvas_height:
        _canvas_mid = int(canvas_height / 2)
        _image_in_mid = int(image_in_h / 2)
        return _canvas_mid - _image_in_mid
    else:
        return 0


def get_center_position_ver(canvas_width, canvas_height, image_h_in):
    """
    Get the correct position for an image to center it vertically
    """
    _canvas_mid = int(canvas_height / 2)
    _image_in_mid = int(image_h_in / 2)
    return _canvas_mid - _image_in_mid


def write_out(out, filename):
    """
    Write 'out' to 'filename'
    """
    with open(filename, 'w') as fout:
        fout.write(out)

parser = argparse.ArgumentParser()
parser.prog = 'piccol'
parser.description = 'Extract the ten most used colors in an image.'
parser.add_argument('image', action='store')
parser.add_argument('-s', '--save-image', help='Save image to a given file',
                        action='store_true', dest='save_image')
parser.add_argument('-d', '--do-not-show', help='Do not show the image that '
                        'is made', action='store_false', dest='do_not_show_image')
parser.add_argument('-st', '--save-text', help='Save text to a given file',
                        action='store_true', dest='save_text')

args = parser.parse_args()

def process_image(image_path):
    """
    Process each image
    """
    # Get filename of input file
    _file_name = image_path.split('/')
    file_name = _file_name[len(_file_name) - 1]

    # Extract colors from an image.
    colors = colorgram.extract(image_path, 10)

    # Make a smaller version of the received image
    image_in = Image.open(image_path)
    image_in.thumbnail((500, 500))
    image_in_w, image_in_h = image_in.size

    # Set height for canvas. This is dynamic, but has no effect until one can
    # increase/decrease the number of colors to output
    canvas_height = int(len(colors)) * 50
    # ...but if the canvas height is smaller than image_in height, set canvas
    # height to image_in height
    if canvas_height < image_in_h:
        canvas_height = image_in_h

    # Testing shows that 750px wide should be enough
    canvas_width = 750
    img = Image.new('RGB', (canvas_width, canvas_height), 'white')
    # Paste image_in into canvas and find out center position
    center_hor = get_center_position_hor(canvas_height, image_in_h)
    img.paste(image_in, (0, center_hor))
    out = ImageDraw.Draw(img)

    # Get fonts
    title_fnt = get_font('OpenSans-Light.ttf', 30)
    hex_fnt = get_font('OpenSans-LightItalic.ttf', 24)

    # Write header
    title_w, title_h = title_fnt.getsize(file_name)
    center_ver = get_center_position_ver(canvas_width, canvas_height, title_w)
    out.text((center_ver, 7), file_name, font=title_fnt, fill=(0, 0, 0))

    write_output = 'Colors for \'{}\':'.format(file_name)

    hor = 0
    ver = 120

    i = 0
    for color in colors:
        color_out = rgb_to_hex(color.rgb.r, color.rgb.g, color.rgb.b)
        if i == 0:
            pass
        else:
            hor += 50
            ver += 50
        # rectangle(())
        out.rectangle((550, hor, 600, ver), fill=color_out['hex_color'])
        out.text((610, 7 + hor), color_out['hex_color'], font=hex_fnt,
                 fill=(0, 0, 0))
        i += 1
        if args.save_text:
            write_output += '\n{} - {}'.format(color_out['hex_color'],
                                               color_out['link'])
    out_file_name = file_name.split('.')[0]
    out_file_name = 'colors_{}'.format(out_file_name)
    if args.save_text:
        out_file_name += '.txt'
        write_out(write_output, out_file_name)
    if args.save_image:
        out_file_name += '.jpg'
        img.save(out_file_name)
    if args.do_not_show_image is not False:
        img.show()

def main():
    # Allowed extensions for bulk processing
    allowed_exts = ['*.png','*.jpg']
    for i in allowed_exts:
        if str(args.image).lower().endswith(i):
            for j in sorted(glob.glob(i)):
                file_path = os.path.join(os.path.dirname(args.image),j)
                print(file_path)
                process_image(file_path)
            break
    else:
        process_image(args.image)


if __name__ == '__main__':
    main()

P.S.我不对任何类型的系统中断/故障承担责任

关于python-2.7 - 添加命令行参数以读取所有图像以创建调色板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54779256/

相关文章:

python - 使用 python 从文件夹中一张一张打开图像?

python - 我应该在哪个文件中编写代码来调整 Django 上的图像文件大小?

python - 如何在不指定绝对路径的情况下使用 PIL.ImageFont.truetype 加载字体文件?

python - (Python) 如何将我的代码从 2.7 转换为 python 3

python - Python中根据多个条件返回列的方法

Android Edittext 线条颜色

android - 在不使用 ColorDrawable 的情况下从 textview 获取背景颜色(API 11)

python - 处理 csv 文件中的页脚行?

python-2.7 - 如何将对列表(到矩阵)转换为热图; Python

android - (Android)是否可以更改谷歌地图中多段线的形状?