十一、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();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值