前回までは画像の読み書きしかしなかったが、ここでいよいよ、画像処理を行う。
ここでは、入力ダイアログのいらないグレースケール変換を行う。
サンプルの7という名前のフォルダの中に、以下の内容のファイルがある。
メイン関数には変更がなかったのでリンクからは削除した。
今回、行うことは、
ことである。
class GrayScale : public QObject{ Q_OBJECT public: GrayScale(); ~GrayScale(); void toGrayScale(QImage*); };
GrayScaleクラスの宣言である。
処理をするだけなのでQWidgetを継承する必要はなく、
また、独自のスロットを使うことを考えて、QObjectを継承した。
void GrayScale::toGrayScale(QImage* img){ int gray=0; QRgb color; for(int y=0; y<img->height(); y++){ for(int x=0; x<img->width(); x++){ color = img->pixel(x,y); gray = qRed(color) + qGreen(color) + qBlue(color); gray /= 3; img->setPixel(x,y, qRgb(gray,gray,gray)); } } }
QImageクラスはpixel単位で画像にアクセスできる。
pixel(x,y)関数で座標(x,y)のRGB情報を得て、
さらに、qRed, qGreen, qBlueでRGBそれぞれの値を得ている。
そして、3つの値の平均値をグレースケールの色として、
setPixel(x,y,QRgb)関数で色を変更している。
グレースケール変換には他にも様々な手法がある。この方法だと、 心理的な明るさが表現されない(赤と青が同じ明るさになってしまう)が、 ここでは厳密なグレースケール変換自体が目的ではないのでこの方法を用いた。
ここで行うのは、メニューにフィルタの項目を追加すること、 グレースケース処理を呼び出しを行う事である。
#include"grayscale.h"
独自のヘッダファイルの読込は""を使う事に注意する。
enum type_filter{ idGrayScale };
列挙型enumを用いて識別のためのIDナンバーを設定している。
ポップアップメニューにIDを振り分けて置けば、
ポップアップメニューが選択されたときに、どのメニューが選択されたか
判断できる。
GrayScale *_grayscale;
privateであるメンバ変数にそれぞれ必要なクラス変数を用意した。
_filtermenu = new QPopupMenu(this, "filter"); _filtermenu->insertItem("Grayscale",idGrayScale);
ポップアップメニュー項目に、enumで設定したIDを割り当てた。
このメニューが選択されたときactivated(idGrayScale)シグナルが発生する。
connect(_filtermenu, SIGNAL(activated(int)), this, SLOT(callFilter(int)));
connectはシグナルとスロットを接続するための関数である。
Qtを使う上で非常に重要な関数である。
connect(どのクラスの,SIGNAL(どのシグナルを), どのクラスの,SLOT(どのスロットに接続するか?))
の様に使う。
ここではポップアップメニューから発生したシグナルを、 各フィルタを呼ぶスロットに接続している。
void MainWindow::callFilter(int id){ switch(id){ case idGrayScale: _grayscale->toGrayScale(_buffer); break; } }
各フィルタを呼ぶためのスロットである。
割り当てたIDをswitchの条件に使って
処理を行った。
上のようにグレースケール処理が行われた。