2017-06-26 4 views
0

Qt画像クラスに存在しないカスタマイズされた画像編集ツールを使用して画像エディタを実装しようとしています。ユーザーがイメージシーンをクリックして操作を実行すると、GUIアプリケーションでイメージを即時に更新し、その変更をリアルタイムでユーザーに表示します(ピクセル、ズームなど)。問題は、クリックしたときに画像を編集するアクションは、別のクラス(少なくとも私の知る限り)でしか行えないことです(この例では、このクラスはGraphicsSceneと呼ばれています)。編集したイメージをMainWindowクラスに転送します。Qtで画像をクリックしたときにユーザーの編集操作の結果を即座に表示しようとしました

つまり、ユーザーが画像を編集するアクションを実行した直後にGraphicsSceneクラスの編集済み画像をMainWindowクラスに「送信」し、後者がコードを実行して画面を更新するようにしたいと思います各ユーザアクションが画像上で実行された後、リアルタイムで表示される。

わかりやすくするために、次に私が今持っているコードのスキームを示します。

main.cppに

#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 
    Ui::MainWindow *ui; 

private slots: 

private: 

}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 
#include <QFileDialog> 
#include <QApplication> 
#include <QMouseEvent> 
#include <QGraphicsSceneMouseEvent> 
#include "graphicsscene.h" 

extern QImage Image_original, Image_modified; 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::on_actionOpen_Image_triggered() 
{ 
    QDir dir; 

    QString filename=QFileDialog::getOpenFileName(this, 
                tr("Open Background"), 
                path, 
                tr("Images (*.png *.bmp *.jpg *.jpeg);;All files (*.*)")); 

    Image_original.load(filename); 
    GraphicsScene * img = new GraphicsScene(this); 
    img->addPixmap(QPixmap::fromImage(Image_original)); 
    ui->preview->setScene(img); 
} 

されるためにクリックすると、ネットを中心にいくつかの提案を以下の座標を追跡することができ、私はQGraphicsSceneのサブクラスは、そのヘッダファイルであるGraphicsScene、と呼ばれる作成:

graphicsscene.h

最後に
#ifndef GRAPHICSSCENE_H 
#define GRAPHICSSCENE_H 

#include <QGraphicsScene> 
#include <QGraphicsSceneMouseEvent> 
#include <QPointF> 
#include <QList> 

class GraphicsScene : public QGraphicsScene 
{ 
    Q_OBJECT 
public: 
    explicit GraphicsScene(QObject *parent = 0); 
    virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent); 
signals: 

public slots: 

private: 
    int x, y; 
}; 

#endif // GRAPHICSSCENE_H 

を実行します画像版、関連するソースファイルは、次のとおりです。

graphicsscene.cpp

#include "graphicsscene.h" 
#include <iostream> 

using namespace std; 

extern QImage Image_original, Image_modified; 

GraphicsScene::GraphicsScene(QObject *parent) : 
    QGraphicsScene(parent) 
{ 
    this->setBackgroundBrush(Qt::gray); 
} 

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent) 
{ 
    QGraphicsScene::mousePressEvent(mouseEvent); 
    if (mouseEvent->button()==Qt::LeftButton) 
    { 
     x=mouseEvent->scenePos().x(); 
     y=mouseEvent->scenePos().y(); 
    } 
    Image_modified=some_custom_image_editing_code(Image_original, x, y); 
} 

理想的には、私はmousePressEventが行われた後、メインウィンドウで、次のアクションを実行したいと思います:

img->addPixmap(QPixmap::fromImage(Image_modified)); 
ui->preview->setScene(img); 

私は非常には、任意のアイデアをいただければ幸いです。

+0

を発見された

new_pixmap.toImage() 

:あなたのコードで

は、私はあなたがあなたとQImageのにQPixmapのを変換することができ、それを引き続き使用したい場合は、QImageのを使用していることがわかり彼らはあなたが説明したいものを逸脱するので、あなたのインターネット検索を伝えるのに多くの行を費やす必要はありません。 – eyllanesc

+0

私はこの部分を理解していません。「クリックした座標に合わせて画像が中央になるようにズームを複製し、それに応じて画像を切り取って解像度を維持するというアクションを実装したい」ズームはQGraphicsviewを拡大/縮小するため、QPixmapではなくQGraphicsPixmapItemの変更方法が変更されます。または、画像を中央に配置したいと思うかもしれませんか? – eyllanesc

+0

画面サイズが400x200(たとえば)と仮定しましょう。 400×200の画像も読み込みます。をクリックすると、ピクセル(200,50)とし、新しい画像は水平方向に101〜300、垂直方向に1〜100のピクセルを取得します。次に、新しいサイズが再び400x200。しかし、要求に応じて、私が望むものは、画像に何が変更されたとしても、この情報をクラスGraphicsSceneからクラスMainWindowに "送信"してシーンに画像をペイントする方法ですいったん完了したら、新しい変更を「img」に追加します。 – ksb496

答えて

1

pixmapを含む項目をクリックしたいので、QGraphicsScene mousePressEventメソッドを上書きする必要はないので、画像の外側をクリックすることができるので、そのメソッドをQGraphicsPixmapItemに上書きする方がよい。

イメージにアクセスするためにexternを使用する代わりに、Qtはより良いシグナルとスロットですが、QObjectを継承するクラスだけがこれらの属性を持つことができます。残念ながらQGraphicsPixmapItemはこれを継承しません。

グラフィックスpixmapem。我々は、信号newPixmapを作成し、前のコードで時間

#ifndef GRAPHICSPIXMAPITEM_H 
#define GRAPHICSPIXMAPITEM_H 

#include <QGraphicsPixmapItem> 
#include <QObject> 

class GraphicsPixmapItem : public QObject, public QGraphicsPixmapItem 
{ 
    Q_OBJECT 
public: 
    explicit GraphicsPixmapItem(QObject *parent=0); 

protected: 
    void mousePressEvent(QGraphicsSceneMouseEvent * event); 

signals: 
    void newPixmap(const QPixmap p); 
}; 

#endif // GRAPHICSPIXMAPITEM_H 

graphicspixmapitem.cpp

#include "graphicspixmapitem.h" 

#include <QGraphicsSceneMouseEvent> 

GraphicsPixmapItem::GraphicsPixmapItem(QObject * parent):QObject(parent) 
{ 

} 

void GraphicsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) 
{ 
    QPoint p = QPoint(event->pos().x(), event->pos().y()); 
    QPixmap pix = pixmap(); 
    if(!pix.isNull()){ 
     QRect rect(QPoint(), pix.rect().size()/2); 
     rect.moveCenter(p); 
     QPixmap modified = pix.copy(rect); 
     modified = modified.scaled(pix.rect().size(), Qt::KeepAspectRatioByExpanding); 
     emit newPixmap(modified); 
    } 
    QGraphicsPixmapItem::mousePressEvent(event); 
} 

は、これはメインウィンドウにonNewPixmap呼ばスロットとそれを接続します。そのスロットに

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

#include "graphicsscene.h" 
#include "graphicspixmapitem.h" 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private slots: 
    void on_actionOpen_triggered(); 
    void onNewPixmap(const QPixmap pixmap); 

private: 
    Ui::MainWindow *ui; 

    GraphicsPixmapItem *item; 
    GraphicsScene *scene; 

    QPixmap original_pixmap; 
    QPixmap new_pixmap; 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

#include <QGraphicsView> 
#include <QFileDialog> 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    scene = new GraphicsScene(this); 
    ui->preview->setScene(scene); 
    item = new GraphicsPixmapItem; 
    /*ui->preview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 
    ui->preview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);*/ 
    scene->addItem(item); 
    connect(item, &GraphicsPixmapItem::newPixmap, this, &MainWindow::onNewPixmap); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::on_actionOpen_triggered() 
{ 

    QString path = QDir::homePath(); 
    QString filename=QFileDialog::getOpenFileName(this, 
                tr("Open Background"), 
                path, 

                tr("Images (*.png *.bmp *.jpg *.jpeg);;All files (*.*)")); 

    original_pixmap = QPixmap(filename); 
    item->setPixmap(original_pixmap); 
} 

void MainWindow::onNewPixmap(const QPixmap pixmap) 
{ 

    new_pixmap = pixmap; 
    QFile file("new_file.png"); 
    file.open(QIODevice::WriteOnly); 
    new_pixmap.save(&file, "PNG"); 
} 

私は実行可能ファイルが生成されたフォルダに画像を保存試験など。 、完全な例では、より良い自分自身を教えてくださいhere

+0

それは動作します!素晴らしい説明をいただきありがとうございます! 将来の読者のためのちょっとした説明。必要に応じて(クリックするたびに画面を更新するために)、void MainWindow :: onNewPixmap(const QPixmap pixmap)の内部コードを次の行で置き換えれば十分です: item-> setPixmap(pixmap); – ksb496

+0

あなたは、少なくともあなたの最初の質問では、それを表示したかったと言っていませんでした。あなたの質問を編集し、その発言を追加してください。 – eyllanesc

+0

あなたの最初のメッセージの後で、よりよく説明する必要があることを指摘した後、私は質問を編集していました。今、あなたはそれがより適切に書かれているかどうかを教えてください。 – ksb496

関連する問題