画像ファイルのオープンし、表示し、セーブできるようにする。
上のようなファイル名を得るためのダイアログをファイルダイアログという。
本章では、ファイルダイアログを用いて、ファイル名を指定する。
この章ではじめて
QImageクラスを用いるので解説する。
QImageクラスは、画像の入出力、ピクセル単位のアクセスができる。
同様に画像を扱うクラスとして
QPixmapがあるが、
QPixmapは図形の描画を得意とする。
サンプルの6という名前のフォルダの中に、以下の内容のファイルがある。
画像を保持するためにQImageクラスのオブジェクトを、
ファイルダイアログを使用するためにQFileDialogクラスのオブジェクトを用いた。
protected: void paintEvent(QPaintEvent*);
ウィンドウに画像を表示し、何か(例えば、他のウィンドウ)に隠されて、
また画像を表示しているウィンドウがアクティブになったとき、再描画が必要になる。
親クラスのQWidgetで定義された、描画が必要な時に呼び出される仮想メソッドである、
paintEventメソッドをオーバーライドした。
実装は以下の通りである。
void MainWindow::paintEvent(QPaintEvent*){ if(!_buffer->isNull())bitBlt(this,0,0,_buffer); }
あるペイントデバイスから別のペイントデバイスにピクセルのブロックをコピーする
bitBlt関数で、メインウィンドウにコピーしている。
バッファがNullでないかを判断しているのは、画像が読み込まれていない状態で、
bitBltが呼ばれるのは好ましくないためである。
(実行中に警告される)
void MainWindow::slotLoad(){ QString name = QFileDialog::getOpenFileName(".", "Images (*.png *.bmp *.jpg)", this, "Load dialog"); if(!name.isEmpty()){ if(!_buffer->load(name)){ QMessageBox::warning(this, "Load error", "Could not load file."); }else{ bitBlt(this,0,0,_buffer); } } } void MainWindow::slotSave(){ QString name = QFileDialog::getSaveFileName(".", "Images (*.bmp)", this, "Save dialog"); if(!name.isEmpty()){ if(!_buffer->save(name, "BMP")){ QMessageBox::warning(this, "Save error", "Could not save file."); } } }
まず、ファイルダイアログを用いて、ファイル名を得ている。
QFileDialogクラスのgetOpenFileName、getSaveFileName関数の引数は、
QFileDialog::getOpenFileName("開くディレクトリ", "開くファイルの種類", 親, オブジェクト自体の名前)
の様に取る。(getSaveFileName関数も同様)
ここでは読み込むファイルを、png,bmp,jpgにし、書き出すファイルはbmpのみにした。
ファイル名が得られたら、画像の読み込み、書き込みは、QImageクラスのload, save関数
で行う。
load関数は、ファイルタイプを自動判別し、Qtで扱える形にロードする。
save関数は、ファイルタイプを指定し、保存する。
それぞれの関数は、
bool QImage::load(QString filename) bool QImage::save(QString filename, char *format)
のように引数をとり、処理に成功したらtrueを返す。本プログラムでは、
それをif文の判断に使い、エラーの場合はダイアログで警告を表示するようにした。
対応するファイル形式は、BMP、PPM、PBM、PGM、PNG、JPGなど。
詳しくはマニュアルを参照すること。
この例だと、画像はBMP形式に固定されてしまう。
保存するファイル形式別にメニューを作る、ファイル名から判断する、
など、解決策が思いつくが、ここでは触れない。
上の図のように、画像が読み込める。また、同様に保存も可能である。
また、再描画がきちんとなされているか試してほしい。