from tkinter import * from tkinter import filedialog from zipfile import ZipFile as zf from PIL import Image, ImageTk import io,os class MangaReader: def __init__(self, master): self.master = master self.page = 0 self.total = 0 self.file = 'None' self.img = '' self.dir = 'None' master.title("Manga Reader") # tk window size and allow resize master.geometry("700x900") master.resizable(width=True, height=True) # Menu Bar self.menu = Menu(master) item = Menu(self.menu) item.add_command(label="Open", command=self.open_menu) item.add_separator() item.add_command(label="Exit", command=master.quit) self.menu.add_cascade(label="File", menu=item) root.config(menu=self.menu) self.buttonFrame = Frame(master) # forward/back buttons self.nextPg = Button(self.buttonFrame, text='>') self.nextPg.bind('', self.nextPage) self.nextPg.grid(row=1, column=2) self.buttonFrame.pack(side=BOTTOM) self.backPg = Button(self.buttonFrame, text='<') self.backPg.bind('', self.backPage) self.backPg.grid(row=1, column=0) # page counter self.pgcount = Label(self.buttonFrame, text= str(self.page) + " of " + str(self.total)) self.pgcount.grid(row=1, columns=1, columnspan=2) self.mangaTitle = Label(self.buttonFrame, text=os.path.basename(self.file)) self.mangaTitle.grid(row=0, column=1) # display image self.panel = Label(self.master, image=self.img) self.panel.pack() self.panel.bind('', self.redraw) # key bindings self.master.bind('', self.nextPage) self.master.bind('', self.backPage) self.master.bind('q', quit) def open_menu(self): # file dialog. reset page counts, call display Maanga passing in starting values if self.dir == 'None': mangaFile = filedialog.askopenfilename(initialdir = "/home/dan/Desktop/") else: mangaFile = filedialog.askopenfilename(initialdir = self.dir) self.file = mangaFile if self.file != '': self.page = 0 self.total = 0 self.mangaTitle.configure(text=os.path.basename(self.file)) self.dir = os.path.dirname(self.file) self.displayManga(self.file, 0) def displayManga(self, file, pg): #basewidth = 500 hsize = self.master.winfo_height() - self.buttonFrame.winfo_height() - self.menu.winfo_height() wsize = 500 with zf(file, 'r') as zip: # grab all the manga pages from the cbz file and sort them to put them in the correct order fl = zip.namelist() fl.sort() self.total = len(fl)-1 # grab the current page out of the array. treat it as byte data since it's still zipped. data = zip.read(fl[pg]) im = Image.open(io.BytesIO(data)) # I found the below code to maintain image ratios at https://stackoverflow.com/questions/273946/how-do-i-resize-an-image-using-pil-and-maintain-its-aspect-ratio # wpercent = (basewidth / float(im.size[0])) # hsize = int((float(im.size[1]) * float(wpercent))) #Modified above code to maintain height and scale width hpercent = (hsize / float(im.size[1])) widthsize = int((float(im.size[0] * float(hpercent)))) im = im.resize((widthsize, hsize), Image.ANTIALIAS) #convert to tkImage and update the on screen image. self.img = ImageTk.PhotoImage(im) self.panel.config(image=self.img) #finally update the current page count self.pgcount.configure(text=str(pg+1) + " of " + str(self.total)) self.panel.focus_set() self.master.config(width=wsize) def nextPage(self, event): self.page = self.page + 1 if self.page < self.total: self.displayManga(self.file, self.page) else: #reset self.page and doNothing self.page = self.page - 1 self.open_menu() def backPage(self, event): self.page = self.page - 1 if self.page >= 0: self.displayManga(self.file, self.page) else: #reset self.page and doNothing self.page = self.page + 1 def redraw(self, event): if self.file != 'None': self.displayManga(self.file, self.page) #initalize tk root=Tk() app = MangaReader(root) root.mainloop()