VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UIImageTools.cpp@ 43138

Last change on this file since 43138 was 41527, checked in by vboxsync, 12 years ago

FE/Qt: Warnings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: UIImageTools.cpp 41527 2012-05-31 16:29:00Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * Implementation of utility classes and functions for image manipulation
6 */
7
8/*
9 * Copyright (C) 2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Local include */
21#include "UIImageTools.h"
22
23/* Qt includes */
24#include <QPainter>
25
26/* System includes */
27#include <math.h>
28
29/* Todo: Think about the naming convention and if the images should be
30 * processed in place or return changed copies. Make it more uniform. Add
31 * asserts if the bit depth of the given image could not processed. */
32
33QImage toGray(const QImage& image)
34{
35 QImage result = image.convertToFormat(QImage::Format_ARGB32);
36 for (int y = 0; y < result.height(); ++y)
37 {
38 QRgb *pScanLine = (QRgb*)result.scanLine(y);
39 for (int x = 0; x < result.width(); ++x)
40 {
41 const int g = qGray(pScanLine[x]);
42 pScanLine[x] = qRgba(g, g, g, qAlpha(pScanLine[x]));
43 }
44 }
45 return result;
46}
47
48void dimImage(QImage& image)
49{
50 /* Todo: factor out the < 32bit case, cause this can be done a lot faster
51 * by just processing every second line. */
52 for (int y = 0; y < image.height(); ++y)
53 {
54 QRgb *sl = (QRgb*)image.scanLine(y);
55 if (y % 2)
56 {
57 if (image.depth() == 32)
58 {
59 for (int x = 0; x < image.width(); ++x)
60 {
61 const int gray = qGray(sl[x]) / 2;
62 sl[x] = qRgba(gray, gray, gray, qAlpha(sl[x]));
63 }
64 }
65 else
66 ::memset(sl, 0, image.bytesPerLine());
67 }
68 else
69 {
70 if (image.depth() == 32)
71 {
72 for (int x = 0; x < image.width(); ++x)
73 {
74 const int gray = (2 * qGray(sl[x])) / 3;
75 sl[x] = qRgba(gray, gray, gray, qAlpha(sl[x]));
76 }
77 }
78 }
79 }
80}
81
82void blurImage(const QImage &source, QImage &dest, int r)
83{
84 /* Blur in two steps. First horizontal and then vertical. Todo: search
85 * for more optimization. */
86 QImage tmpImage(source.size(), QImage::Format_ARGB32);
87 blurImageHorizontal(source, tmpImage, r);
88 blurImageVertical(tmpImage, dest, r);
89}
90
91void blurImageHorizontal(const QImage &source, QImage &dest, int r)
92{
93 QSize s = source.size();
94 for (int y = 0; y < s.height(); ++y)
95 {
96 int rt = 0;
97 int gt = 0;
98 int bt = 0;
99 int at = 0;
100
101 /* In the horizontal case we can just use the scanline, which is
102 * much faster than accessing every pixel with the QImage::pixel
103 * method. Unfortunately this doesn't work in the vertical case. */
104 QRgb* ssl = (QRgb*)source.scanLine(y);
105 QRgb* dsl = (QRgb*)dest.scanLine(y);
106 /* First process the horizontal zero line at once */
107 int b = r + 1;
108 for (int x1 = 0; x1 <= r; ++x1)
109 {
110 QRgb rgba = ssl[x1];
111 rt += qRed(rgba);
112 gt += qGreen(rgba);
113 bt += qBlue(rgba);
114 at += qAlpha(rgba);
115 }
116 /* Set the new weighted pixel */
117 dsl[0] = qRgba(rt / b, gt / b, bt / b, at / b);
118
119 /* Now process the rest */
120 for (int x = 1; x < s.width(); ++x)
121 {
122 /* Subtract the pixel which fall out of our blur matrix */
123 int x1 = x - r - 1;
124 if (x1 >= 0)
125 {
126 --b; /* Adjust the weight (necessary for the border case) */
127 QRgb rgba = ssl[x1];
128 rt -= qRed(rgba);
129 gt -= qGreen(rgba);
130 bt -= qBlue(rgba);
131 at -= qAlpha(rgba);
132 }
133
134 /* Add the pixel which get into our blur matrix */
135 int x2 = x + r;
136 if (x2 < s.width())
137 {
138 ++b; /* Adjust the weight (necessary for the border case) */
139 QRgb rgba = ssl[x2];
140 rt += qRed(rgba);
141 gt += qGreen(rgba);
142 bt += qBlue(rgba);
143 at += qAlpha(rgba);
144 }
145 /* Set the new weighted pixel */
146 dsl[x] = qRgba(rt / b, gt / b, bt / b, at / b);
147 }
148 }
149}
150
151void blurImageVertical(const QImage &source, QImage &dest, int r)
152{
153 QSize s = source.size();
154 for (int x = 0; x < s.width(); ++x)
155 {
156 int rt = 0;
157 int gt = 0;
158 int bt = 0;
159 int at = 0;
160
161 /* First process the vertical zero line at once */
162 int b = r + 1;
163 for (int y1 = 0; y1 <= r; ++y1)
164 {
165 QRgb rgba = source.pixel(x, y1);
166 rt += qRed(rgba);
167 gt += qGreen(rgba);
168 bt += qBlue(rgba);
169 at += qAlpha(rgba);
170 }
171 /* Set the new weighted pixel */
172 dest.setPixel(x, 0, qRgba(rt / b, gt / b, bt / b, at / b));
173
174 /* Now process the rest */
175 for (int y = 1; y < s.height(); ++y)
176 {
177 /* Subtract the pixel which fall out of our blur matrix */
178 int y1 = y - r - 1;
179 if (y1 >= 0)
180 {
181 --b; /* Adjust the weight (necessary for the border case) */
182 QRgb rgba = source.pixel(x, y1);
183 rt -= qRed(rgba);
184 gt -= qGreen(rgba);
185 bt -= qBlue(rgba);
186 at -= qAlpha(rgba);
187 }
188
189 /* Add the pixel which get into our blur matrix */
190 int y2 = y + r;
191 if (y2 < s.height())
192 {
193 ++b; /* Adjust the weight (necessary for the border case) */
194 QRgb rgba = source.pixel(x, y2);
195 rt += qRed(rgba);
196 gt += qGreen(rgba);
197 bt += qBlue(rgba);
198 at += qAlpha(rgba);
199 }
200 /* Set the new weighted pixel */
201 dest.setPixel(x, y, qRgba(rt / b, gt / b, bt / b, at / b));
202 }
203 }
204}
205
206static QImage betaLabelImage(const QSize& ls)
207{
208 /* Beta label */
209 QColor bgc(246, 179, 0);
210 QImage i(ls, QImage::Format_ARGB32);
211 i.fill(Qt::transparent);
212 QPainter p(&i);
213 p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
214 p.setPen(Qt::NoPen);
215 /* Background */
216 p.setBrush(bgc);
217 p.drawRect(0, 0, ls.width(), ls.height());
218 /* The black stripes */
219 p.setPen(QPen(QColor(70, 70, 70), 5));
220 float c = ((float)ls.width() / ls.height()) + 1;
221 float g = (ls.width() / (c - 1));
222 for (int i = 0; i < c; ++i)
223 p.drawLine((int)(-g / 2 + g * i), ls.height(), (int)(-g / 2 + g * (i + 1)), 0);
224 /* The text */
225 QFont f = p.font();
226 f.setBold(true);
227 QPainterPath tp;
228 tp.addText(0, 0, f, "BETA");
229 QRectF r = tp.boundingRect();
230 /* Center the text path */
231 p.translate((ls.width() - r.width()) / 2, ls.height() - (ls.height() - r.height()) / 2);
232 QPainterPathStroker pps;
233 QPainterPath pp = pps.createStroke(tp);
234 p.setPen(QPen(bgc.darker(80), 2, Qt::SolidLine, Qt::RoundCap));
235 p.drawPath(pp);
236 p.setBrush(Qt::black);
237 p.setPen(Qt::NoPen);
238 p.drawPath(tp);
239 p.end();
240
241 /* Smoothing */
242 QImage i1(ls, QImage::Format_ARGB32);
243 i1.fill(Qt::transparent);
244 QPainter p1(&i1);
245 p1.setCompositionMode(QPainter::CompositionMode_Source);
246 p1.drawImage(0, 0, i);
247 p1.setCompositionMode(QPainter::CompositionMode_DestinationIn);
248 QLinearGradient lg(0, 0, ls.width(), 0);
249 lg.setColorAt(0, QColor(Qt::transparent));
250 lg.setColorAt(0.20, QColor(Qt::white));
251 lg.setColorAt(0.80, QColor(Qt::white));
252 lg.setColorAt(1, QColor(Qt::transparent));
253 p1.fillRect(0, 0, ls.width(), ls.height(), lg);
254 p1.end();
255
256 return i1;
257}
258
259QPixmap betaLabel(const QSize &ls /* = QSize(80, 16) */)
260{
261 return QPixmap::fromImage(betaLabelImage(ls));
262}
263
264QPixmap betaLabelSleeve(const QSize &ls /* = QSize(80, 16) */)
265{
266 const QImage &i = betaLabelImage(ls);
267 /* Create a secondary image which will contain the rotated banner. */
268 int w = (int)sqrtf(powf(ls.width(), 2) / 2);
269 QImage i1(w, w, QImage::Format_ARGB32);
270 i1.fill(Qt::transparent);
271 QPainter p1(&i1);
272 p1.setRenderHints(QPainter::SmoothPixmapTransform);
273 p1.rotate(45);
274 p1.drawImage(0, -ls.height(), i);
275 p1.end();
276
277 return QPixmap::fromImage(i1);
278}
279
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use