import logging from PIL import ImageTk import config from .resizablecanvas import ResizableCanvas from analyzer.corners import Corners from analyzer.epoint import EPoint from analyzer.grid import Grid import analyzer log=logging.getLogger(__name__) class ImgView(ResizableCanvas): def __init__(self,gui,master=None): super().__init__(master) self._gui=gui self._corners=Corners() self._boardGrid=None self._img=None self._tkImg=None 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: w,h=self._img.size ratio=min(self._width/w, self._height/h) img=self._img.resize((int(w*ratio),int(h*ratio))) self._tkImg=ImageTk.PhotoImage(img) # just to save the image from garbage collector self.create_image(self._width//2, self._height//2, anchor="center", image=self._tkImg) for c in self._corners: self.markPoint(c.x,c.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))=analyzer.relevantRect(self._boardGrid.intersections[r][c], *(self._boardGrid.stoneSizeAt(r, c))) self.create_rectangle(r1,c1,r2,c2,outline="#00ffff") def setImg(self,img): 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) if self._corners.is_canon(): # transform corners from show coordinates to real coordinates self._boardGrid=Grid(self._corners) corners=[self._transformPoint(c) for c in self._corners] self._gui.detector.setCorners(corners) self._gui.preview() 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 setUp(self): self.bind('<1>',lambda e: self.addCorner(e.x,e.y)) def setRecording(self): self.bind('<1>',lambda e: None) def isSet(self): return self._img is not None def _onResize(self,event): w=self._width super()._onResize(event) self._corners.scale(self._width/w) if len(self._corners)==4: self._boardGrid=Grid(self._corners) self.redraw() def _transformPoint(self,point): w=int(self._width) h=int(self._height) wo,ho=self._img.size # o for original log.debug("image: %sx%s, view: %sx%s",wo,ho,w,h) widthRatio=wo/w heightRatio=ho/h imgSizeCoef=max(widthRatio,heightRatio) # shift compensates possible horizontal or vertical empty margins from unmatching aspect ratios imgShift=EPoint(wo-w*imgSizeCoef,ho-h*imgSizeCoef)/2 return EPoint(self.canvasx(point.x),self.canvasy(point.y)) * imgSizeCoef + imgShift