Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
viewer.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
4/*
5viewer.cpp
6
7Provides a main window for displaying a user-specified original image
8with three color separations in a grid layout.
9
10A main menu provides entries for selecting files, and adjusting the
11brightness of the separations.
12*/
13
14#include <QtWidgets>
15
16#include "finalwidget.h"
17#include "screenwidget.h"
18#include "viewer.h"
19
20/*
21 Constructor: initializes a default value for the brightness, creates
22 the main menu entries, and constructs a central widget that contains
23 enough space for images to be displayed.
24*/
25
27{
28 setWindowTitle(tr("QImage Color Separations"));
29
30 brightness = 255;
31
32 createMenus();
33 setCentralWidget(createCentralWidget());
34}
35
36/*
37 Creates a main menu with two entries: a File menu, to allow the image
38 to be selected, and a Brightness menu to allow the brightness of the
39 separations to be changed.
40
41 Initially, the Brightness menu items are disabled, but the first entry in
42 the menu is checked to reflect the default brightness.
43*/
44
45void Viewer::createMenus()
46{
47 fileMenu = new QMenu(tr("&File"), this);
48 brightnessMenu = new QMenu(tr("&Brightness"), this);
49
50 QAction *openAction = fileMenu->addAction(tr("&Open..."));
51 openAction->setShortcut(QKeySequence("Ctrl+O"));
52 saveAction = fileMenu->addAction(tr("&Save..."));
53 saveAction->setShortcut(QKeySequence("Ctrl+S"));
54 saveAction->setEnabled(false);
55 QAction *quitAction = fileMenu->addAction(tr("E&xit"));
56 quitAction->setShortcut(QKeySequence("Ctrl+Q"));
57
58 QAction *noBrightness = brightnessMenu->addAction(tr("&0%"));
59 noBrightness->setCheckable(true);
60 QAction *quarterBrightness = brightnessMenu->addAction(tr("&25%"));
61 quarterBrightness->setCheckable(true);
62 QAction *halfBrightness = brightnessMenu->addAction(tr("&50%"));
63 halfBrightness->setCheckable(true);
64 QAction *threeQuartersBrightness = brightnessMenu->addAction(tr("&75%"));
65 threeQuartersBrightness->setCheckable(true);
66 QAction *fullBrightness = brightnessMenu->addAction(tr("&100%"));
67 fullBrightness->setCheckable(true);
68
69 menuMap[noBrightness] = None;
70 menuMap[quarterBrightness] = Quarter;
71 menuMap[halfBrightness] = Half;
72 menuMap[threeQuartersBrightness] = ThreeQuarters;
73 menuMap[fullBrightness] = Full;
74
75 currentBrightness = fullBrightness;
76 currentBrightness->setChecked(true);
77 brightnessMenu->setEnabled(false);
78
79 menuBar()->addMenu(fileMenu);
80 menuBar()->addMenu(brightnessMenu);
81
82 connect(openAction, &QAction::triggered, this, &Viewer::chooseFile);
83 connect(saveAction, &QAction::triggered, this, &Viewer::saveImage);
85 connect(brightnessMenu, &QMenu::triggered,
87}
88
89/*
90 Constructs a central widget for the window consisting of a two-by-two
91 grid of labels, each of which will contain an image. We restrict the
92 size of the labels to 256 pixels, and ensure that the window cannot
93 be resized.
94*/
95
96QFrame* Viewer::createCentralWidget()
97{
98 QFrame* frame = new QFrame(this);
99 grid = new QGridLayout(frame);
100 grid->setSpacing(8);
101
103
104 QSize labelSize(256, 256);
105
106 finalWidget = new FinalWidget(frame, tr("Final image"), labelSize);
107
108 cyanWidget = new ScreenWidget(frame, Qt::cyan, tr("Cyan"),
109 ScreenWidget::Cyan, labelSize);
110 magentaWidget = new ScreenWidget(frame, Qt::magenta, tr("Magenta"),
111 ScreenWidget::Magenta, labelSize);
112 yellowWidget = new ScreenWidget(frame, Qt::yellow, tr("Yellow"),
113 ScreenWidget::Yellow, labelSize);
114
118
119 grid->addWidget(finalWidget, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
120 grid->addWidget(cyanWidget, 0, 1, Qt::AlignTop | Qt::AlignHCenter);
121 grid->addWidget(magentaWidget, 1, 0, Qt::AlignTop | Qt::AlignHCenter);
122 grid->addWidget(yellowWidget, 1, 1, Qt::AlignTop | Qt::AlignHCenter);
123
124 return frame;
125}
126
127/*
128 Provides a dialog window to allow the user to specify an image file.
129 If a file is selected, the appropriate function is called to process
130 and display it.
131*/
132
134{
135 QString imageFile = QFileDialog::getOpenFileName(this,
136 tr("Choose an image file to open"), path, tr("Images (*.*)"));
137
138 if (!imageFile.isEmpty()) {
139 openImageFile(imageFile);
140 path = imageFile;
141 }
142}
143
144/*
145 Changes the value of the brightness according to the entry selected in the
146 Brightness menu. The selected entry is checked, and the previously selected
147 entry is unchecked.
148
149 The color separations are updated to use the new value for the brightness.
150*/
151
153{
154 if (!menuMap.contains(action) || scaledImage.isNull())
155 return;
156
157 Brightness amount = menuMap[action];
158
159 switch (amount) {
160 case None:
161 brightness = 0; break;
162 case Quarter:
163 brightness = 64; break;
164 case Half:
165 brightness = 128; break;
166 case ThreeQuarters:
167 brightness = 191; break;
168 case Full:
169 brightness = 255; break;
170 default: return;
171 }
172
173 currentBrightness->setChecked(false);
174 currentBrightness = action;
175 currentBrightness->setChecked(true);
176
177 createImage();
178}
179
180/*
181 Load the image from the file given, and create four pixmaps based
182 on the original image.
183
184 The window caption is set, and the Brightness menu enabled if the image file
185 can be loaded.
186*/
187
188void Viewer::openImageFile(QString &imageFile)
189{
190 QImage originalImage;
191
192 if (originalImage.load(imageFile)) {
193 setWindowTitle(imageFile);
194 //menuBar()->setItemEnabled(brightnessMenuId, true);
195 saveAction->setEnabled(true);
196 brightnessMenu->setEnabled(true);
197
198 /* Note: the ScaleMin value may be different for Qt 4. */
199 scaledImage = originalImage.scaled(256, 256, Qt::KeepAspectRatio);
200
201 cyanWidget->setImage(scaledImage);
202 magentaWidget->setImage(scaledImage);
203 yellowWidget->setImage(scaledImage);
204 createImage();
205 }
206 else
207 (void) QMessageBox::warning(this, tr("Cannot open file"),
208 tr("The selected file could not be opened."),
210}
211
212/*
213 Creates an image by combining the contents of the three screens
214 to present a page preview.
215
216 The image associated with each screen is separated into cyan,
217 magenta, and yellow components. We add up the values for each
218 component from the three screen images, and subtract the totals
219 from the maximum value for each corresponding primary color.
220*/
221
223{
224 QImage newImage = scaledImage.copy();
225
226 QImage *image1 = cyanWidget->image();
227 QImage *image2 = magentaWidget->image();
228 QImage *image3 = yellowWidget->image();
229 int darkness = 255 - brightness;
230
231 for (int y = 0; y < newImage.height(); ++y) {
232 for (int x = 0; x < newImage.width(); ++x) {
233
234 // Create three screens, using the quantities of the source
235 // CMY components to determine how much of each of the
236 // inks are to be put on each screen.
237 QRgb p1(image1->pixel(x, y));
238 float cyan1 = 255 - qRed(p1);
239 float magenta1 = 255 - qGreen(p1);
240 float yellow1 = 255 - qBlue(p1);
241
242 QRgb p2(image2->pixel(x, y));
243 float cyan2 = 255 - qRed(p2);
244 float magenta2 = 255 - qGreen(p2);
245 float yellow2 = 255 - qBlue(p2);
246
247 QRgb p3(image3->pixel(x, y));
248 float cyan3 = 255 - qRed(p3);
249 float magenta3 = 255 - qGreen(p3);
250 float yellow3 = 255 - qBlue(p3);
251
252 QColor newColor(
253 qMax(255 - int(cyan1+cyan2+cyan3) - darkness, 0),
254 qMax(255 - int(magenta1+magenta2+magenta3) - darkness, 0),
255 qMax(255 - int(yellow1+yellow2+yellow3) - darkness, 0));
256
257 newImage.setPixel(x, y, newColor.rgb());
258 }
259 }
260
261 finalWidget->setPixmap(QPixmap::fromImage(newImage));
262}
263
264/*
265 Provides a dialog window to allow the user to save the image file.
266*/
267
269{
270 QString imageFile = QFileDialog::getSaveFileName(this,
271 tr("Choose a filename to save the image"), "", tr("Images (*.png)"));
272
273 QFileInfo info(imageFile);
274
275 if (!info.baseName().isEmpty()) {
276 QString newImageFile = QFileInfo(info.absoluteDir(),
277 info.baseName() + ".png").absoluteFilePath();
278
279 if (!finalWidget->pixmap().save(newImageFile, "PNG"))
280 (void) QMessageBox::warning(this, tr("Cannot save file"),
281 tr("The file could not be saved."),
284 }
285 else
286 (void) QMessageBox::warning(this, tr("Cannot save file"),
287 tr("Please enter a valid filename."),
290}
QPixmap pixmap() const
void setPixmap(const QPixmap &pixmap)
The QAction class provides an abstraction for user commands that can be added to different user inter...
Definition qaction.h:30
void setChecked(bool)
Definition qaction.cpp:877
void triggered(bool checked=false)
This signal is emitted when an action is activated by the user; for example, when the user clicks a m...
void setEnabled(bool)
Definition qaction.cpp:927
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
static void quit()
\threadsafe
static QString getSaveFileName(QWidget *parent=nullptr, const QString &caption=QString(), const QString &dir=QString(), const QString &filter=QString(), QString *selectedFilter=nullptr, Options options=Options())
This is a convenience static function that returns a file name selected by the user.
static QString getOpenFileName(QWidget *parent=nullptr, const QString &caption=QString(), const QString &dir=QString(), const QString &filter=QString(), QString *selectedFilter=nullptr, Options options=Options())
This is a convenience static function that returns an existing file selected by the user.
QString absoluteFilePath() const
The QFrame class is the base class of widgets that can have a frame.
Definition qframe.h:17
The QGridLayout class lays out widgets in a grid.
Definition qgridlayout.h:21
void addWidget(QWidget *w)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qgridlayout.h:64
void setSpacing(int spacing) override
This function sets both the vertical and horizontal spacing to spacing.
\inmodule QtGui
Definition qimage.h:37
QImage scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qimage.h:209
void setPixel(int x, int y, uint index_or_rgb)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qimage.cpp:2588
QRgb pixel(int x, int y) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qimage.cpp:2493
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
int width() const
Returns the width of the image.
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition qimage.cpp:1222
int height() const
Returns the height of the image.
bool load(QIODevice *device, const char *format)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qimage.cpp:3780
The QKeySequence class encapsulates a key sequence as used by shortcuts.
void setSizeConstraint(SizeConstraint)
Definition qlayout.cpp:1241
@ SetFixedSize
Definition qlayout.h:39
void setCentralWidget(QWidget *widget)
Sets the given widget to be the main window's central widget.
bool contains(const Key &key) const
Definition qmap.h:341
QAction * addMenu(QMenu *menu)
Appends menu to the menu bar.
Definition qmenubar.cpp:768
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus.
Definition qmenu.h:26
void triggered(QAction *action)
This signal is emitted when an action in this menu is triggered.
void addAction(QAction *action)
Appends the action action to this widget's list of actions.
Definition qwidget.cpp:3117
static StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition qpixmap.cpp:1437
bool save(const QString &fileName, const char *format=nullptr, int quality=-1) const
Saves the pixmap to the file with the given fileName using the specified image file format and qualit...
Definition qpixmap.cpp:803
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void setEnabled(bool)
Definition qwidget.cpp:3358
QLayout * layout() const
Returns the layout manager that is installed on this widget, or \nullptr if no layout manager is inst...
int y
the y coordinate of the widget relative to its parent and including any window frame
Definition qwidget.h:110
int x
the x coordinate of the widget relative to its parent including any window frame
Definition qwidget.h:109
void setWindowTitle(const QString &)
Definition qwidget.cpp:6105
void imageChanged()
QImage * image()
Returns a pointer to the modified image.
void setImage(QImage &image)
Records the original image selected by the user, creates a color separation, and enables the invert i...
void setBrightness(QAction *action)
Definition viewer.cpp:152
void saveImage()
Definition viewer.cpp:268
Viewer()
Definition viewer.cpp:26
Brightness
Definition viewer.h:23
@ Full
Definition viewer.h:23
@ ThreeQuarters
Definition viewer.h:23
@ None
Definition viewer.h:23
@ Quarter
Definition viewer.h:23
@ Half
Definition viewer.h:23
void createImage()
Definition viewer.cpp:222
void chooseFile()
Definition viewer.cpp:133
QPixmap p2
QPixmap p1
[0]
@ AlignTop
Definition qnamespace.h:153
@ AlignHCenter
Definition qnamespace.h:148
@ KeepAspectRatio
@ cyan
Definition qnamespace.h:38
@ magenta
Definition qnamespace.h:39
@ yellow
Definition qnamespace.h:40
#define qApp
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLint GLint GLint GLint GLint x
[0]
GLint y
GLsizei const GLchar *const * path
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition qrgb.h:13
constexpr int qRed(QRgb rgb)
Definition qrgb.h:18
constexpr int qGreen(QRgb rgb)
Definition qrgb.h:21
constexpr int qBlue(QRgb rgb)
Definition qrgb.h:24
#define tr(X)
QFrame frame
[0]
QMenuBar * menuBar
[0]
QHostInfo info
[0]