1
0
mirror of https://github.com/ciromattia/kcc synced 2025-12-12 17:26:23 +00:00

Mainly adhere to PEP 8 code style (http://www.python.org/dev/peps/pep-0008/)

Add some commented code for working on Panel view enhancement and natural sorting.
This commit is contained in:
Ciro Mattia Gonano
2013-03-01 16:22:11 +01:00
parent 1edbe389ba
commit 32a0038c49
3 changed files with 142 additions and 132 deletions

View File

@@ -14,22 +14,23 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
__license__ = 'ISC'
__license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>'
__docformat__ = 'restructuredtext en'
import os
class CBxArchive:
def __init__(self, origFileName):
self.cbxexts = ['.zip','.cbz','.rar','.cbr']
self.cbxexts = ['.zip', '.cbz', '.rar', '.cbr']
self.origFileName = origFileName
self.filename = os.path.splitext(origFileName)
def isCbxFile(self):
return self.filename[1].lower() in self.cbxexts
def extractCBZ(self,targetdir):
def extractCBZ(self, targetdir):
try:
from zipfile import ZipFile
except ImportError:
@@ -40,13 +41,13 @@ class CBxArchive:
pass # skip MacOS special files
elif f.endswith('/'):
try:
os.makedirs(os.path.join(targetdir,f))
os.makedirs(os.path.join(targetdir, f))
except:
pass #the dir exists so we are going to extract the images only.
pass # the dir exists so we are going to extract the images only.
else:
cbzFile.extract(f, targetdir)
def extractCBR(self,targetdir):
def extractCBR(self, targetdir):
try:
import rarfile
except ImportError:
@@ -55,24 +56,24 @@ class CBxArchive:
cbrFile = rarfile.RarFile(self.origFileName)
for f in cbrFile.namelist():
if f.startswith('__MACOSX') or f.endswith('.DS_Store'):
pass # skip MacOS special files
pass # skip MacOS special files
elif f.endswith('/'):
try:
os.makedirs(os.path.join(targetdir,f))
except:
pass #the dir exists so we are going to extract the images only.
pass # the dir exists so we are going to extract the images only.
else:
cbrFile.extract(f, targetdir)
def extract(self,targetdir):
def extract(self, targetdir):
if '.cbr' == self.filename[1].lower() or '.rar' == self.filename[1].lower():
self.extractCBR(targetdir)
elif '.cbz' == self.filename[1].lower() or '.zip' == self.filename[1].lower():
self.extractCBZ(targetdir)
dir = os.listdir(targetdir)
if len(dir) == 1 and os.path.isdir(os.path.join(targetdir,dir[0])):
adir = os.listdir(targetdir)
if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])):
import shutil
for f in os.listdir(os.path.join(targetdir,dir[0])):
shutil.move(os.path.join(targetdir,dir[0],f),targetdir)
os.rmdir(os.path.join(targetdir,dir[0]))
for f in os.listdir(os.path.join(targetdir, adir[0])):
shutil.move(os.path.join(targetdir, adir[0], f), targetdir)
os.rmdir(os.path.join(targetdir, adir[0]))
return targetdir

View File

@@ -16,16 +16,22 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
__license__ = 'ISC'
__license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>'
__docformat__ = 'restructuredtext en'
from Tkinter import *
import tkFileDialog, tkMessageBox, ttk
import comic2ebook, kindlestrip
import tkFileDialog
import tkMessageBox
import ttk
import comic2ebook
import kindlestrip
from image import ProfileData
from subprocess import call, Popen, PIPE, STDOUT
import os, shutil, stat
from subprocess import call
import os
import shutil
import stat
class MainWindow:
@@ -34,9 +40,9 @@ class MainWindow:
self.refresh_list()
def open_files(self):
filetypes = [('all files', '.*'), ('Comic files', ('*.cbr','*.cbz','*.zip','*.rar','*.pdf'))]
f = tkFileDialog.askopenfilenames(title="Choose a file...",filetypes=filetypes)
if not isinstance(f,tuple):
filetypes = [('all files', '.*'), ('Comic files', ('*.cbr', '*.cbz', '*.zip', '*.rar', '*.pdf'))]
f = tkFileDialog.askopenfilenames(title="Choose a file...", filetypes=filetypes)
if not isinstance(f, tuple):
try:
import re
f = re.findall('\{(.*?)\}', f)
@@ -58,58 +64,58 @@ class MainWindow:
def refresh_list(self):
self.filelocation.config(state=NORMAL)
self.filelocation.delete(0, END)
for file in self.filelist:
self.filelocation.insert(END, file)
for afile in self.filelist:
self.filelocation.insert(END, afile)
self.filelocation.config(state=DISABLED)
def initialize(self):
self.filelocation = Listbox(self.master)
self.filelocation.grid(row=0,columnspan=4,sticky=W+E+N+S)
self.filelocation.grid(row=0, columnspan=4, sticky=W + E + N + S)
self.refresh_list()
self.clear_file = Button(self.master, text="Clear files", command=self.clear_files)
self.clear_file.grid(row=4,column=0,rowspan=3)
self.clear_file.grid(row=4, column=0, rowspan=3)
self.open_file = Button(self.master, text="Add files...", command=self.open_files)
self.open_file.grid(row=4,column=1,rowspan=3)
self.open_file.grid(row=4, column=1, rowspan=3)
self.open_folder = Button(self.master, text="Add folder...", command=self.open_folder)
self.open_folder.grid(row=4,column=2,rowspan=3)
self.open_folder.grid(row=4, column=2, rowspan=3)
self.profile = StringVar()
profiles = sorted(ProfileData.ProfileLabels.iterkeys())
self.profile.set(profiles[-1])
w = apply(OptionMenu, (self.master, self.profile) + tuple(profiles))
w.grid(row=1,column=3)
w.grid(row=1, column=3)
self.options = {
'epub_only':IntVar(None,0),
'image_preprocess':IntVar(None,1),
'cut_page_numbers':IntVar(None,1),
'mangastyle':IntVar(None,0),
'image_upscale':IntVar(None,0),
'image_stretch':IntVar(None,0),
'black_borders':IntVar(None,0)
'epub_only': IntVar(None, 0),
'image_preprocess': IntVar(None, 1),
'cut_page_numbers': IntVar(None, 1),
'mangastyle': IntVar(None, 0),
'image_upscale': IntVar(None, 0),
'image_stretch': IntVar(None, 0),
'black_borders': IntVar(None, 0)
}
self.optionlabels = {
'epub_only':"Generate ePub only (does not call 'kindlegen')",
'image_preprocess':"Apply image optimizations",
'cut_page_numbers':"Cut page numbers",
'mangastyle':"Split manga-style (right-to-left reading)",
'image_upscale':"Allow image upscaling",
'image_stretch':"Stretch images",
'black_borders':"Use black borders"
'epub_only': "Generate ePub only (does not call 'kindlegen')",
'image_preprocess': "Apply image optimizations",
'cut_page_numbers': "Cut page numbers",
'mangastyle': "Split manga-style (right-to-left reading)",
'image_upscale': "Allow image upscaling",
'image_stretch': "Stretch images",
'black_borders': "Use black borders"
}
for key in self.options:
aCheckButton = Checkbutton(self.master, text=self.optionlabels[key],variable=self.options[key])
aCheckButton.grid(column=3,sticky='w')
aCheckButton = Checkbutton(self.master, text=self.optionlabels[key], variable=self.options[key])
aCheckButton.grid(column=3, sticky='w')
self.progressbar = ttk.Progressbar(orient=HORIZONTAL, length=200, mode='determinate')
self.submit = Button(self.master, text="Execute!", command=self.start_conversion, fg="red")
self.submit.grid(column=3)
self.progressbar.grid(column=0,columnspan=4,sticky=W+E+N+S)
self.progressbar.grid(column=0, columnspan=4, sticky=W + E + N + S)
# self.debug = Listbox(self.master)
# self.debug.grid(row=9,columnspan=4,sticky=W+E+N+S)
# self.debug.insert(END, os.environ['PATH'])
self.notelabel = Label(self.master,
text="GUI can seem frozen while converting, kindly wait until some message appears!")
self.notelabel.grid(column=0, columnspan=4, sticky=W + E + N + S)
def start_conversion(self):
self.progressbar.start()
@@ -120,9 +126,8 @@ class MainWindow:
if len(self.filelist) < 1:
tkMessageBox.showwarning('No file selected', "You should really select some files to convert...")
return
tkMessageBox.showinfo('Starting conversion', "KCC will now start converting files. GUI can seem frozen, kindly wait until some message appears!")
profilekey = ProfileData.ProfileLabels[self.profile.get()]
argv = ["-p",profilekey]
argv = ["-p", profilekey]
if self.options['image_preprocess'].get() == 0:
argv.append("--no-image-processing")
if self.options['cut_page_numbers'].get() == 0:
@@ -138,8 +143,8 @@ class MainWindow:
errors = False
for entry in self.filelist:
self.master.update()
subargv = list(argv)
try:
subargv = list(argv)
subargv.append(entry)
epub_path = comic2ebook.main(subargv)
except Exception, err:
@@ -147,7 +152,7 @@ class MainWindow:
errors = True
continue
if self.options['epub_only'] == 1:
continue;
continue
try:
retcode = call("kindlegen \"" + epub_path + "\"", shell=True)
if retcode < 0:
@@ -158,9 +163,9 @@ class MainWindow:
tkMessageBox.showerror('Error kindlegen', "Error on file %s:\n%s" % (epub_path, e))
errors = True
continue
mobifile = epub_path.replace('.epub', '.mobi')
try:
mobifile = epub_path.replace('.epub','.mobi')
shutil.move(mobifile,mobifile + '_tostrip')
shutil.move(mobifile, mobifile + '_tostrip')
kindlestrip.main((mobifile + '_tostrip', mobifile))
os.remove(mobifile + '_tostrip')
except Exception, err:
@@ -178,7 +183,7 @@ class MainWindow:
"Conversion successfully done!"
)
def remove_readonly(self, fn, path, excinfo):
def remove_readonly(self, fn, path):
if fn is os.rmdir:
os.chmod(path, stat.S_IWRITE)
os.rmdir(path)
@@ -191,5 +196,3 @@ class MainWindow:
self.master = master
self.master.title(title)
self.initialize()

View File

@@ -15,13 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__license__ = 'ISC'
__license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>'
__docformat__ = 'restructuredtext en'
import os
from PIL import Image, ImageOps, ImageDraw, ImageStat
class ImageFlags:
Orient = 1 << 0
Resize = 1 << 1
@@ -86,17 +87,18 @@ class ProfileData:
}
ProfileLabels = {
"Kindle" : 'K1',
"Kindle 2" : 'K2',
"Kindle 3/Keyboard" : 'K3',
"Kindle 4/NT/Touch" : 'K4',
"Kindle Paperwhite" : 'KHD',
"Kindle DX" : 'KDX',
"Kindle DXG" : 'KDXG'
"Kindle": 'K1',
"Kindle 2": 'K2',
"Kindle 3/Keyboard": 'K3',
"Kindle 4/NT/Touch": 'K4',
"Kindle Paperwhite": 'KHD',
"Kindle DX": 'KDX',
"Kindle DXG": 'KDXG'
}
class ComicPage:
def __init__(self,source,device):
def __init__(self, source, device):
try:
self.profile_label, self.size, self.palette = ProfileData.Profiles[device]
except KeyError:
@@ -108,13 +110,13 @@ class ComicPage:
raise RuntimeError('Cannot read image file %s' % source)
self.image = self.image.convert('RGB')
def saveToDir(self,targetdir):
def saveToDir(self, targetdir):
filename = os.path.basename(self.origFileName)
try:
self.image = self.image.convert('L') # convert to grayscale
self.image.save(os.path.join(targetdir,filename),"JPEG")
self.image.save(os.path.join(targetdir, filename), "JPEG")
except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' %(targetdir,e))
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
def optimizeImage(self):
self.image = ImageOps.autocontrast(self.image)
@@ -122,12 +124,12 @@ class ComicPage:
def quantizeImage(self):
colors = len(self.palette) / 3
if colors < 256:
self.palette = self.palette + self.palette[:3] * (256 - colors)
self.palette += self.palette[:3] * (256 - colors)
palImg = Image.new('P', (1, 1))
palImg.putpalette(self.palette)
self.image = self.image.quantize(palette=palImg)
def resizeImage(self,upscale=False, stretch=False, black_borders=False):
def resizeImage(self, upscale=False, stretch=False, black_borders=False):
method = Image.ANTIALIAS
if black_borders:
fill = 'black'
@@ -138,23 +140,23 @@ class ComicPage:
# do not upscale but center image in a device-sized image
borderw = (self.size[0] - self.image.size[0]) / 2
borderh = (self.size[1] - self.image.size[1]) / 2
self.image = ImageOps.expand(self.image, border=(borderw,borderh), fill=fill)
self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=fill)
return self.image
else:
method = Image.NEAREST
if stretch: # if stretching call directly resize() without other considerations.
self.image = self.image.resize(self.size,method)
if stretch: # if stretching call directly resize() without other considerations.
self.image = self.image.resize(self.size, method)
return self.image
ratioDev = float(self.size[0]) / float(self.size[1])
if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
diff = int(self.image.size[1] * ratioDev) - self.image.size[0]
self.image = ImageOps.expand(self.image, border=(diff/2,0), fill=fill)
self.image = ImageOps.expand(self.image, border=(diff / 2, 0), fill=fill)
elif (float(self.image.size[0]) / float(self.image.size[1])) > ratioDev:
diff = int(self.image.size[0] / ratioDev) - self.image.size[1]
self.image = ImageOps.expand(self.image, border=(0,diff/2), fill=fill)
self.image = ImageOps.fit(self.image, self.size, method = method, centering = (0.5,0.5))
self.image = ImageOps.expand(self.image, border=(0, diff / 2), fill=fill)
self.image = ImageOps.fit(self.image, self.size, method=method, centering=(0.5, 0.5))
return self.image
def splitPage(self, targetdir, righttoleft=False):
@@ -165,12 +167,12 @@ class ComicPage:
if (width > height) != (dstwidth > dstheight):
if width > height:
# source is landscape, so split by the width
leftbox = (0, 0, width/2, height)
rightbox = (width/2, 0, width, height)
leftbox = (0, 0, width / 2, height)
rightbox = (width / 2, 0, width, height)
else:
# source is portrait and target is landscape, so split by the height
leftbox = (0, 0, width, height/2)
rightbox = (0, height/2, width, height)
leftbox = (0, 0, width, height / 2)
rightbox = (0, height / 2, width, height)
filename = os.path.splitext(os.path.basename(self.origFileName))
fileone = targetdir + '/' + filename[0] + '-1' + filename[1]
filetwo = targetdir + '/' + filename[0] + '-2' + filename[1]
@@ -185,8 +187,8 @@ class ComicPage:
pagetwo.save(filetwo)
os.remove(self.origFileName)
except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' %(targetdir,e))
return fileone,filetwo
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
return fileone, filetwo
else:
return None
@@ -213,56 +215,57 @@ class ComicPage:
draw.rectangle([corner1, corner2], outline=foreground)
self.image = imageBg
def cutPageNumber(self):
widthImg, heightImg = self.image.size
delta = 2
diff = delta
fixedThreshold = 5
if ImageStat.Stat(self.image).var[0] < 2*fixedThreshold:
if ImageStat.Stat(self.image).var[0] < 2 * fixedThreshold:
return self.image
while ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg))).var[0] < fixedThreshold\
and diff < heightImg:
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < fixedThreshold\
and diff < heightImg:
diff += delta
diff -= delta
pageNumberCut1 = diff
if diff<delta:
diff=delta
oldStat=ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg))).var[0]
if diff < delta:
diff = delta
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta
while ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg))).var[0] - oldStat > 0\
and diff < heightImg/4:
oldStat=ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg))).var[0]
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] - oldStat > 0\
and diff < heightImg / 4:
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta
diff -= delta
pageNumberCut2 = diff
diff += delta
oldStat=ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg-pageNumberCut2))).var[0]
while ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg-pageNumberCut2))).var[0] < fixedThreshold+oldStat\
and diff < heightImg/4:
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]\
< fixedThreshold + oldStat and diff < heightImg / 4:
diff += delta
diff -= delta
pageNumberCut3 = diff
delta = 5
diff = delta
while ImageStat.Stat(self.image.crop((0,heightImg-pageNumberCut2,diff,heightImg))).var[0] < fixedThreshold and diff < widthImg:
while ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut2, diff, heightImg))).var[0] < fixedThreshold\
and diff < widthImg:
diff += delta
diff -= delta
pageNumberX1 = diff
diff = delta
while ImageStat.Stat(self.image.crop((widthImg-diff,heightImg-pageNumberCut2,widthImg,heightImg))).var[0] < fixedThreshold and diff < widthImg:
while ImageStat.Stat(self.image.crop((widthImg - diff, heightImg - pageNumberCut2,
widthImg, heightImg))).var[0] < fixedThreshold and diff < widthImg:
diff += delta
diff -= delta
pageNumberX2=widthImg-diff
if pageNumberCut3-pageNumberCut1 > 2*delta\
and float(pageNumberX2-pageNumberX1)/float(pageNumberCut2-pageNumberCut1) <= 9.0\
and ImageStat.Stat(self.image.crop((0,heightImg-pageNumberCut3,widthImg,heightImg))).var[0] / ImageStat.Stat(self.image).var[0] < 0.1\
and pageNumberCut3 < heightImg/4-delta:
diff=pageNumberCut3
pageNumberX2 = widthImg - diff
if pageNumberCut3 - pageNumberCut1 > 2 * delta\
and float(pageNumberX2 - pageNumberX1) / float(pageNumberCut2 - pageNumberCut1) <= 9.0\
and ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut3, widthImg, heightImg))).var[0]\
/ ImageStat.Stat(self.image).var[0] < 0.1\
and pageNumberCut3 < heightImg / 4 - delta:
diff = pageNumberCut3
else:
diff=pageNumberCut1
self.image = self.image.crop((0,0,widthImg,heightImg-diff))
diff = pageNumberCut1
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
return self.image
def cropWhiteSpace(self, threshold):
@@ -270,68 +273,71 @@ class ComicPage:
delta = 10
diff = delta
# top
while ImageStat.Stat(self.image.crop((0,0,widthImg,diff))).var[0] < threshold and diff < heightImg:
while ImageStat.Stat(self.image.crop((0, 0, widthImg, diff))).var[0] < threshold and diff < heightImg:
diff += delta
diff -= delta
# print "Top crop: %s"%diff
self.image = self.image.crop((0,diff,widthImg,heightImg))
self.image = self.image.crop((0, diff, widthImg, heightImg))
widthImg, heightImg = self.image.size
diff = delta
# left
while ImageStat.Stat(self.image.crop((0,0,diff,heightImg))).var[0] < threshold and diff < widthImg:
while ImageStat.Stat(self.image.crop((0, 0, diff, heightImg))).var[0] < threshold and diff < widthImg:
diff += delta
diff -= delta
# print "Left crop: %s"%diff
self.image = self.image.crop((diff,0,widthImg,heightImg))
self.image = self.image.crop((diff, 0, widthImg, heightImg))
widthImg, heightImg = self.image.size
diff = delta
# down
while ImageStat.Stat(self.image.crop((0,heightImg-diff,widthImg,heightImg))).var[0] < threshold\
and diff < heightImg:
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < threshold\
and diff < heightImg:
diff += delta
diff -= delta
# print "Down crop: %s"%diff
self.image = self.image.crop((0,0,widthImg,heightImg-diff))
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
widthImg, heightImg = self.image.size
diff = delta
# right
while ImageStat.Stat(self.image.crop((widthImg-diff,0,widthImg,heightImg))).var[0] < threshold\
and diff < widthImg:
while ImageStat.Stat(self.image.crop((widthImg - diff, 0, widthImg, heightImg))).var[0] < threshold\
and diff < widthImg:
diff += delta
diff -= delta
# print "Right crop: %s"%diff
self.image = self.image.crop((0,0 ,widthImg-diff,heightImg))
self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
# print "New size: %sx%s"%(self.image.size[0],self.image.size[1])
return self.image
def addProgressbar(self, file_number, files_totalnumber, size, howoften):
if file_number//howoften!=float(file_number)/howoften:
if file_number // howoften != float(file_number) / howoften:
return self.image
white = (255,255,255)
black = (0,0,0)
white = (255, 255, 255)
black = (0, 0, 0)
widthDev, heightDev = size
widthImg, heightImg = self.image.size
pastePt = (
max(0, (widthDev - widthImg) / 2),
max(0, (heightDev - heightImg) / 2)
)
imageBg = Image.new('RGB',size,white)
)
imageBg = Image.new('RGB', size, white)
imageBg.paste(self.image, pastePt)
self.image = imageBg
widthImg, heightImg = self.image.size
draw = ImageDraw.Draw(self.image)
#Black rectangle
draw.rectangle([(0,heightImg-3), (widthImg,heightImg)], outline=black, fill=black)
draw.rectangle([(0, heightImg - 3), (widthImg, heightImg)], outline=black, fill=black)
#White rectangle
draw.rectangle([(widthImg*file_number/files_totalnumber,heightImg-3), (widthImg-1,heightImg)], outline=black, fill=white)
draw.rectangle([(widthImg * file_number / files_totalnumber, heightImg - 3), (widthImg - 1, heightImg)],
outline=black, fill=white)
#Making notches
for i in range(1,10):
if i <= (10*file_number/files_totalnumber):
notch_colour=white #White
for i in range(1, 10):
if i <= (10 * file_number / files_totalnumber):
notch_colour = white # White
else:
notch_colour=black #Black
draw.line([(widthImg*float(i)/10,heightImg-3), (widthImg*float(i)/10,heightImg)],fill=notch_colour)
notch_colour = black # Black
draw.line([(widthImg * float(i) / 10, heightImg - 3), (widthImg * float(i) / 10, heightImg)],
fill=notch_colour)
#The 50%
if i==5:
draw.rectangle([(widthImg/2-1,heightImg-5), (widthImg/2+1,heightImg)],outline=black,fill=notch_colour)
if i == 5:
draw.rectangle([(widthImg / 2 - 1, heightImg - 5), (widthImg / 2 + 1, heightImg)],
outline=black, fill=notch_colour)
return self.image