我有一些图案它们是黑色的α和有我想提请符合模式的几点思考。
我觉得QBrush可以通过纹理构造,但我不知道如何用不同颜色绘制。
这个答案显示的方式在这里的C#代码,但我不知道如何改变图案颜色与嘉洛斯。
我有一些图案它们是黑色的α和有我想提请符合模式的几点思考。
我觉得QBrush可以通过纹理构造,但我不知道如何用不同颜色绘制。
这个答案显示的方式在这里的C#代码,但我不知道如何改变图案颜色与嘉洛斯。
使用5×5的颜色矩阵的图像的RGBA值的修改提醒我的转化齐次坐标如何它常常在计算机图形中使用。 如果你想像的RGBA值4维的颜色/ alpha空间的使用变换矩阵听起来并不革命性色彩的转变。 (不是说你让我错了 - 这让我印象深刻了,我忍不住要立刻尝试了这一点)。因此,我不知道为什么需要一个5X5矩阵,虽然只有4个颜色分量。 (例如,如果颜色值的翻译意第五维卡梅斯发挥作用。)
我必须承认,我首先应用于从电脑动画我认识到这个问题,我比较的方法来MSDN上描述的一个使用彩色矩阵变换到一个单一的颜色之后。 后来我明白了,原来纸相比,矿采用互换的向量和矩阵。 这只是作为数学
(ⅴTm 值 T)T = V” = M v
如果我没有记错的权利。
实际上,这意味着我必须使用矩阵的行,列,当我尝试重现如的样品嘉洛斯指南 。 (这在某种程度上觉得我的权利,因为它是完全一样的,我们描述了在三维空间中,即平移变换是变换矩阵的最后一列。)
示例代码:
colorMatrix.h
:
#ifndef COLOR_MATRIX_H
#define COLOR_MATRIX_H
#include <algorithm>
struct ColorMatrix {
float values[5][5];
ColorMatrix() { }
ColorMatrix(const float(&values)[25])
{
std::copy(std::begin(values), std::end(values), (float*)this->values);
}
float (&operator[](unsigned i))[5] { return values[i]; }
const float(&operator[](unsigned i) const)[5] { return values[i]; }
};
struct ColorVector {
float values[5];
ColorVector(const float(&values)[5])
{
std::copy(std::begin(values), std::end(values), (float*)this->values);
}
float& operator[](size_t i) { return values[i]; }
const float& operator[](size_t i) const { return values[i]; }
};
#endif // COLOR_MATRIX_H
colorMatrix.cc
:
#include <algorithm>
#include <QtWidgets>
#include "colorMatrix.h"
#include "QColorMatrixView.h"
ColorVector operator*(const ColorMatrix &m, const ColorVector &v)
{
return ColorVector({
m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3] + m[0][4] * v[4],
m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3] + m[1][4] * v[4],
m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3] + m[2][4] * v[4],
m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3] + m[3][4] * v[4],
m[4][0] * v[0] + m[4][1] * v[1] + m[4][2] * v[2] + m[4][3] * v[3] + m[4][4] * v[4]
});
}
const ColorMatrix Identity({
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f
});
template <typename T>
T clamp(T value, T min, T max)
{
return value < min ? min
: value > max ? max
: value;
}
QRgb transform(const ColorMatrix &mat, const QRgb &color)
{
ColorVector vec({
qRed(color) / 255.0f, qGreen(color) / 255.0f, qBlue(color) / 255.0f, qAlpha(color) / 255.0f, 1.0f });
vec = mat * vec;
if (vec[4] != 0.0f) {
vec[0] /= vec[4]; vec[1] /= vec[4]; vec[2] /= vec[4]; vec[3] /= vec[4]; // vec[4] = 1.0f;
}
return qRgba(
clamp<int>(255 * vec[0], 0, 255),
clamp<int>(255 * vec[1], 0, 255),
clamp<int>(255 * vec[2], 0, 255),
clamp<int>(255 * vec[3], 0, 255));
}
QImage transform(const ColorMatrix &mat, const QImage &qImg)
{
const int w = qImg.width(), h = qImg.height();
QImage qImgDst(w, h, qImg.format());
for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) {
qImgDst.setPixel(x, y, transform(mat, qImg.pixel(x, y)));
}
return qImgDst;
}
QImage open(QWidget *pQParent)
{
return QImage(
QFileDialog::getOpenFileName(pQParent,
QString::fromUtf8("Open Image File"),
QString()));
}
void update(
QLabel &qLblViewResult,
const QColorMatrixView &qEditColMat, const QLabel &qLblViewOrig)
{
ColorMatrix colMat = qEditColMat.values();
const QPixmap *pQPixmap = qLblViewOrig.pixmap();
const QImage qImg = pQPixmap ? pQPixmap->toImage() : QImage();
qLblViewResult.setPixmap(
QPixmap::fromImage(transform(colMat, qImg)));
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// setup GUI
QWidget qWin;
qWin.setWindowTitle(QString::fromUtf8("Qt Color Matrix Demo"));
QGridLayout qGrid;
QVBoxLayout qVBoxColMat;
QLabel qLblColMat(QString::fromUtf8("Color Matrix:"));
qVBoxColMat.addWidget(&qLblColMat, 0);
QColorMatrixView qEditColMat;
qEditColMat.setValues(Identity);
qVBoxColMat.addWidget(&qEditColMat);
QPushButton qBtnReset(QString::fromUtf8("Identity"));
qVBoxColMat.addWidget(&qBtnReset);
QPushButton qBtnGray(QString::fromUtf8("Grayscale"));
qVBoxColMat.addWidget(&qBtnGray);
qVBoxColMat.addStretch(1);
qGrid.addLayout(&qVBoxColMat, 0, 0, 2, 1);
QLabel qLblX(QString::fromUtf8(" \xc3\x97 "));
qGrid.addWidget(&qLblX, 0, 1);
QLabel qLblViewOrig;
qGrid.addWidget(&qLblViewOrig, 0, 2);
QPushButton qBtnLoad(QString::fromUtf8("Open..."));
qGrid.addWidget(&qBtnLoad, 1, 2);
QLabel qLblEq(QString::fromUtf8(" = "));
qGrid.addWidget(&qLblEq, 0, 3);
QLabel qLblViewResult;
qGrid.addWidget(&qLblViewResult, 0, 4);
qWin.setLayout(&qGrid);
qWin.show();
// install signal handlers
QObject::connect(&qEditColMat, &QColorMatrixView::editingFinished,
[&]() { update(qLblViewResult, qEditColMat, qLblViewOrig); });
QObject::connect(&qBtnReset, &QPushButton::clicked,
[&]() {
qEditColMat.setValues(Identity);
update(qLblViewResult, qEditColMat, qLblViewOrig);
});
QObject::connect(&qBtnGray, &QPushButton::clicked,
[&]() {
qEditColMat.setValues(ColorMatrix({
0.33f, 0.59f, 0.11f, 0.0f, 0.0f,
0.33f, 0.59f, 0.11f, 0.0f, 0.0f,
0.33f, 0.59f, 0.11f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f,
0.00f, 0.00f, 0.00f, 0.0f, 1.0f
}));
update(qLblViewResult, qEditColMat, qLblViewOrig);
});
QObject::connect(&qBtnLoad, &QPushButton::clicked,
[&]() {
qLblViewOrig.setPixmap(QPixmap::fromImage(open(&qBtnLoad)));
update(qLblViewResult, qEditColMat, qLblViewOrig);
});
// initial contents
{
QImage qImg("colorMatrixDefault.jpg");
qLblViewOrig.setPixmap(QPixmap::fromImage(qImg));
update(qLblViewResult, qEditColMat, qLblViewOrig);
}
// runtime loop
return app.exec();
}
QColorMatrixView.h
:
#ifndef Q_COLOR_MATRIX_VIEW_H
#define Q_COLOR_MATRIX_VIEW_H
#include <QLineEdit>
#include <QGridLayout>
#include <QWidget>
#include "colorMatrix.h"
class QColorMatrixView: public QWidget {
Q_OBJECT
private:
QGridLayout _qGrid;
QLineEdit _qEdit[5][5];
signals:
void editingFinished();
public:
QColorMatrixView(QWidget *pQParent = nullptr);
virtual ~QColorMatrixView() = default;
QColorMatrixView(const QColorMatrixView&) = delete;
QColorMatrixView& operator=(const QColorMatrixView&) = delete;
ColorMatrix values() const;
void setValues(const ColorMatrix &mat);
};
#endif // Q_COLOR_MATRIX_VIEW_H
QColorMatrixView.cc
:
#include "QColorMatrixView.h"
QColorMatrixView::QColorMatrixView(QWidget *pQParent):
QWidget(pQParent)
{
QFontMetrics qFontMetrics(font());
const int w = qFontMetrics.boundingRect(QString("-000.000")).width() + 10;
for (int r = 0; r < 5; ++r) {
for (int c = 0; c < 5; ++c) {
QLineEdit &qEdit = _qEdit[r][c];
_qGrid.addWidget(&qEdit, r, c);
qEdit.setFixedWidth(w);
QObject::connect(&qEdit, &QLineEdit::editingFinished,
[this, r, c]() {
_qEdit[r][c].setText(
QString::number(_qEdit[r][c].text().toFloat(), 'f', 3));
editingFinished();
});
}
}
setLayout(&_qGrid);
}
ColorMatrix QColorMatrixView::values() const
{
ColorMatrix mat;
for (int r = 0; r < 5; ++r) for (int c = 0; c < 5; ++c) {
mat[r][c] = _qEdit[r][c].text().toFloat();
}
return mat;
}
void QColorMatrixView::setValues(const ColorMatrix &mat)
{
for (int r = 0; r < 5; ++r) for (int c = 0; c < 5; ++c) {
_qEdit[r][c].setText(QString::number(mat[r][c], 'f', 3));
}
}
moc_colorMatrix.cc
(考虑MOC生成源):
#include "moc_QColorMatrixView.cpp"
colorMatrix.pro
(中的qmake项目文件):
SOURCES = colorMatrix.cc QColorMatrixView.cc
HEADERS = colorMatrix.h QColorMatrixView.h
SOURCES += moc_colorMatrix.cc
MOC_DIR = .
QT += widgets
和默认的样本图像colorMatrixDefault.jpg
如果没有(猫)照片文件就在眼前:
虽然,我已经开发并在VS2013测试的应用程序,我建的和还测试上的cygwin ,以确保Qmake工程已经完成,自立式:
$ qmake-qt5 colorMatrix.pro
$ make
$ ./colorMatrix
此示例代码的增强版本,可以在github上发现的Qt彩色矩阵演示 。