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 |