画像にパスを加えるツール version 7
:追加された部分
:削除された部分
(差分が大きい場合、文字単位では表示しません)
画像にパスを加えるツール
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 なら簡単だと思うが、書き出し用のメソッドがあるのかな?
- このプログラムは自作のパスを使い回しできるので、パスを作ってパーツとして選べるようにしておきたい
ウインドウ中に置くか、ダイアログで選択させるかは設計上の問題ですね
パスの線とブラシの色選択画面はウインドウ中の方が良いのかな
イフェクトの操作もできた方が良いか
- これって状態の保存は出来るのかしら??
できたら簡単な画像加工ソフトになるね
----
190722
- 画像保存出来た
これでQImageに書き出せってドキュメントには書いてある
しかしViewにすべきかSceneにすべきか?
両方に同じメソッドが用意されていて引数も全く同じだ
メインがviewで作ったからviewでいいか
>QGraphicsView.render (self, QPainter painter, QRectF target = QRectF(), QRect source = QRect(), Qt.AspectRatioMode mode = Qt.KeepAspectRatio)
>QGraphicsScene.render (self, QPainter painter, QRectF target = QRectF(), QRectF source = QRectF(), Qt.AspectRatioMode mode = Qt.KeepAspectRatio)
- **paint周りが今ひとつわからない**
今回もengineがないエラーになった
painterのbegin()もどういう場合に必須なのかわからない
自分で書く場合とシステムから呼ばれる場合で違うのだろうか??
勉強が必要だな ( ̄― ̄?)
- あとrectの指定がよくわからん┐('д')┌
---
---> [PyQt で画像にパスを加えるツールを作る #](https://mimemo.io/m/JkWVal6ZmJlBEqd)
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 なら簡単だと思うが、書き出し用のメソッドがあるのかな? - このプログラムは自作のパスを使い回しできるので、パスを作ってパーツとして選べるようにしておきたい
ウインドウ中に置くか、ダイアログで選択させるかは設計上の問題ですね
パスの線とブラシの色選択画面はウインドウ中の方が良いのかな
イフェクトの操作もできた方が良いか - これって状態の保存は出来るのかしら??
できたら簡単な画像加工ソフトになるね
190722
- 画像保存出来た
これでQImageに書き出せってドキュメントには書いてある
しかしViewにすべきかSceneにすべきか?
両方に同じメソッドが用意されていて引数も全く同じだ
メインがviewで作ったからviewでいいか
QGraphicsView.render (self, QPainter painter, QRectF target = QRectF(), QRect source = QRect(), Qt.AspectRatioMode mode = Qt.KeepAspectRatio)
QGraphicsScene.render (self, QPainter painter, QRectF target = QRectF(), QRectF source = QRectF(), Qt.AspectRatioMode mode = Qt.KeepAspectRatio)
- paint周りが今ひとつわからない
今回もengineがないエラーになった
painterのbegin()もどういう場合に必須なのかわからない
自分で書く場合とシステムから呼ばれる場合で違うのだろうか??
勉強が必要だな ( ̄― ̄?) - あとrectの指定がよくわからん┐('д')┌