image_trimmer.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. try:
  2. import PIL
  3. except ImportError:
  4. import os
  5. print("Trying to Install required module: Pillow\n")
  6. os.system('python get-pip.py')
  7. os.system('python -m pip install Pillow')
  8. pass
  9. from PIL import Image
  10. ERROR_OK=0
  11. ERROR_LOAD_IMAGE_FAILED=1
  12. ERROR_IMAGE_NOT_RGBA=2
  13. ERROR_IMAGE_EMPTY=3
  14. ERROR_IMAGE_TRANSPARENT=4
  15. ERROR_SAVE_IMAGE_FAILED=5
  16. error_message = {
  17. ERROR_OK:"ok",
  18. ERROR_LOAD_IMAGE_FAILED:"load image failed",
  19. ERROR_IMAGE_NOT_RGBA:"image not rgba",
  20. ERROR_IMAGE_EMPTY:"image empty",
  21. ERROR_IMAGE_TRANSPARENT:"image transparent",
  22. ERROR_SAVE_IMAGE_FAILED:"save image failed",
  23. }
  24. def get_error_message(rv):
  25. return error_message[rv]
  26. pass
  27. def image_load(path,mode='RGBA'):
  28. try:
  29. img=Image.open(path)
  30. except:
  31. return ERROR_LOAD_IMAGE_FAILED,None
  32. if img.width==0 or img.height==0:
  33. return ERROR_IMAGE_EMPTY,img
  34. if img.mode!='RGBA':
  35. if mode=='RGBA':
  36. return ERROR_IMAGE_NOT_RGBA,img
  37. if mode=='ForceRGBA':
  38. img=img.convert('RGBA')
  39. return ERROR_OK,img
  40. def image_save(img,path):
  41. try:
  42. img.save(path)
  43. except:
  44. return ERROR_SAVE_IMAGE_FAILED
  45. return ERROR_OK
  46. def premultiply_alpha(img):
  47. img=img.convert('RGBa')
  48. img.mode='RGBA'
  49. return img
  50. def process_zero_alpha_pixels(img):
  51. neighbours=((-1,0),(+1,0),(0,-1),(0,+1))
  52. for y in range(1,img.height-1):
  53. for x in range(1,img.width-1):
  54. px=img.getpixel((x,y))
  55. if px[3]==0:
  56. colors=r=g=b=0
  57. for px in neighbours:
  58. px=img.getpixel((x+px[0],y+px[1]))
  59. if px[3]!=0:
  60. colors+=1
  61. r+=px[0]
  62. g+=px[1]
  63. b+=px[2]
  64. if colors>0:
  65. img.putpixel((x,y),(r//colors,g//colors,b//colors,0))
  66. else:
  67. img.putpixel((x,y),(0,0,0,0))
  68. return img
  69. def image_trimmer_process(src,trim=False,border=0,premultiplied=False,info_only=False):
  70. src_w=src.width
  71. src_h=src.height
  72. if trim:
  73. trimmed_rect=src.convert('RGBa').getbbox()
  74. if trimmed_rect is None:
  75. trimmed_rect=(0,0,0,0)
  76. else:
  77. trimmed_rect=(0,0,src_w,src_h)
  78. src_x=trimmed_rect[0]
  79. src_y=trimmed_rect[1]
  80. copy_w=trimmed_rect[2]-src_x
  81. copy_h=trimmed_rect[3]-src_y
  82. dest_w=copy_w+border*2
  83. dest_h=copy_h+border*2
  84. info=(src_w,src_h,dest_w,dest_h,src_x-border,src_y-border)
  85. if info_only:
  86. return ERROR_OK,None,info
  87. dest=Image.new('RGBA',(dest_w,dest_h),(0,0,0,0))
  88. trimmed=src.crop((src_x,src_y,src_x+copy_w,src_y+copy_h))
  89. dest.paste(trimmed,(border,border,border+copy_w,border+copy_h))
  90. if premultiplied:
  91. dest=premultiply_alpha(dest)
  92. else:
  93. dest=process_zero_alpha_pixels(dest)
  94. return ERROR_OK,dest,info
  95. def image_trimmer(src_path,dest_path=None,trim=False,border=0,premultiplied=False):
  96. rv,src=image_load(src_path)
  97. if rv==ERROR_IMAGE_NOT_RGBA:
  98. rv=image_save(src,dest_path)
  99. info=(src.width, src.height, src.width, src.height, 0.0, 0.0)
  100. return ERROR_OK,info
  101. if rv!=ERROR_OK:
  102. return rv,None
  103. rv,dest,info=image_trimmer_process(src,trim,border,premultiplied,dest_path is None)
  104. if rv!=ERROR_OK:
  105. return rv,info
  106. if dest is not None:
  107. rv=image_save(dest,dest_path)
  108. return rv,info