TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
imagewrapper.cpp
Go to the documentation of this file.
1 #include "imagewrapper.h"
2 #include "random.h"
3 
4 #include <qmath.h>
5 #include <QPainter>
6 
7 namespace QAlgorithm
8 {
12 class SharpeImagePrivate : public TTKPrivate<SharpeImage>
13 {
14 public:
17 
18  QRect m_rectangle;
19 };
20 
22 {
23 
24 }
25 
27 {
28 
29 }
30 
31 
34 {
35 
36 }
37 
39 {
40  TTK_INIT_PRIVATE_D(pvt);
41 }
42 
43 void SharpeImage::input(const QRect &region)
44 {
46  d->m_rectangle = region;
47 }
48 
51  : SharpeImage()
52 {
53 
54 }
55 
56 QPixmap GaussBlur::render(const QPixmap &pixmap, int value)
57 {
59  QImage image = pixmap.copy(d->m_rectangle).toImage();
60 
61  const float sigma = 1.0 * value / 2.57;
62  const float deno = 1.0 / (sigma * sqrt(2.0 * M_PI));
63  const float nume = -1.0 / (2.0 * sigma * sigma);
64 
65  float* gaussMatrix = (float*)malloc(sizeof(float)* (value + value + 1));
66  float gaussSum = 0.0;
67  for(int i = 0, x = -value; x <= value; ++x, ++i)
68  {
69  float g = deno * exp(1.0 * nume * x * x);
70 
71  gaussMatrix[i] = g;
72  gaussSum += g;
73  }
74 
75  const int len = value + value + 1;
76  for(int i = 0; i < len; ++i)
77  {
78  gaussMatrix[i] /= gaussSum;
79  }
80 
81  const int width = image.width();
82  const int height = image.height();
83  int *pix = (int*)image.bits();
84  int *rowData = (int*)malloc(width * sizeof(int));
85  int *listData = (int*)malloc(height * sizeof(int));
86 
87  for(int y = 0; y < height; ++y)
88  {
89  memcpy(rowData, pix + y * width, sizeof(int) *width);
90 
91  for(int x = 0; x < width; ++x)
92  {
93  float r = 0, g = 0, b = 0;
94  gaussSum = 0;
95 
96  for(int i = -value; i <= value; ++i)
97  {
98  int k = x + i;
99 
100  if(0 <= k && k <= width)
101  {
102  int color = rowData[k];
103  int cr = (color & 0x00ff0000) >> 16;
104  int cg = (color & 0x0000ff00) >> 8;
105  int cb = (color & 0x000000ff);
106 
107  r += cr * gaussMatrix[i + value];
108  g += cg * gaussMatrix[i + value];
109  b += cb * gaussMatrix[i + value];
110 
111  gaussSum += gaussMatrix[i + value];
112  }
113  }
114 
115  int cr = (int)(r / gaussSum);
116  int cg = (int)(g / gaussSum);
117  int cb = (int)(b / gaussSum);
118 
119  pix[y * width + x] = cr << 16 | cg << 8 | cb | 0xff000000;
120  }
121  }
122 
123  for(int x = 0; x < width; ++x)
124  {
125  for(int y = 0; y < height; ++y)
126  {
127  listData[y] = pix[y * width + x];
128  }
129 
130  for(int y = 0; y < height; ++y)
131  {
132  float r = 0, g = 0, b = 0;
133  gaussSum = 0;
134 
135  for(int j = -value; j <= value; ++j)
136  {
137  int k = y + j;
138 
139  if(0 <= k && k <= height)
140  {
141  int color = listData[k];
142  int cr = (color & 0x00ff0000) >> 16;
143  int cg = (color & 0x0000ff00) >> 8;
144  int cb = (color & 0x000000ff);
145 
146  r += cr * gaussMatrix[j + value];
147  g += cg * gaussMatrix[j + value];
148  b += cb * gaussMatrix[j + value];
149 
150  gaussSum += gaussMatrix[j + value];
151  }
152  }
153 
154  int cr = (int)(r / gaussSum);
155  int cg = (int)(g / gaussSum);
156  int cb = (int)(b / gaussSum);
157 
158  pix[y * width + x] = cr << 16 | cg << 8 | cb | 0xff000000;
159  }
160  }
161 
162  free(gaussMatrix);
163  free(rowData);
164  free(listData);
165  return QPixmap::fromImage(image);
166 }
167 
168 
170 
174 {
175 public:
176  CubeWavePrivate();
177 
178  void initialize(int width, int height);
179 
180  int count() const;
181  bool isValid(int index, int value) const;
182 
183  int m_row;
184  int m_column;
186 };
187 
189  : SharpeImagePrivate(),
190  m_row(0),
191  m_column(0)
192 {
194 }
195 
196 void CubeWavePrivate::initialize(int width, int height)
197 {
198  m_column = ceil(width * 1.0 / 8);
199  m_row = ceil(height * 1.0 / 8);
200 }
201 
202 bool CubeWavePrivate::isValid(int index, int value) const
203 {
204  if(index < 0 || index > m_data.count())
205  {
206  return false;
207  }
208 
209  return m_data[index] > value;
210 }
211 
213 {
214  return 8 * 8;
215 }
216 
217 
220 {
221 
222 }
223 
224 void CubeWave::input(const QRect &region)
225 {
226  SharpeImage::input(region);
227 
228  TTK_D(CubeWave);
229  d->initialize(region.width(), region.height());
230  for(int index = 0; index < d->count(); ++index)
231  {
232  d->m_data.push_back(QAlgorithm::random(100));
233  }
234 }
235 
236 QPixmap CubeWave::render(const QPixmap &pixmap, int value)
237 {
238  TTK_D(CubeWave);
239  QPixmap pix(d->m_rectangle.size());
240 
241  pix.fill(Qt::transparent);
242  for(int index = 0; index < d->count(); ++index)
243  {
244  QPainter painter(&pix);
245 
246  const int row = index / 8;
247  const int column = index % 8;
248 
249  QRect rect(QRect(row * d->m_column, column * d->m_row, d->m_column, d->m_row));
250  if(rect.y() + rect.height() > pixmap.height())
251  {
252  rect.setHeight(pixmap.height() - rect.y());
253  }
254 
255  if(d->isValid(index, value))
256  {
257  painter.fillRect(rect, QColor(0xFF, 0xFF, 0xFF, 255 - 2.55 * value));
258  }
259 
260  painter.setCompositionMode(QPainter::CompositionMode_SourceOut);
261  painter.drawPixmap(rect, pixmap.copy(rect));
262  }
263 
264  return pix;
265 }
266 
267 
269 
273 {
274 public:
277 
278  int* data();
279  void render();
280  void initialize(const QImage &image, int radius);
281 
282  void setWaveSourcePower(int radius, int depth);
283  void setWaveSourcePosition(int x, int y);
284 
285 private:
286  void spreedRipple();
287  void renderRipple();
288 
289 private:
292  short *m_buffer1;
293  short *m_buffer2;
296 
297  int m_width;
298  int m_height;
299 
301  float m_scale;
302 
305 };
306 
309 {
310 
311 }
312 
314 {
315  if(m_orginPixels)
316  {
317  delete[] m_orginPixels;
318  }
319 
320  if(m_newPixels)
321  {
322  delete[] m_newPixels;
323  }
324 
325  if(m_buffer1)
326  {
327  delete[] m_buffer1;
328  }
329 
330  if(m_buffer2)
331  {
332  delete[] m_buffer2;
333  }
334 
335  if(m_sourcePower)
336  {
337  delete[] m_sourcePower;
338  }
339 
340  if(m_sourcePosition)
341  {
342  delete[] m_sourcePosition;
343  }
344 }
345 
347 {
348  return m_newPixels;
349 }
350 
352 {
353  spreedRipple();
354  renderRipple();
355 }
356 
357 void WaterWavePrivate::initialize(const QImage &image, int radius)
358 {
359  m_orginPixels = nullptr;
360  m_newPixels = nullptr;
361  m_buffer1 = nullptr;
362  m_buffer2 = nullptr;
363  m_sourcePower = nullptr;
364  m_sourcePosition = nullptr;
365 
366  m_width = image.width();
367  m_height = image.height();
368 
369  m_orginPixels = new int[m_width * m_height]{};
370  memcpy(m_orginPixels, image.bits(), m_width * m_height * 4);
371 
372  m_newPixels = new int[m_width * m_height]{};
373  memcpy(m_newPixels, image.bits(), m_width * m_height * sizeof(int));
374 
375  m_buffer1 = new short[m_width * m_height]{};
376  m_buffer2 = new short[m_width * m_height]{};
377 
378  m_powerRate = 2;
379  m_scale = 1;
380 
381  setWaveSourcePower(radius, 100);
382 }
383 
384 void WaterWavePrivate::setWaveSourcePower(int radius, int depth)
385 {
386  m_sourceRadius = TTKStaticCast(int, radius / m_scale);
387  m_sourceDepth = depth;
388 
389  const int value = m_sourceRadius * m_sourceRadius;
390  const int diameter = (m_sourceRadius << 1) + 1;
391  const int rate = m_sourceRadius / value;
392  const int size = diameter * diameter;
393 
394  m_sourcePower = new int[size]{};
395  m_sourcePosition = new int[size]{};
396 
397  for(int x = 0; x <= diameter; ++x)
398  {
399  for(int y = 0; y <= diameter; ++y)
400  {
401  const int distanceSquare = (m_sourceRadius - x) * (m_sourceRadius - x) + (m_sourceRadius - y) * (m_sourceRadius - y);
402  if(distanceSquare <= value)
403  {
404  const int depth = m_sourceDepth - distanceSquare * rate;
405  m_sourcePosition[y * diameter + x] = y * m_width + x;
406  m_sourcePower[y * diameter + x] = depth;
407  }
408  }
409  }
410 }
411 
413 {
414  const int sourceX = TTKStaticCast(int, x / m_scale);
415  const int sourceY = TTKStaticCast(int, y / m_scale);
416  if((sourceX + m_sourceRadius) >= m_width || (sourceY + m_sourceRadius) >= m_height || (sourceX - m_sourceRadius) <= 0 || (sourceY - m_sourceRadius) <= 0)
417  {
418  return;
419  }
420 
421  const int distance = (sourceY - m_sourceRadius) * m_width + sourceX - m_sourceRadius;
422  const int size = ((m_sourceRadius << 1) + 1) * ((m_sourceRadius << 1) + 1);
423  for(int i = 0; i < size; ++i)
424  {
425  m_buffer1[distance + m_sourcePosition[i]] = TTKStaticCast(short, m_sourcePower[i]);
426  }
427 }
428 
430 {
431  const int length = m_width * (m_height - 1);
432  for(int i = m_width; i < length; ++i)
433  {
434  m_buffer2[i] = ((m_buffer1[i - 1] + m_buffer1[i - m_width] + m_buffer1[i + 1] + m_buffer1[i + m_width]) >> 1) - m_buffer2[i];
435  m_buffer2[i] -= m_buffer2[i] >> m_powerRate;
436  }
437 
438  short* temp = m_buffer1;
440  m_buffer2 = temp;
441 }
442 
444 {
445  int offset;
446  int w = m_width;
447  for(int y = 1; y < m_height - 1; ++y)
448  {
449  for(int x = 0; x < m_width; ++x, ++w)
450  {
451  offset = (m_width * (m_buffer1[w - m_width] - m_buffer1[w + m_width])) + (m_buffer1[w - 1] - m_buffer1[w + 1]);
452  if(w + offset > 0 && w + offset < m_width * m_height)
453  {
454  m_newPixels[w] = m_orginPixels[w + offset];
455  }
456  else
457  {
458  m_newPixels[w] = m_orginPixels[w];
459  }
460  }
461  }
462 }
463 
464 
465 WaterWave::WaterWave(const QImage &image, int radius)
467 {
468  TTK_D(WaterWave);
469  d->initialize(image, radius);
470 }
471 
472 void WaterWave::input(const QRect &region)
473 {
474  SharpeImage::input(region);
475 
476  TTK_D(WaterWave);
477  d->setWaveSourcePosition(region.width() / 2, region.height() / 2);
478 }
479 
480 QPixmap WaterWave::render(const QPixmap &pixmap, int value)
481 {
482  TTK_D(WaterWave);
483  d->render();
484 
485  QImage image = pixmap.toImage();
486  memcpy(image.bits(), (const uchar*)d->data(), QtImageBytes(image));
487 
488  QPixmap pix(d->m_rectangle.size());
489  pix.fill(Qt::transparent);
490 
491  QPainter painter(&pix);
492  painter.fillRect(d->m_rectangle, QColor(0xFF, 0xFF, 0xFF, qMin(2.55 * 2 * value, 255.0)));
493  painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
494  painter.drawPixmap(d->m_rectangle, QPixmap::fromImage(image));
495  return pix;
496 }
497 }
#define TTKStaticCast(x, y)
Definition: ttkglobal.h:159
#define QtImageBytes(p)
Image byte count.
Definition: ttkqtcompat.h:38
The class of the sharpe image.
Definition: imagewrapper.h:35
The class of the water wave.
Definition: imagewrapper.h:111
void initRandom()
Definition: random.cpp:10
WaterWave(const QImage &image, int radius)
The class of the water wave private.
voidpf void uLong size
Definition: ioapi.h:136
virtual void input(const QRect &region)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
virtual QPixmap render(const QPixmap &pixmap, int value) overridefinal
The namespace of the algorithm.
int random(int value)
Definition: random.cpp:17
void initialize(const QImage &image, int radius)
voidpf uLong offset
Definition: ioapi.h:142
QList< int > TTKIntList
Definition: ttkqtglobal.h:188
#define TTK_INIT_PRIVATE_D(PVT)
Definition: ttkprivate.h:37
void setWaveSourcePower(int radius, int depth)
virtual QPixmap render(const QPixmap &pixmap, int value) overridefinal
#define TTK_CREATE_PRIVATE(Class)
Definition: ttkprivate.h:24
The class of the sharpe image private.
virtual void input(const QRect &region) overridefinal
virtual QPixmap render(const QPixmap &pixmap, int value) overridefinal
The class of the cube wave.
Definition: imagewrapper.h:88
void free(voidpf ptr)
void setWaveSourcePosition(int x, int y)
virtual void input(const QRect &region) overridefinal
The class of the ttk private base.
Definition: ttkprivate.h:48
voidp malloc(uInt size)
void initialize(int width, int height)
bool isValid(int index, int value) const
The class of the cube wave private.
#define TTK_D(Class)
Definition: ttkprivate.h:41