Bonjour à tous,
nouvel épisode de mon application, j'ai réussi à effectuer un zoom malgré tout mes outils de fonctionne pas tous avec les niveaux de zoom différents de 100%.
Je vous remercie d'avance pour la lecture de mon post ^^ et vos conseils.
J'ai donc une combo box dans ma fênetre principale associée au signal:
qui appelle l'action zoom qui est en faite celle de la scène ( elle renvoie aussi l'index à mes outils pour connaitre le facteur de zoom).Code:
1
2
3
4
5
6
7
8
9
10
11
12 def onActivatedComboBox(self,text): if text == "300%": self.__actionZoom(3) if text=="200%": self.__actionZoom(2) if text == "100%": self.__actionZoom(1) if text == "75%": self.__actionZoom(0.75) if text == "50%": self.__actionZoom(0.5)
Puis, dans ma scène, l'action zoom.
GraphicsScene.py
Elle recrée pour chaque niveau de zoom un pixItem intégré à la scène.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 def zoomAction(self, factor ): print "zoom : ", factor #Not rezoom in same factor if factor == self.oldFactor: pass else : self.image = self.getCurrentImage() w_img, h_img = self.image.width(), self.image.height() w, h = w_img * factor, h_img * factor self.pixmap = QPixmap().fromImage(self.image.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) #Copy of the old one to keep the trace of the items before the zoom self.pixItem = PixmapItem(self,self._model) self.pixItem.setPixmap(self.pixmap) self.clear() self.addItem(self.pixItem) self.pixItem.undoView.hide() #Adjusting the size of the scene to the new zooming pixmap self.setSceneRect(0, 0, w, h) self.oldFactor = factor
Sachant que pixmapItem gère les actions. (j'arrive bientôt à mon problème lol)
PixmapItem.py
Mon souci est le suivant , j'ai un outil pipette qui fonctione bien avec le zoom,Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 ''' PixmapItem handles : + Mouses events + by calling the currentTool set in the Model ''' class PixmapItem(QGraphicsPixmapItem): def __init__(self, scene, model, pixmap=None, parent=None ): super(PixmapItem, self).__init__() self.scene = scene self._model = model self.currentTool = None #Undostack has all the actions to undo/redo shapes self.undoStack = QUndoStack() # Here we can fix the limit of the actions saved self.undoStack.setUndoLimit(200) ''' TODO: + autorub, allows you to rub automatically the color selected from the pixel ''' self._createUndoView() def _createUndoView(self): # we give the undoview the stack with all the items to display the actions self.undoView = QUndoView(self.undoStack) self.undoView.setWindowTitle("Commands list") self.undoView.setAttribute(Qt.WA_QuitOnClose,False) def mousePressEvent(self, event): tool = self._model.currentTool() if tool is not None: tool.mousePress(event) #etc.. pour move et release
j'applique seulement le facteur comme ceci .Je divise les coordonnées par le facteur et cela fonctionne. Mais avec un outil d'effacement d'une couleur, cela ne fonctione pas du tout.Code:color = self.scene().getCurrentImage().pixel(int(x/self.getZoomFactor()), int(y/self.getZoomFactor()))
ColorEraserToolC'est à dire que la division ne fonctionne pas quand l'index est différent de 1 bien sur, le résultat est que l'image que je souhaite modifier est dessinée à unCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 class ColorEraserTool(AbstractTool): def __init__(self,*args): AbstractTool.__init__(self,*args) self._model = self.model() self.pen = QPen(Qt.SolidLine) self.brush = QBrush() self.color = QColor() self._colorPix = QColor(Qt.white) self._name = 'ColorEraserTool' self._cursor = QCursor() self.x = 0 self.y = 0 self._deltaE=0 self._image = QImage() self.pixmap = None self.pixmapItem = None #Allows to get the right color when zoom in Action self._zoomFactor = 1 #List of the items to put into undostack self.items = [] def getZoomFactor(self): return self._zoomFactor def setZoomFactor(self,fact): self._zoomFactor = fact def name(self): return self._name def cursor(self): _img = QPixmap(2*self._model.width(),2*self._model.width()) _p = QPainter(_img) _p.fillRect(_img.rect(), QBrush(QColor(self._model.foregroundColor()))) _p.end() self._cursor = QCursor(_img,-16,-16)# return self._cursor def choose(self, p): foreColor = QColor(self._model.foregroundColor()) c_hsv = foreColor.toHsv() p_hsv = p.toHsv() colorDist =self.color_dist(c_hsv,p_hsv) if colorDist < 0.5: #print "colorDist",colorDist if c_hsv.valueF() !=0 : p_hsv.setHsvF(p_hsv.hueF(), 0, min(1.0, p_hsv.valueF() / c_hsv.valueF())) return p_hsv.toRgb() else: return p def erase(self, x, y): self._colorPix = pc = QColor(self.getImage().pixel(x, y)) #if pc != Qt.white and self.colorDist() < 20: # return if pc != Qt.white: return self.choose(pc) def applyRubber(self, mx, my): w = self._model.width() pm = QPixmap(w * 2, w * 2) pm.fill(Qt.transparent) p = QPainter(pm) for x in xrange(-w, w): for y in xrange(-w, w): #mx,my = int(mx/self.getZoomFactor()), int(my/self.getZoomFactor()) c = self.erase(mx + x, my + y) if c is not None : p.setPen(c) p.drawPoint(x + w, y + w) p.end() p = QPainter(self.pixmap) #mx,my = int(mx * self.getZoomFactor()),int(my * self.getZoomFactor()) print "Mx , my", mx ,",", my p.drawPixmap(mx - w, my - w, pm) p.end() self.pixmapItem.setPixmap(self.pixmap) def overlay(self): #Creates an overlay on which we 'll apply the rub self.pixmap = QPixmap(self.getImage().size()) self.pixmap.fill(Qt.transparent) self.pixmapItem = QGraphicsPixmapItem() self.scene().addItem(self.pixmapItem) self.items.append(self.pixmapItem) def getImage(self): #Get the image from the scene newly updated return self._image def setImage(self,img): self._image= img def color_dist(self, c1, c2): """ returns the squared euklidian distance between two color vectors in hsv space """ _result = (abs(c1.hueF()-c2.hueF()))**2 + (abs(c1.saturationF() - c2.saturationF()))**2 + (abs(c1.valueF()-c2.valueF()))**2 return (_result ** 0.5) def mousePress(self, event): self.items = [] x,y = event.pos().x(), event.pos().y() x,y = int(x/self.getZoomFactor()), int(y/self.getZoomFactor()) self.setImage(self.scene().getCurrentImage()) self.overlay() self.applyRubber(x,y) def mouseMove(self, event): x,y = event.pos().x(), event.pos().y() x,y = int(x/self.getZoomFactor()), int(y/self.getZoomFactor()) self.applyRubber(x,y) self.scene().update() def mouseRelease(self, event): for i in range(0,len(self.items)): addCmd = AddCommand(self.items[i], self.scene(), self.name()) self.scene().pixItem.undoStack.push(addCmd) self.pixmap = None self.pixmapItem = None
autre endroit.
Merci d'avance ^^.