@@ -0,0 +1,478 @@
__version__ = " 1.0.0 "
# --- package ---
# --- color ---
import webcolors
# --- image ---
from pathlib import Path
from PIL import Image , ImageSequence
import cv2
import numpy as np
from io import BytesIO
# --- base64 ---
import base64
# --- common ---
import os
from datetime import datetime
import shutil
import time
import inspect
def hex_to_rgb ( hex_code ) :
""" Convert a hex code to RGB values. """
hex_code = hex_code . lstrip ( ' # ' )
return tuple ( int ( hex_code [ i : i + 2 ] , 16 ) for i in ( 0 , 2 , 4 ) )
def rgb_to_hex ( rgb_values ) :
""" Convert RGB values to a hex code. """
r , g , b = rgb_values
hex_code = " {:02x} {:02x} {:02x} " . format ( r , g , b )
return hex_code
def get_color_name ( rgb_values ) :
""" Return the name of the closest matching color. """
min_colors = { }
for key , name in webcolors . CSS3_HEX_TO_NAMES . items ( ) :
r_c , g_c , b_c = hex_to_rgb ( key )
rd = ( r_c - rgb_values [ 0 ] ) * * 2
gd = ( g_c - rgb_values [ 1 ] ) * * 2
bd = ( b_c - rgb_values [ 2 ] ) * * 2
min_colors [ ( rd + gd + bd ) ] = name
return min_colors [ min ( min_colors . keys ( ) ) ]
def image_resize ( import_path , import_raw_path , export_path , img , resize_target , resize_resolution ) :
image_ext = os . path . splitext ( img ) [ 1 ] . split ( ' . ' ) [ 1 ]
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( img , f " { import_path } { img_new_nm } " )
image = cv2 . imread ( f ' { import_path } { img_new_nm } ' )
img_width = image . shape [ 1 ]
img_height = image . shape [ 0 ]
if resize_target == ' W ' :
resize_height = int ( img_height * ( resize_resolution / img_width ) )
dim = ( resize_resolution , resize_height )
elif resize_target == ' H ' :
resize_width = int ( img_width * ( resize_resolution / img_height ) )
dim = ( resize_width , resize_resolution )
resized_img = cv2 . resize ( image , dim , interpolation = cv2 . INTER_AREA )
cv2 . imwrite ( f " { export_path } export_ { move_date } . { image_ext } " , resized_img )
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( f ' { import_path } { img_new_nm } ' , f " { import_raw_path } { img_new_nm } " )
time . sleep ( 1 )
return ' Success Image Resize '
def distribute_serveral_png ( import_path , import_raw_path , export_path , img ) :
image_ext = os . path . splitext ( img ) [ 1 ] . split ( ' . ' ) [ 1 ]
if image_ext == ' png ' :
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( img , f " { import_path } { img_new_nm } " )
pc_sizes = [ 16 , 24 , 32 , 48 , 64 ,
72 , 80 , 96 , 128 , 256 ]
and_sizes = [ 36 , 48 , 72 , 96 , 144 ]
ios_sizes = [ 20 , 29 , 40 , 40 , 48 ,
50 , 55 , 57 , 58 , 60 ,
60 , 72 , 76 , 80 , 87 ,
88 , 100 , 114 , 120 , 144 ,
152 , 167 , 172 , 180 , 196 ,
1024 ]
android_names = [ ' launcher_ldpi ' ,
' launcher_mdpi ' ,
' launcher_hdpi ' ,
' launcher_xhdpi ' ,
' launcher_xxhdpi ' ]
ios_names = [ ' icon-20 ' ,
' icon-29 ' ,
' icon-20@2x ' ,
' icon-40 ' ,
' icon-24@2x ' ,
' icon-50 ' ,
' icon-27.5@2x ' ,
' icon ' ,
' icon-29@2x ' ,
' icon-20@3x ' ,
' icon-60 ' ,
' icon-72 ' ,
' icon-76 ' ,
' icon-40@2x ' ,
' icon-83.5@2x ' ,
' icon-44@2x ' ,
' icon-50@2x ' ,
' icon@2x ' ,
' icon-60@2x ' ,
' icon-72@2x ' ,
' icon-76@2x ' ,
' icon-29@3x ' ,
' icon-86@2x ' ,
' icon-60@3x ' ,
' icon-98@2x ' ,
' icon-1024 ' ]
pc_icon_sizes = [ ( x , x ) for x in pc_sizes ]
and_icon_sizes = [ ( x , x ) for x in and_sizes ]
ios_icon_sizes = [ ( x , x ) for x in ios_sizes ]
image = Image . open ( f ' { import_path } { img_new_nm } ' )
for size in pc_icon_sizes :
exp_img_new_nm = f " { export_path } export_ { move_date } _ { str ( size [ 0 ] ) } . { image_ext } "
new_image = image . resize ( size )
new_image . save ( exp_img_new_nm )
new_logo_ico_filename = f " { export_path } export_ { move_date } _main.ico "
new_logo_ico = image . resize ( size )
new_logo_ico . save ( new_logo_ico_filename , format = " ICO " , quality = 100 )
for num , label in zip ( and_icon_sizes , android_names ) :
exp_img_new_nm = f " { export_path } export_ { move_date } _ { label } . { image_ext } "
new_image = image . resize ( num )
new_image . save ( exp_img_new_nm )
for num , label in zip ( ios_icon_sizes , ios_names ) :
exp_img_new_nm = f " { export_path } export_ { move_date } _ { label } . { image_ext } "
new_image = image . resize ( num )
new_image . save ( exp_img_new_nm )
time . sleep ( 1 )
shutil . move ( f ' { import_path } { img_new_nm } ' , f " { import_raw_path } { img_new_nm } " )
return ' Success Image to Icon '
else :
return ' Only Convert .PNG '
def bake_one_big_png_to_ico ( import_path , import_raw_path , export_path , img ) :
""" Converts one big PNG into one ICO file.
args:
sourcefile (str): Pathname of a PNG file.
targetfile (str): Pathname of the resulting ICO file.
sizes (list of int): Requested sizes of the resulting
icon file, defaults to [16, 32, 48].
Use this function if you have one big, square PNG file
and don’ t care about fine-tuning individual icon sizes.
Example::
sourcefile = " Path/to/high_resolution_logo_512x512.png "
targetfile = " Path/to/logo.ico "
sizes = [16, 24, 32, 48, 256]
bake_one_big_png_to_ico(sourcefile, targetfile, sizes)
"""
# if sizes is None:
# sizes = [16, 24, 32, 48, 256, 512]
# icon_sizes = [(x, x) for x in sizes]
# Image.open(sourcefile).save(targetfile, icon_sizes=icon_sizes)
image_ext = os . path . splitext ( img ) [ 1 ] . split ( ' . ' ) [ 1 ]
if image_ext == ' png ' :
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( img , f " { import_path } { img_new_nm } " )
sizes = [ 16 , 24 , 32 , 48 , 64 , 72 , 80 , 96 , 128 , 256 ]
icon_sizes = [ ( x , x ) for x in sizes ]
print ( icon_sizes )
# img_new_nm = '{}_{}{}'.format('import', move_date, f'.{image_ext}')
Image . open ( f ' { import_path } { img_new_nm } ' ) . save ( f " { export_path } export_ { move_date } .ico " , icon_sizes = icon_sizes )
# shutil.move(f'{import_path}{img_new_nm}', f"{import_raw_path}{img_new_nm}")
time . sleep ( 1 )
return ' Success Image to Icon '
else :
return ' Only Convert .PNG '
def bake_several_pngs_to_ico ( sourcefiles , targetfile ) :
""" Converts several PNG files into one ICO file.
args:
sourcefiles (list of str): A list of pathnames of PNG files.
targetfile (str): Pathname of the resulting ICO file.
Use this function if you want to have fine-grained control over
the resulting icon file, providing each possible icon resolution
individually.
Example::
sourcefiles = [
" Path/to/logo_16x16.png " ,
" Path/to/logo_32x32.png " ,
" Path/to/logo_48x48.png "
]
targetfile = " Path/to/logo.ico "
bake_several_pngs_to_ico(sourcefiles, targetfile)
"""
# Write the global header
number_of_sources = len ( sourcefiles )
data = bytes ( ( 0 , 0 , 1 , 0 , number_of_sources , 0 ) )
offset = 6 + number_of_sources * 16
# Write the header entries for each individual image
for sourcefile in sourcefiles :
img = Image . open ( sourcefile )
data + = bytes ( ( img . width , img . height , 0 , 0 , 1 , 0 , 32 , 0 , ) )
bytesize = Path ( sourcefile ) . stat ( ) . st_size
data + = bytesize . to_bytes ( 4 , byteorder = " little " )
data + = offset . to_bytes ( 4 , byteorder = " little " )
offset + = bytesize
# Write the individual image data
for sourcefile in sourcefiles :
data + = Path ( sourcefile ) . read_bytes ( )
# Save the icon file
Path ( targetfile ) . write_bytes ( data )
# def image_to_icon(import_path, import_raw_path, export_path, img, resize_resolution):
# image_ext = os.path.splitext(img)[1].split('.')[1]
#
# if image_ext == 'png':
# move_date = datetime.now().strftime('%y%m%d%H%M%S')
#
# img_new_nm = '{}_{}{}'.format('import', move_date, f'.{image_ext}')
#
# shutil.move(img, f"{import_path}{img_new_nm}")
#
# image = cv2.imread(f'{import_path}{img_new_nm}')
#
# resized_img = cv2.resize(image, (resize_resolution, resize_resolution))
#
# cv2.imwrite(f"{export_path}export_{image_ext}_{move_date}.ico", resized_img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
#
# move_date = datetime.now().strftime('%y%m%d%H%M%S')
#
# img_new_nm = '{}_{}{}'.format('import', move_date, f'.{image_ext}')
#
# shutil.move(f'{import_path}{img_new_nm}', f"{import_raw_path}{img_new_nm}")
#
# time.sleep(1)
#
# return 'Success Image to Icon'
#
# else:
# return 'Only Convert .PNG'
def image_to_extension ( import_path , import_raw_path , export_path , img , extension ) :
image_ext = os . path . splitext ( img ) [ 1 ] . split ( ' . ' ) [ 1 ]
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( img , f " { import_path } { img_new_nm } " )
if image_ext == ' gif ' :
# Load the GIF into a PIL Image object
image = Image . open ( f " { import_path } { img_new_nm } " )
if extension == ' png ' :
# Split the GIF into individual frames
frames = [ ]
for frame in ImageSequence . Iterator ( image ) :
frames . append ( frame . copy ( ) )
# Save each frame as an individual image file
for i , frame in enumerate ( frames ) :
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
frame . save ( f " { export_path } export_ { move_date } _ { i } . { extension } " , format = extension )
else :
image = image . convert ( " RGB " )
image . save ( f " { export_path } export_ { move_date } . { extension } " )
elif image_ext == ' png ' :
# Load the GIF into a PIL Image object
image = Image . open ( f " { import_path } { img_new_nm } " )
background = Image . new ( ' RGB ' , image . size , ( 255 , 255 , 255 ) )
background . paste ( image , mask = image )
background . save ( f " { export_path } export_ { move_date } . { extension } " )
else :
image = cv2 . imread ( f ' { import_path } { img_new_nm } ' )
cv2 . imwrite ( f " { export_path } export_ { move_date } . { extension } " , image )
shutil . move ( f ' { import_path } { img_new_nm } ' , f " { import_raw_path } { img_new_nm } " )
time . sleep ( 1 )
return ' Success Image Extension '
def base64_to_image ( import_raw_path , export_path , base64_str , txt_file , file ) :
try :
# ImageFile.LOAD_TRUNCATED_IMAGES = True
# Remove the "data:image/png;base64," prefix from the string
base64_string = base64_str . split ( ' , ' ) [ 1 ]
# Determine the length of the input string
length = len ( base64_string )
# Add padding characters if necessary
if length % 4 != 0 :
base64_string + = ' = ' * ( 4 - length % 4 )
# Decode the base64-encoded string into bytes
image_bytes = base64 . b64decode ( base64_string )
image = Image . open ( BytesIO ( image_bytes ) )
image_ext = base64_str . split ( ' / ' ) [ 1 ] . split ( ' ; ' ) [ 0 ]
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
if image_ext == ' gif ' :
if image . mode == " RGBA " :
# If the image has an alpha channel, convert it to RGB mode
image = image . convert ( " RGB " )
# Get the duration of each frame in the animation
frame_durations = [ ]
frames = [ ]
for frame in ImageSequence . Iterator ( image ) :
frame_durations . append ( frame . info . get ( " duration " , 100 ) ) # default duration is 100ms
frames . append ( frame . copy ( ) )
# Calculate the speed of the animation
average_duration = sum ( frame_durations ) / len ( frame_durations )
# if not average_duration == 0.0:
if average_duration != 0 :
speed = 1 / ( average_duration / 1000 ) # speed in frames per second
else :
speed = 0
frames [ 0 ] . save ( f " { export_path } export_ { move_date } . { image_ext } " , format = " GIF " , save_all = True , append_images = frames [ 1 : ] , duration = speed , loop = 0 )
# Check if the image is a PNG with transparency
elif image_ext == " png " :
# Convert the image to RGB mode to remove the alpha channel
image = image . convert ( " RGBA " )
# Save the image to file
image . save ( f " { export_path } export_ { move_date } . { image_ext } " )
else :
# Convert the bytes to a numpy array
image_array = np . frombuffer ( image_bytes , dtype = np . uint8 )
# Decode the numpy array into an OpenCV image
image = cv2 . imdecode ( image_array , cv2 . IMREAD_UNCHANGED )
# Save the image to a file
cv2 . imwrite ( f " { export_path } export_ { move_date } . { image_ext } " , image )
file . close ( )
image_ext = os . path . splitext ( txt_file ) [ 1 ] . split ( ' . ' ) [ 1 ]
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( txt_file , f " { import_raw_path } { img_new_nm } " )
time . sleep ( 1 )
return ' Success Image Convert '
except Exception as e :
return e
def image_to_base64 ( import_path , import_raw_path , export_path , img ) :
image_ext = os . path . splitext ( img ) [ 1 ] . split ( ' . ' ) [ 1 ]
move_date = datetime . now ( ) . strftime ( ' % y % m %d % H % M % S ' )
img_new_nm = ' {} _ {} {} ' . format ( ' import ' , move_date , f ' . { image_ext } ' )
shutil . move ( img , f " { import_path } { img_new_nm } " )
if image_ext == ' gif ' :
image_pil = Image . open ( f " { import_path } { img_new_nm } " )
# Convert the image to a sequence of frames
frames = [ ]
try :
while True :
frames . append ( image_pil . copy ( ) )
image_pil . seek ( len ( frames ) ) # skip to the next frame
except EOFError :
pass # end of sequence
# Encode the frames as GIF bytes
with BytesIO ( ) as output :
frames [ 0 ] . save ( output , format = ' GIF ' , save_all = True , append_images = frames [ 1 : ] )
image_bytes = output . getvalue ( )
elif image_ext == ' png ' :
image = Image . open ( f ' { import_path } { img_new_nm } ' )
if image . mode != ' RGBA ' :
image = image . convert ( ' RGBA ' )
buffer = BytesIO ( )
image . save ( buffer , format = ' PNG ' )
# Encode the image data as a base64 string
image_bytes = buffer . getvalue ( )
else :
# Load the image file
image = cv2 . imread ( f ' { import_path } { img_new_nm } ' )
# Convert the image to bytes
success , image_bytes = cv2 . imencode ( f ' . { image_ext } ' , image )
image_bytes = image_bytes . tobytes ( )
# Encode the bytes as a base64 string
base64_str = base64 . b64encode ( image_bytes ) . decode ( )
# Create the base64-encoded image string
base64_str_dec = f " data:image/ { image_ext } ;base64, " + base64_str
shutil . move ( f ' { import_path } { img_new_nm } ' , f " { import_raw_path } { img_new_nm } " )
time . sleep ( 1 )
# Print the base64-encoded image string
return base64_str_dec , ' Success Base64 Convert ' , f " { export_path } export_ { move_date } "