十一、QT之截圖並取出圖中的顏色

一、截圖

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
    QPixmap pixmap = QPixmap::grabWindow(QApplication::desktop()->winId(), x, y, 2, 2);
#else
    //下面函數功能是截屏
    QScreen *screen = QApplication::primaryScreen();
    //QApplication::desktop()->winId(),返回的是要截屏的窗口的ID , 設爲0 表示當前桌面 ,截屏時就會截全屏
    QPixmap pixmap = screen->grabWindow(QApplication::desktop()->winId(), x, y, 2, 2);

二、取出鼠標點擊處的顏色

void ColorWidget::showColorValue()
{
    if (!pressed) {
        return;
    }

    int x = QCursor::pos().x();
    int y = QCursor::pos().y();

    txtPoint->setText(tr("x:%1  y:%2").arg(x).arg(y));
    QString strDecimalValue, strHex, strTextColor;
    int red, green, blue;

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
    QPixmap pixmap = QPixmap::grabWindow(QApplication::desktop()->winId(), x, y, 2, 2);
#else
    //下面函數功能是截屏
    QScreen *screen = QApplication::primaryScreen();
    //QApplication::desktop()->winId(),返回的是要截屏的窗口的ID , 設爲0 表示當前桌面 ,截屏時就會截全屏
    QPixmap pixmap = screen->grabWindow(QApplication::desktop()->winId(), x, y, 2, 2);
#endif

    if (!pixmap.isNull()) {
        QImage image = pixmap.toImage();

        if (!image.isNull()) {
            if (image.valid(0, 0)) {
                //獲取 QPixmap 對象顏色
                QColor color = image.pixel(0, 0);
                red = color.red();
                green = color.green();
                blue = color.blue();
                /**
                 * arg(int a, int fieldWidth, int base, QChar fillChar):
                 *     a表示輸入的值,fieldWidth表示字符寬度,base表示進制,fillChar 表示填充字符
                 *     若是字符寬度fieldWidth是正數,fillchar填在左邊,若是負數,fillchar填在右邊
                 */
                QString strRed = tr("%1").arg(red & 0xFF, 2, 16, QChar('0'));
                QString strGreen = tr("%1").arg(green & 0xFF, 2, 16, QChar('0'));
                QString strBlue = tr("%1").arg(blue & 0xFF, 2, 16, QChar('0'));

                strDecimalValue = tr("%1, %2, %3").arg(red).arg(green).arg(blue);
                strHex = tr("#%1%2%3").arg(strRed.toUpper()).arg(strGreen.toUpper()).arg(strBlue.toUpper());
            }
        }
    }
    //設置字體顏色
    if (red > 200 && green > 200 && blue > 200) {
        strTextColor = "10, 10, 10";
    } else {
        strTextColor = "255, 255, 255";
    }

    QString str = tr("background-color: rgb(%1);color: rgb(%2)").arg(strDecimalValue).arg(strTextColor);
    labColor->setStyleSheet(str);
    txtRgb->setText(strDecimalValue);
    txtWeb->setText(strHex);
}

二、真實案例

1、效果圖:

在這裏插入圖片描述

2、代碼

screenapi.h
#ifndef SCREENAPI_H
#define SCREENAPI_H

#ifndef FRMSCREEN_H
#define FRMSCREEN_H

#include <QPoint>
#include <QSize>

#include <QDialog>
#include <QMutex>
#include <QMenu>

class ScreenAPI
{
public:
	enum STATUS {SELECT, MOV, SET_W_H};
	ScreenAPI() {}
	ScreenAPI(QSize size);

	void setStart(QPoint pos);
	void setEnd(QPoint pos);
	QPoint getStart();
	QPoint getEnd();

	QPoint getLeftUp();
	QPoint getRightDown();

	STATUS getStatus();
	void setStatus(STATUS status);

	int width();
	int height();
	bool isInArea(QPoint pos);          // 檢測pos是否在截圖區域內
	void move(QPoint p);                // 按 p 移動截圖區域

private:
	QPoint leftUpPos, rightDownPos;     //記錄 截圖區域 左上角、右下角
	QPoint startPos, endPos;            //記錄 鼠標開始位置、結束位置
	int maxWidth, maxHeight;            //記錄屏幕大小
	STATUS status;                      //三個狀態 :  選擇區域、移動區域、設置width height

	void cmpPoint(QPoint &s, QPoint &e);//比較兩位置,判斷左上角、右下角
};

#endif // SCREENAPI_H

class frmScreen : public QDialog
{
	Q_OBJECT

public:
	explicit frmScreen(QWidget *parent = 0);
    static frmScreen *Instance()
    {
        static QMutex mutex;

        if (!_instance) {
            QMutexLocker locker(&mutex);

            if (!_instance) {
                _instance = new frmScreen;
            }
        }

        return _instance;
    }

private:
    static frmScreen *_instance;
	QMenu *menu;            //右鍵菜單對象
	ScreenAPI *screen;      //截屏對象
	QPixmap *fullScreen;    //保存全屏圖像
	QPixmap *bgScreen;      //模糊背景圖
	QPoint movPos;          //座標

protected:
	void contextMenuEvent(QContextMenuEvent *);
	void mousePressEvent(QMouseEvent *);
	void mouseMoveEvent(QMouseEvent *);
	void mouseReleaseEvent(QMouseEvent *);
	void paintEvent(QPaintEvent *);
    void showEvent(QShowEvent *);

private slots:
	void InitForm();
	void SaveScreen();
	void SaveScreenOther();
	void SaveFullScreen();

};

#endif // FRMSCREEN_H


screenapi.cpp
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

#include "screenapi.h"
#include "myhelper.h"

ScreenAPI::ScreenAPI(QSize size)
{
	maxWidth = size.width();
	maxHeight = size.height();

	startPos = QPoint(-1, -1);
	endPos = startPos;
	leftUpPos = startPos;
	rightDownPos = startPos;
	status = SELECT;
}

int ScreenAPI::width()
{
	return maxWidth;
}

int ScreenAPI::height()
{
	return maxHeight;
}

ScreenAPI::STATUS ScreenAPI::getStatus()
{
	return status;
}

void ScreenAPI::setStatus(STATUS status)
{
	this->status = status;
}

void ScreenAPI::setEnd(QPoint pos)
{
	endPos = pos;
	leftUpPos = startPos;
	rightDownPos = endPos;
	cmpPoint(leftUpPos, rightDownPos);
}

void ScreenAPI::setStart(QPoint pos)
{
	startPos = pos;
}

QPoint ScreenAPI::getEnd()
{
	return endPos;
}

QPoint ScreenAPI::getStart()
{
	return startPos;
}

QPoint ScreenAPI::getLeftUp()
{
	return leftUpPos;
}

QPoint ScreenAPI::getRightDown()
{
	return rightDownPos;
}

bool ScreenAPI::isInArea(QPoint pos)
{
	if (pos.x() > leftUpPos.x() && pos.x() < rightDownPos.x() && pos.y() > leftUpPos.y() && pos.y() < rightDownPos.y()) {
		return true;
	}

	return false;
}

void ScreenAPI::move(QPoint p)
{
	int lx = leftUpPos.x() + p.x();
	int ly = leftUpPos.y() + p.y();
	int rx = rightDownPos.x() + p.x();
	int ry = rightDownPos.y() + p.y();

	if (lx < 0) {
		lx = 0;
		rx -= p.x();
	}

	if (ly < 0) {
		ly = 0;
		ry -= p.y();
	}

	if (rx > maxWidth)  {
		rx = maxWidth;
		lx -= p.x();
	}

	if (ry > maxHeight) {
		ry = maxHeight;
		ly -= p.y();
	}

	leftUpPos = QPoint(lx, ly);
	rightDownPos = QPoint(rx, ry);
	startPos = leftUpPos;
	endPos = rightDownPos;
}

void ScreenAPI::cmpPoint(QPoint &leftTop, QPoint &rightDown)
{
	QPoint l = leftTop;
	QPoint r = rightDown;

	if (l.x() <= r.x()) {
		if (l.y() <= r.y()) {
			;
		} else {
			leftTop.setY(r.y());
			rightDown.setY(l.y());
		}
	} else {
		if (l.y() < r.y()) {
			leftTop.setX(r.x());
			rightDown.setX(l.x());
		} else {
			QPoint tmp;
			tmp = leftTop;
			leftTop = rightDown;
			rightDown = tmp;
		}
	}
}


frmScreen *frmScreen::_instance = 0;
frmScreen::frmScreen(QWidget *parent) : QDialog(parent)
{
	this->InitForm();
}

void frmScreen::InitForm()
{
//    Qt::WindowStaysOnTopHint 總是顯示在最前面
	this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);

	menu = new QMenu(this);
	menu->addAction("保存截圖", this, SLOT(SaveScreen()));
	menu->addAction("截圖另存爲", this, SLOT(SaveScreenOther()));
	menu->addAction("全屏截圖", this, SLOT(SaveFullScreen()));
    menu->addAction("退出截圖", this, SLOT(hide()));

    //取得屏幕大小
    screen = new ScreenAPI(QApplication::desktop()->size());

    //保存全屏
    fullScreen = new QPixmap();
}

void frmScreen::paintEvent(QPaintEvent *)
{
	int x = screen->getLeftUp().x();
	int y = screen->getLeftUp().y();
	int w = screen->getRightDown().x() - x;
	int h = screen->getRightDown().y() - y;

	QPainter painter(this);

	QPen pen;
	pen.setColor(Qt::green);
	pen.setWidth(2);
	pen.setStyle(Qt::DotLine);
	painter.setPen(pen);

	QFont font;
	font.setFamily(App::FontName);
	font.setPointSize(App::FontSize + 2);
	painter.setFont(font);

	painter.drawPixmap(0, 0, *bgScreen);

	if (w != 0 && h != 0) {
		painter.drawPixmap(x, y, fullScreen->copy(x, y, w, h));
	}

	painter.drawRect(x, y, w, h);

	pen.setColor(Qt::yellow);
	painter.setPen(pen);
	painter.drawText(x + 2, y - 8, tr("截圖範圍:( %1 x %2 ) - ( %3 x %4 )  圖片大小:( %5 x %6 )")
	                 .arg(x).arg(y).arg(x + w).arg(y + h).arg(w).arg(h));
}

void frmScreen::showEvent(QShowEvent *)
{
	QPoint point(-1, -1);
	screen->setStart(point);
	screen->setEnd(point);

    *fullScreen = QPixmap::grabWindow(QApplication::desktop()->winId(), 0, 0, screen->width(), screen->height());

    bgScreen = new QPixmap(*fullScreen);
    QPainter p(bgScreen);

    //設置透明度實現模糊背景
    QPixmap pix(screen->width(), screen->height());
    pix.fill((QColor(160, 160, 160, 200)));

    p.drawPixmap(0, 0, pix);
}

void frmScreen::SaveScreenOther()
{
	QString fileName = QFileDialog::getSaveFileName(this, "保存圖片", STRDATETIME, "JPEG Files (*.jpg)");

	if (fileName.length() > 0) {
		int x = screen->getLeftUp().x();
		int y = screen->getLeftUp().y();
		int w = screen->getRightDown().x() - x;
		int h = screen->getRightDown().y() - y;

		fullScreen->copy(x, y, w, h).save(fileName, "jpg");

		close();
	}
}

void frmScreen::SaveScreen()
{
	int x = screen->getLeftUp().x();
	int y = screen->getLeftUp().y();
	int w = screen->getRightDown().x() - x;
	int h = screen->getRightDown().y() - y;

	QString fileName = QString("%1/image_screen/screen_%2.jpg").arg(App::AppPath).arg(STRDATETIME);
	fullScreen->copy(x, y, w, h).save(fileName, "jpg");

	close();
}

void frmScreen::SaveFullScreen()
{
	QString fileName = QString("%1/image_screen/full_%2.jpg").arg(App::AppPath).arg(STRDATETIME);
	fullScreen->save(fileName, "jpg");

	close();
}

void frmScreen::mouseMoveEvent(QMouseEvent *e)
{
	if (screen->getStatus() == ScreenAPI::SELECT) {
		screen->setEnd(e->pos());
	} else if (screen->getStatus() == ScreenAPI::MOV) {
		QPoint p(e->x() - movPos.x(), e->y() - movPos.y());
		screen->move(p);
		movPos = e->pos();
	}

	update();
}

void frmScreen::mousePressEvent(QMouseEvent *e)
{
	int status = screen->getStatus();

	if (status == ScreenAPI::SELECT) {
		screen->setStart(e->pos());
	} else if (status == ScreenAPI::MOV) {
		if (screen->isInArea(e->pos()) == false) {
			screen->setStart(e->pos());
			screen->setStatus(ScreenAPI::SELECT);
		} else {
			movPos = e->pos();
			this->setCursor(Qt::SizeAllCursor);
		}
	}

	update();
}

void frmScreen::mouseReleaseEvent(QMouseEvent *)
{
	if (screen->getStatus() == ScreenAPI::SELECT) {
		screen->setStatus(ScreenAPI::MOV);
	} else if (screen->getStatus() == ScreenAPI::MOV) {
		this->setCursor(Qt::ArrowCursor);
	}
}

void frmScreen::contextMenuEvent(QContextMenuEvent *)
{
	this->setCursor(Qt::ArrowCursor);
	menu->exec(cursor().pos());
}

3、使用

void frmMain::Screen()
{
//    顯示最大化
    frmScreen::Instance()->showMaximized();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章