画像にパスを加えるツール version 4

2019/07/22 11:44 by yamasyuh68
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
ビットマップ画像とパスの結合
190721
# 画像との結合

https://live.staticflickr.com/65535/48337267662_8d8df672d9_b.jpg

```
import sys , os
from PyQt5.QtWidgets import (QApplication, QGraphicsItem, QGraphicsScene, QGraphicsView,
        QGraphicsDropShadowEffect ,QGraphicsPathItem )
from PyQt5.QtSvg import QGraphicsSvgItem
from PyQt5.QtGui import  QPixmap , QColor , QPainterPath ,QPen
from PyQt5.QtCore import Qt,QSizeF ,QPoint,QPointF ,Qt,QDataStream,QIODevice,QDataStream,QFile

class pathitem(QGraphicsPathItem):
    def __init__(self,filename):
        super().__init__(filename)
        self.setCursor(Qt.OpenHandCursor)
        self.setAcceptedMouseButtons(Qt.LeftButton)
        self.setFlag(QGraphicsItem.ItemIsSelectable,1)
        self.setFlag(QGraphicsItem.ItemIsMovable,1)
        self.setGraphicsEffect(QGraphicsDropShadowEffect())
        self.setTransformOriginPoint(self.boundingRect().width()/2,
            self.boundingRect().height()/2)
        self.angle=0
        self.scale=1.0
        self.distance=5.0
        self.radius=1.0

    def mousePressEvent(self, event):
        self.setCursor(Qt.ClosedHandCursor)
        super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        self.setCursor(Qt.OpenHandCursor)
        super().mouseReleaseEvent(event)

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)

    def keyPressEvent(self, event):

        if (event.modifiers() & Qt.ShiftModifier): # shift
            if (event.key() == Qt.Key_Up):
                self.distance += 0.5
            elif (event.key() == Qt.Key_Down):
                self.distance -= 0.5
            elif (event.key() == Qt.Key_Right):
                self.radius += 0.5
            elif (event.key() == Qt.Key_Left):
                self.radius -= 0.5
            self.graphicsEffect().setOffset(self.distance)
            self.graphicsEffect().setBlurRadius(self.distance)
            return

        if (event.key() == Qt.Key_Right):
            self.angle += 1
        elif (event.key() == Qt.Key_Left):
            self.angle -= 1
        elif (event.key() == Qt.Key_Up):
            self.scale += 0.1
        elif (event.key() == Qt.Key_Down):
            self.scale -= 0.1
        # elif (event.key() == Qt.Key_Escape):
        #     return

        self.setScale(self.scale)
        self.setRotation(self.angle)

    def paint(self,painter,option,n):
        painter.setPen( QPen( Qt.red , 2, style=Qt.SolidLine ) )
        painter.setBrush(  Qt.red )
        painter.drawPath(self.path())



class SvgView(QGraphicsView):
    def __init__(self, parent=None):
        super(SvgView, self).__init__(parent)
        self.pix = QPixmap(r'e:\Programs\python\qt\svg\cat.png')

        fname=os.path.join(os.path.dirname(__file__) , 'qtpath.qtdata')
        f = QFile(fname)
        f.open( QIODevice.ReadOnly)
        ds = QDataStream(f)
        path=QPainterPath()
        ds.__rshift__(path)
        f.close() 
        self.path=pathitem(path)

        self.setScene(QGraphicsScene(self))
        self.scene().addPixmap(self.pix)
        self.scene().addItem(self.path
       self.scene().selectionChanged.connect(self.selectionChanged)
        self.selected=None

    def selectionChanged(self):
        if self.selected :
            self.selected.ungrabKeyboard()
        p=self.scene().selectedItems()
        if len(p) >= 1 :
            p=p[0]
            p.grabKeyboard()
            self.selected=p

app = QApplication(sys.argv)
window = SvgView()
window.show()
sys.exit(app.exec_())

```
もともと画像に挿入するパーツを自作したかった
原型はここ
以前に作成していたものの使いまわし

- 前に書いたプログラムの使い回し
QGraphicsPathItemの派生クラスはsvg用のクラスの親をpathに変えただけで一切変更していないが、完璧に動作してます
- paintメッソドを新たに実装した
無くても描画されますが、黒ペンでブラシ無しだったので、適当に設定した
ここを変えたら自由な色で塗れる、グラデもアリだな、しないけど
- 影のイフェクトも完璧です、Qtすごいね、しつこいけど
- 作った画像の保存ルーチンは書いてない( ´∀`)
widget の grab なら簡単だと思うが、書き出し用のメソッドがあるのかな?
- このプログラムは自作のパスを使い回しできるので、パスを作ってパーツとして選べるようにしておきたい
ウインドウ中に置くか、ダイアログで選択させるかは設計上の問題ですね
パスの線とブラシの色選択画面はウインドウ中の方が良いのかな
イフェクトの操作もできた方が良いか
- これって状態の保存は出来るのかしら??
できたら簡単な画像加工ソフトになるね


---
--> [PyQt でベクターオブジェクト作成ツールを作る #](https://mimemo.io/m/3Rx1XoR367le95E)

      

190721

画像との結合

import sys , os
from PyQt5.QtWidgets import (QApplication, QGraphicsItem, QGraphicsScene, QGraphicsView,
        QGraphicsDropShadowEffect ,QGraphicsPathItem )
from PyQt5.QtSvg import QGraphicsSvgItem
from PyQt5.QtGui import  QPixmap , QColor , QPainterPath ,QPen
from PyQt5.QtCore import Qt,QSizeF ,QPoint,QPointF ,Qt,QDataStream,QIODevice,QDataStream,QFile

class pathitem(QGraphicsPathItem):
    def __init__(self,filename):
        super().__init__(filename)
        self.setCursor(Qt.OpenHandCursor)
        self.setAcceptedMouseButtons(Qt.LeftButton)
        self.setFlag(QGraphicsItem.ItemIsSelectable,1)
        self.setFlag(QGraphicsItem.ItemIsMovable,1)
        self.setGraphicsEffect(QGraphicsDropShadowEffect())
        self.setTransformOriginPoint(self.boundingRect().width()/2,
            self.boundingRect().height()/2)
        self.angle=0
        self.scale=1.0
        self.distance=5.0
        self.radius=1.0

    def mousePressEvent(self, event):
        self.setCursor(Qt.ClosedHandCursor)
        super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        self.setCursor(Qt.OpenHandCursor)
        super().mouseReleaseEvent(event)

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)

    def keyPressEvent(self, event):

        if (event.modifiers() & Qt.ShiftModifier): # shift
            if (event.key() == Qt.Key_Up):
                self.distance += 0.5
            elif (event.key() == Qt.Key_Down):
                self.distance -= 0.5
            elif (event.key() == Qt.Key_Right):
                self.radius += 0.5
            elif (event.key() == Qt.Key_Left):
                self.radius -= 0.5
            self.graphicsEffect().setOffset(self.distance)
            self.graphicsEffect().setBlurRadius(self.distance)
            return

        if (event.key() == Qt.Key_Right):
            self.angle += 1
        elif (event.key() == Qt.Key_Left):
            self.angle -= 1
        elif (event.key() == Qt.Key_Up):
            self.scale += 0.1
        elif (event.key() == Qt.Key_Down):
            self.scale -= 0.1
        # elif (event.key() == Qt.Key_Escape):
        #     return

        self.setScale(self.scale)
        self.setRotation(self.angle)

    def paint(self,painter,option,n):
        painter.setPen( QPen( Qt.red , 2, style=Qt.SolidLine ) )
        painter.setBrush(  Qt.red )
        painter.drawPath(self.path())



class SvgView(QGraphicsView):
    def __init__(self, parent=None):
        super(SvgView, self).__init__(parent)
        self.pix = QPixmap(r'e:\Programs\python\qt\svg\cat.png')

        fname=os.path.join(os.path.dirname(__file__) , 'qtpath.qtdata')
        f = QFile(fname)
        f.open( QIODevice.ReadOnly)
        ds = QDataStream(f)
        path=QPainterPath()
        ds.__rshift__(path)
        f.close() 
        self.path=pathitem(path)

        self.setScene(QGraphicsScene(self))
        self.scene().addPixmap(self.pix)
        self.scene().addItem(self.path
       self.scene().selectionChanged.connect(self.selectionChanged)
        self.selected=None

    def selectionChanged(self):
        if self.selected :
            self.selected.ungrabKeyboard()
        p=self.scene().selectedItems()
        if len(p) >= 1 :
            p=p[0]
            p.grabKeyboard()
            self.selected=p

app = QApplication(sys.argv)
window = SvgView()
window.show()
sys.exit(app.exec_())

  • 前に書いたプログラムの使い回し
    QGraphicsPathItemの派生クラスはsvg用のクラスの親をpathに変えただけで一切変更していないが、完璧に動作してます
  • paintメッソドを新たに実装した
    無くても描画されますが、黒ペンでブラシ無しだったので、適当に設定した
    ここを変えたら自由な色で塗れる、グラデもアリだな、しないけど
  • 影のイフェクトも完璧です、Qtすごいね、しつこいけど
  • 作った画像の保存ルーチンは書いてない( ´∀`)
    widget の grab なら簡単だと思うが、書き出し用のメソッドがあるのかな?
  • このプログラムは自作のパスを使い回しできるので、パスを作ってパーツとして選べるようにしておきたい
    ウインドウ中に置くか、ダイアログで選択させるかは設計上の問題ですね
    パスの線とブラシの色選択画面はウインドウ中の方が良いのかな
    イフェクトの操作もできた方が良いか
  • これって状態の保存は出来るのかしら??
    できたら簡単な画像加工ソフトになるね

--> PyQt でベクターオブジェクト作成ツールを作る #