diff --git a/src/gui/imgview.py b/src/gui/imgview.py new file mode 100644 --- /dev/null +++ b/src/gui/imgview.py @@ -0,0 +1,91 @@ +import logging as log + +from PIL import ImageTk + +import config +from .resizablecanvas import ResizableCanvas +from corners import Corners +from epoint import EPoint +from grid import Grid +import imageanalyzer + + +class ImgView(ResizableCanvas): + def __init__(self,master=None,parent=None): + super().__init__(master) + + self._parent=parent + self._corners=Corners() + self._boardGrid=None + + self._img=None + self._tkImg=None + self._imgSizeCoef=1 + self._imgShift=EPoint(0,0) + + self.configure(width=480,height=360) + self.bind('<1>',lambda e: self.addCorner(e.x,e.y)) + + ## Redraws the current image and its overlay. + def redraw(self): + self.delete("all") + + if self._img: + img=self._img.copy() + img.thumbnail((int(self._width),int(self._height))) + self._tkImg=ImageTk.PhotoImage(img) # just to save the image from the garbage collector + self.create_image(self._width//2, self._height//2, anchor="center", image=self._tkImg) + + for corner in self._corners.corners: + self.markPoint(corner.x,corner.y) + + if self._boardGrid!=None and config.gui.showGrid: + for r in range(19): + a=self._boardGrid.intersections[r][0] + b=self._boardGrid.intersections[r][-1] + self.create_line(a.x,a.y,b.x,b.y,fill='#00ff00') + for c in range(19): + a=self._boardGrid.intersections[0][c] + b=self._boardGrid.intersections[-1][c] + self.create_line(a.x,a.y,b.x,b.y,fill='#00ff00') + + if self._boardGrid!=None and config.gui.showBigPoints: + for r in range(19): + for c in range(19): + ((r1,c1),(r2,c2))=imageanalyzer.relevantRect(self._boardGrid.intersections[r][c], *(self._boardGrid.stoneSizeAt(r, c))) + self.create_rectangle(r1,c1,r2,c2,outline="#00ffff") + + def setImg(self,img): + w=int(self._width) + h=int(self._height) + wo,ho=img.size # o for original + widthRatio=wo/w + heightRatio=ho/h + self._imgSizeCoef=max(widthRatio,heightRatio) + # shift compensates possible horizontal or vertical empty margins from unmatching aspect ratios + self._imgShift=EPoint(wo-w*self._imgSizeCoef,ho-h*self._imgSizeCoef)/2 + + self._img=img + + ## Stores a grid corner located at x,y coordinates. + def addCorner(self,x,y): + self._corners.add(x,y) + log.debug("click on %d,%d",x,y) + log.debug("sizeCoef: %f, shift: %d,%d",self._imgSizeCoef,self._imgShift.x,self._imgShift.y) + if self._corners.canonizeOrder(): + # transform corners from show coordinates to real coordinates + log.debug(self._corners.corners) + self._boardGrid=Grid(self._corners.corners) + corners=[(c*self._imgSizeCoef+self._imgShift) for c in self._corners.corners] + self._parent.sendMsg("setCorners",(corners,)) + + self.redraw() + + ## Marks a point at the image with a green cross. Used for corners. + def markPoint(self,x,y): + self.create_line(x-3,y-3,x+4,y+4,fill="#00ff00") + self.create_line(x-3,y+3,x+4,y-4,fill="#00ff00") + + def _onResize(self,event): + super()._onResize(event) + self.redraw()