source: trunk/doc/src/snippets/separations/viewer.cpp@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 11.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*
43viewer.cpp
44
45Provides a main window for displaying a user-specified original image
46with three color separations in a grid layout.
47
48A main menu provides entries for selecting files, and adjusting the
49brightness of the separations.
50*/
51
52#include <QtGui>
53
54#include "finalwidget.h"
55#include "screenwidget.h"
56#include "viewer.h"
57
58/*
59 Constructor: initializes a default value for the brightness, creates
60 the main menu entries, and constructs a central widget that contains
61 enough space for images to be displayed.
62*/
63
64Viewer::Viewer()
65{
66 setWindowTitle(tr("QImage Color Separations"));
67
68 brightness = 255;
69
70 createMenus();
71 setCentralWidget(createCentralWidget());
72}
73
74/*
75 Creates a main menu with two entries: a File menu, to allow the image
76 to be selected, and a Brightness menu to allow the brightness of the
77 separations to be changed.
78
79 Initially, the Brightness menu items are disabled, but the first entry in
80 the menu is checked to reflect the default brightness.
81*/
82
83void Viewer::createMenus()
84{
85 fileMenu = new QMenu(tr("&File"), this);
86 brightnessMenu = new QMenu(tr("&Brightness"), this);
87
88 QAction *openAction = fileMenu->addAction(tr("&Open..."));
89 openAction->setShortcut(QKeySequence("Ctrl+O"));
90 saveAction = fileMenu->addAction(tr("&Save..."));
91 saveAction->setShortcut(QKeySequence("Ctrl+S"));
92 saveAction->setEnabled(false);
93 QAction *quitAction = fileMenu->addAction(tr("E&xit"));
94 quitAction->setShortcut(QKeySequence("Ctrl+Q"));
95
96 QAction *noBrightness = brightnessMenu->addAction(tr("&0%"));
97 noBrightness->setCheckable(true);
98 QAction *quarterBrightness = brightnessMenu->addAction(tr("&25%"));
99 quarterBrightness->setCheckable(true);
100 QAction *halfBrightness = brightnessMenu->addAction(tr("&50%"));
101 halfBrightness->setCheckable(true);
102 QAction *threeQuartersBrightness = brightnessMenu->addAction(tr("&75%"));
103 threeQuartersBrightness->setCheckable(true);
104 QAction *fullBrightness = brightnessMenu->addAction(tr("&100%"));
105 fullBrightness->setCheckable(true);
106
107 menuMap[noBrightness] = None;
108 menuMap[quarterBrightness] = Quarter;
109 menuMap[halfBrightness] = Half;
110 menuMap[threeQuartersBrightness] = ThreeQuarters;
111 menuMap[fullBrightness] = Full;
112
113 currentBrightness = fullBrightness;
114 currentBrightness->setChecked(true);
115 brightnessMenu->setEnabled(false);
116
117 menuBar()->addMenu(fileMenu);
118 menuBar()->addMenu(brightnessMenu);
119
120 connect(openAction, SIGNAL(triggered()), this, SLOT(chooseFile()));
121 connect(saveAction, SIGNAL(triggered()), this, SLOT(saveImage()));
122 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
123 connect(brightnessMenu, SIGNAL(triggered(QAction *)), this,
124 SLOT(setBrightness(QAction *)));
125}
126
127/*
128 Constructs a central widget for the window consisting of a two-by-two
129 grid of labels, each of which will contain an image. We restrict the
130 size of the labels to 256 pixels, and ensure that the window cannot
131 be resized.
132*/
133
134QFrame* Viewer::createCentralWidget()
135{
136 QFrame* frame = new QFrame(this);
137 grid = new QGridLayout(frame);
138 grid->setSpacing(8);
139 grid->setMargin(4);
140
141 layout()->setSizeConstraint(QLayout::SetFixedSize);
142
143 QSize labelSize(256, 256);
144
145 finalWidget = new FinalWidget(frame, tr("Final image"), labelSize);
146
147 cyanWidget = new ScreenWidget(frame, Qt::cyan, tr("Cyan"),
148 ScreenWidget::Cyan, labelSize);
149 magentaWidget = new ScreenWidget(frame, Qt::magenta, tr("Magenta"),
150 ScreenWidget::Magenta, labelSize);
151 yellowWidget = new ScreenWidget(frame, Qt::yellow, tr("Yellow"),
152 ScreenWidget::Yellow, labelSize);
153
154 connect(cyanWidget, SIGNAL(imageChanged()), this, SLOT(createImage()));
155 connect(magentaWidget, SIGNAL(imageChanged()), this, SLOT(createImage()));
156 connect(yellowWidget, SIGNAL(imageChanged()), this, SLOT(createImage()));
157
158 grid->addWidget(finalWidget, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
159 grid->addWidget(cyanWidget, 0, 1, Qt::AlignTop | Qt::AlignHCenter);
160 grid->addWidget(magentaWidget, 1, 0, Qt::AlignTop | Qt::AlignHCenter);
161 grid->addWidget(yellowWidget, 1, 1, Qt::AlignTop | Qt::AlignHCenter);
162
163 return frame;
164}
165
166/*
167 Provides a dialog window to allow the user to specify an image file.
168 If a file is selected, the appropriate function is called to process
169 and display it.
170*/
171
172void Viewer::chooseFile()
173{
174 QString imageFile = QFileDialog::getOpenFileName(this,
175 tr("Choose an image file to open"), path, tr("Images (*.*)"));
176
177 if (!imageFile.isEmpty()) {
178 openImageFile(imageFile);
179 path = imageFile;
180 }
181}
182
183/*
184 Changes the value of the brightness according to the entry selected in the
185 Brightness menu. The selected entry is checked, and the previously selected
186 entry is unchecked.
187
188 The color separations are updated to use the new value for the brightness.
189*/
190
191void Viewer::setBrightness(QAction *action)
192{
193 if (!menuMap.contains(action) || scaledImage.isNull())
194 return;
195
196 Brightness amount = menuMap[action];
197
198 switch (amount) {
199 case None:
200 brightness = 0; break;
201 case Quarter:
202 brightness = 64; break;
203 case Half:
204 brightness = 128; break;
205 case ThreeQuarters:
206 brightness = 191; break;
207 case Full:
208 brightness = 255; break;
209 default: return;
210 }
211
212 currentBrightness->setChecked(false);
213 currentBrightness = action;
214 currentBrightness->setChecked(true);
215
216 createImage();
217}
218
219/*
220 Load the image from the file given, and create four pixmaps based
221 on the original image.
222
223 The window caption is set, and the Brightness menu enabled if the image file
224 can be loaded.
225*/
226
227void Viewer::openImageFile(QString &imageFile)
228{
229 QImage originalImage;
230
231 if (originalImage.load(imageFile)) {
232 setWindowTitle(imageFile);
233 //menuBar()->setItemEnabled(brightnessMenuId, true);
234 saveAction->setEnabled(true);
235 brightnessMenu->setEnabled(true);
236
237 /* Note: the ScaleMin value may be different for Qt 4. */
238 scaledImage = originalImage.scaled(256, 256, Qt::KeepAspectRatio);
239
240 cyanWidget->setImage(scaledImage);
241 magentaWidget->setImage(scaledImage);
242 yellowWidget->setImage(scaledImage);
243 createImage();
244 }
245 else
246 (void) QMessageBox::warning(this, tr("Cannot open file"),
247 tr("The selected file could not be opened."),
248 QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton);
249}
250
251/*
252 Creates an image by combining the contents of the three screens
253 to present a page preview.
254
255 The image associated with each screen is separated into cyan,
256 magenta, and yellow components. We add up the values for each
257 component from the three screen images, and subtract the totals
258 from the maximum value for each corresponding primary color.
259*/
260
261void Viewer::createImage()
262{
263 QImage newImage = scaledImage.copy();
264
265 QImage *image1 = cyanWidget->image();
266 QImage *image2 = magentaWidget->image();
267 QImage *image3 = yellowWidget->image();
268 int darkness = 255 - brightness;
269
270 for (int y = 0; y < newImage.height(); ++y) {
271 for (int x = 0; x < newImage.width(); ++x) {
272
273 // Create three screens, using the quantities of the source
274 // CMY components to determine how much of each of the
275 // inks are to be put on each screen.
276 QRgb p1(image1->pixel(x, y));
277 float cyan1 = 255 - qRed(p1);
278 float magenta1 = 255 - qGreen(p1);
279 float yellow1 = 255 - qBlue(p1);
280
281 QRgb p2(image2->pixel(x, y));
282 float cyan2 = 255 - qRed(p2);
283 float magenta2 = 255 - qGreen(p2);
284 float yellow2 = 255 - qBlue(p2);
285
286 QRgb p3(image3->pixel(x, y));
287 float cyan3 = 255 - qRed(p3);
288 float magenta3 = 255 - qGreen(p3);
289 float yellow3 = 255 - qBlue(p3);
290
291 QColor newColor(
292 qMax(255 - int(cyan1+cyan2+cyan3) - darkness, 0),
293 qMax(255 - int(magenta1+magenta2+magenta3) - darkness, 0),
294 qMax(255 - int(yellow1+yellow2+yellow3) - darkness, 0));
295
296 newImage.setPixel(x, y, newColor.rgb());
297 }
298 }
299
300 finalWidget->setPixmap(QPixmap::fromImage(newImage));
301}
302
303/*
304 Provides a dialog window to allow the user to save the image file.
305*/
306
307void Viewer::saveImage()
308{
309 QString imageFile = QFileDialog::getSaveFileName(this,
310 tr("Choose a filename to save the image"), "", tr("Images (*.png)"));
311
312 QFileInfo info(imageFile);
313
314 if (!info.baseName().isEmpty()) {
315 QString newImageFile = QFileInfo(info.absoluteDir(),
316 info.baseName() + ".png").absoluteFilePath();
317
318 if (!finalWidget->pixmap()->save(newImageFile, "PNG"))
319 (void) QMessageBox::warning(this, tr("Cannot save file"),
320 tr("The file could not be saved."),
321 QMessageBox::Cancel, QMessageBox::NoButton,
322 QMessageBox::NoButton);
323 }
324 else
325 (void) QMessageBox::warning(this, tr("Cannot save file"),
326 tr("Please enter a valid filename."),
327 QMessageBox::Cancel, QMessageBox::NoButton,
328 QMessageBox::NoButton);
329}
Note: See TracBrowser for help on using the repository browser.