簡體   English   中英

如何使用顏色 map 更改整個 QImage 像素值?

[英]How can I change the whole QImage pixel value using a color map?

我正在尋找一種方法來改變另一個像素的值。 我的想法是使用預定義的顏色圖將灰度顏色更改為彩色圖像,例如在 csv 格式( http://www.kennethmoreland.com/color-advice/ )中找到的 inferno。 首先,我在 csv 中獲取值並將其存儲為 Qvector,然后我嘗試使用它。

我已經看到我們可以使用 setColorMap 但它不起作用。

這是一個完整的可重現示例:

  • 需要下載 inferno256 inferno color map並更改 ColorMap.h 中的 PATH_INFERNO_COLORMAP

顏色映射.h

#ifndef COLORMAP_H
#define COLORMAP_H
#include <QDebug>
#include <QFile>
#include <QRgb>
#include <QTextStream>
#include <QVector>

const QString PATH_INFERNO_COLORMAP =
    "~/Documents/colormap/inferno-table-byte-0256.csv";

struct ColorMap {
  QVector<QRgb> inferno;

  void computeColorMap() {
    QFile file(PATH_INFERNO_COLORMAP);
    if (!file.open(QIODevice::ReadOnly)) {
      qDebug() << "ERROR: can't open inferno color map";
    }

    QTextStream in(&file);

    while (!in.atEnd()) {
      QString line = in.readLine();
      QStringList values = line.split(",");
      inferno.append(
          qRgb(values[1].toInt(), values[2].toInt(), values[3].toInt()));
    }

    file.close();
  }
};

#endif // COLORMAP_H

圖像.h

#ifndef IMAGE_H
#define IMAGE_H

#include "ColorMap.h"
#include <QImage>
#include <QPainter>
#include <QQuickItem>
#include <QQuickPaintedItem>

class Image : public QQuickPaintedItem {
  Q_OBJECT
  Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged)
public:
  Image(QQuickItem *parent = nullptr);
  Q_INVOKABLE void setImage(const QImage &image);
  Q_INVOKABLE void applyColorMap();
  void paint(QPainter *painter);
  QImage image() const;
signals:
  void imageChanged();

private:
  QImage current_image;
  ColorMap COLORMAP;
};
#endif // IMAGE_H

圖像.cpp

#include "image.h"
#include <QImage>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QQmlApplicationEngine>

Image::Image(QQuickItem *parent) : QQuickPaintedItem(parent) {
  QJsonObject reponse;
  QEventLoop event_loop;
  QImage my_image;
  QNetworkAccessManager *manager = new QNetworkAccessManager();
  QObject::connect(manager, SIGNAL(finished(QNetworkReply *)), &event_loop,
                   SLOT(quit()));
  QString full_url_request =
      "https://external-content.duckduckgo.com/iu/"
      "?u=https%3A%2F%2Fhdwallsbox.com%2Fwallpapers%2Fl%2F750x1334%2F20%"
      "2Fabstract-patterns-grayscale-artwork-750x1334-19824.jpg&f=1&nofb=1";
  const QUrl url_img = QUrl(full_url_request);
  QNetworkRequest request(url_img);
  QNetworkReply *reply = manager->get(request);
  event_loop.exec();
  if (reply->isFinished() && reply->error() == QNetworkReply::NoError) {
    my_image.loadFromData(reply->readAll());
    this->current_image = my_image;
    event_loop.exit();
    delete manager;
  } else {
    delete manager;
  }
}

void Image::paint(QPainter *painter) {
  QRectF bounding_rect = boundingRect();
  QImage scaled = this->current_image.scaledToHeight(bounding_rect.height());
  QPointF center = bounding_rect.center() - scaled.rect().center();

  if (center.x() < 0)
    center.setX(0);
  if (center.y() < 0)
    center.setY(0);
  painter->drawImage(center, scaled);
}

QImage Image::image() const { return this->current_image; }

void Image::setImage(const QImage &image) {
  this->current_image = image;
  update();
}

Q_INVOKABLE void Image::applyColorMap() {
  qDebug() << "apply_color_map";
  current_image.setColorTable(
      COLORMAP.inferno); // COLOR_MAP is an attribute of type
  update();
}

主文件

#include "image.h"
#include <QGuiApplication>
#include <QImage>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[]) {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

  QGuiApplication app(argc, argv);

  qmlRegisterType<Image>("MyImage", 1, 0, "MyImage");

  QQmlApplicationEngine engine;
  const QUrl url(QStringLiteral("qrc:/main.qml"));
  QObject::connect(
      &engine, &QQmlApplicationEngine::objectCreated, &app,
      [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
          QCoreApplication::exit(-1);
      },
      Qt::QueuedConnection);
  engine.load(url);

  return app.exec();
}

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import MyImage 1.0
import QtQuick.Controls 2.15
import QtQuick.Extras 1.4

Window {
    id: window
    width: 400
    height: 480
    visible: true

    Rectangle{
        id: background
        color: "black"
        width: parent.width
        height: parent.height
        anchors.fill: parent
    }

    Button {
        id: button
        text: qsTr("Apply color map")
        anchors.left: parent.horizontalCenter
        anchors.right: parent.horizontalCenter
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.leftMargin: -99
        anchors.rightMargin: -99
        anchors.topMargin: 8
        anchors.bottomMargin: 432
        width : 40
        height: 20

        onClicked: {
            my_image.applyColorMap();
    }
    }

    Item {
        id: item1
        y: 67
        height: 413
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.rightMargin: 0
        anchors.leftMargin: 0

        MyImage{
            id: my_image
            height: parent.height
            width: parent.width
        }
    }
}

在應用顏色表之前,請確保有一個索引圖像,否則將其轉換為所需的格式:

if(current_image.format() != QImage::Format_Indexed8)
{
    current_image = current_image.convertToFormat(QImage::Format_Indexed8);
}
current_image.setColorTable(
    COLORMAP.inferno); // COLOR_MAP is an attribute of type

不確定您要達到的目標,但我猜原始圖像應該是 8 位灰度格式,所以也許,您可以先檢查一下:

if(current_image.format() != QImage::Format_Grayscale8)
{
    current_image = current_image.convertToFormat(QImage::Format_Grayscale8);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM