イメージビューア(下記のコードを参照)を適用して、読み込んだ画像からピクセル情報を取得できるようにしました。 'イメージをロード'ボタンを使用してイメージをロードし、スクロールホイールを使用してズームイン/ズームアウトし、マウスの左クリックとドラッグを使用してパンすることができます。 'ピクセル情報入力モード'ボタンを押すと、ドラッグは無効になります(ズームすることもできます)。画像をクリックすると、ピクセル座標(整数ピクセルインデックス)とピクセルのグレースケール値が得られます。回転画像のpyqt4ピクセル情報
画像を回転すると、[画像回転]ボタンを押すと、ピクセル情報ボタンを使用して正しいピクセル情報が表示されなくなるという問題があります。私は、mapToSceneメソッドは、回転されたイメージ上で使用するのは適切ではないが、他の方法で見つけることはできないと思います。私は、回転したピクスマップ上でtoImage()を使用して元のイメージを置き換えるなど、さまざまなことを試しましたが、何も動作していないようです。これを解決する最善の方法は何でしょうか?
コード:
from PyQt4 import QtCore, QtGui
class PhotoViewer(QtGui.QGraphicsView):
photoClicked = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, parent):
super(PhotoViewer, self).__init__(parent)
self._zoom = 0
self._empty = True
self._scene = QtGui.QGraphicsScene(self)
self._photo = QtGui.QGraphicsPixmapItem()
self._scene.addItem(self._photo)
self.setScene(self._scene)
self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(30, 30, 30)))
self.setFrameShape(QtGui.QFrame.NoFrame)
def fitInView(self):
rect = QtCore.QRectF(self._photo.pixmap().rect())
if not rect.isNull():
unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
self.scale(1/unity.width(), 1/unity.height())
viewrect = self.viewport().rect()
scenerect = self.transform().mapRect(rect)
factor = min(viewrect.width()/scenerect.width(),
viewrect.height()/scenerect.height())
self.scale(factor, factor)
self.centerOn(rect.center())
self._zoom = 0
def hasPhoto(self):
return not self._empty
def toggleDragMode(self):
if self.dragMode() == QtGui.QGraphicsView.ScrollHandDrag:
self.setDragMode(QtGui.QGraphicsView.NoDrag)
elif self.hasPhoto():
self.setDragMode(QtGui.QGraphicsView.ScrollHandDrag)
def setPhoto(self, pixmap=None):
self._zoom = 0
if pixmap and not pixmap.isNull():
self._empty = False
self.setDragMode(QtGui.QGraphicsView.ScrollHandDrag)
self._photo.setPixmap(pixmap)
self.fitInView()
else:
self._empty = True
self.setDragMode(QtGui.QGraphicsView.NoDrag)
self._photo.setPixmap(QtGui.QPixmap())
def wheelEvent(self, event):
if not self._photo.pixmap().isNull():
if event.delta() > 0:
factor = 1.25
self._zoom += 1
else:
factor = 0.8
self._zoom -= 1
if self._zoom > 0:
self.scale(factor, factor)
elif self._zoom == 0:
self.fitInView()
else:
self._zoom = 0
def mousePressEvent(self, event):
if (self.hasPhoto() and
self.dragMode() == QtGui.QGraphicsView.NoDrag and
self._photo.isUnderMouse()):
self.photoClicked.emit(QtCore.QPoint(event.pos()))
super(PhotoViewer, self).mousePressEvent(event)
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.viewer = PhotoViewer(self)
# 'Load image' button
self.btnLoad = QtGui.QToolButton(self)
self.btnLoad.setText('Load image')
self.btnLoad.clicked.connect(self.loadImage)
# Button to change from drag/pan to getting pixel info
self.btnPixInfo = QtGui.QToolButton(self)
self.btnPixInfo.setText('Enter pixel info mode')
self.btnPixInfo.clicked.connect(self.pixInfo)
self.editPixInfo = QtGui.QLineEdit(self)
self.editPixInfo.setReadOnly(True)
# Button to rotate image by 10 degrees
self.btnRotate = QtGui.QToolButton(self)
self.btnRotate.setText('Rotate image')
self.btnRotate.clicked.connect(self.rotateImage)
self.viewer.photoClicked.connect(self.photoClicked)
# Arrange layout
VBlayout = QtGui.QVBoxLayout(self)
VBlayout.addWidget(self.viewer)
HBlayout = QtGui.QHBoxLayout()
HBlayout.setAlignment(QtCore.Qt.AlignLeft)
HBlayout.addWidget(self.btnLoad)
HBlayout.addWidget(self.btnRotate)
HBlayout.addWidget(self.btnPixInfo)
HBlayout.addWidget(self.editPixInfo)
VBlayout.addLayout(HBlayout)
def loadImage(self):
self.viewer.setPhoto(QtGui.QPixmap('pic.jpg'))
def pixInfo(self):
self.viewer.toggleDragMode()
def rotateImage(self):
self.viewer._photo.setRotation(10)
def photoClicked(self, pos):
pos = self.viewer.mapToScene(pos)
# p.s. I realise the following lines are probably a very convoluted way of getting
# a grayscale value from RGB, but I couldn't make it work any other way I tried
rot_image = self.viewer._photo.pixmap().toImage().pixel(pos.x(), pos.y())
colour = QtGui.QColor.fromRgb(rot_image)
gsval = QtGui.qGray(colour.red(), colour.green(), colour.blue())
self.editPixInfo.setText('X:%d, Y:%d Grayscale: %d' % (pos.x(), pos.y(), gsval))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 800, 600)
window.show()
sys.exit(app.exec_())
は、以前のように(あなたが私の最後の質問に答え)あなたは私のためにそれを修正しました。興味のないものは、この種のもの(pyqt4画像の操作と描画/特にアニメーション)を学ぶための良い本やチュートリアルを知っていますか?私が知らないことがたくさんあるので、私が暗闇の中で捜しているように感じます。私はいつもより簡単に例を学ぶことができます。とにかくありがとう。 –
@AndrewBirch。私は個人的な推薦を持っていません。 [PyQt Wiki](http://wiki.python.org/moin/PyQt)にはいくつかの便利なリンクがありますが、いくつかはかなり古いかもしれないことに注意してください。 [PyQt4 examples](http://github.com/Werkov/PyQt4/tree/master/examples/graphicsview)には、(Qt Docsのものに基づく)いくつかのグラフィックデモもあります。 – ekhumoro