KQuickImageEditor

imageitem.cpp
1 
2 /*
3  * SPDX-FileCopyrightText: (C) 2011 Marco Martin <[email protected]>
4  * SPDX-FileCopyrightText: (C) 2020 Luca Beltrame <[email protected]>
5  *
6  * SPDX-License-Identifier: LGPL-2.1-or-later
7  */
8 
9 #include "imageitem.h"
10 
11 #include <QDebug>
12 #include <QPainter>
13 
14 ImageItem::ImageItem(QQuickItem *parent)
15  : QQuickPaintedItem(parent)
16  , m_smooth(false)
17  , m_fillMode(ImageItem::Stretch)
18 {
19  setFlag(ItemHasContents, true);
20 }
21 
22 void ImageItem::setImage(const QImage &image)
23 {
24  bool oldImageNull = m_image.isNull();
25  m_image = image;
26  updatePaintedRect();
27  update();
28  Q_EMIT nativeWidthChanged();
29  Q_EMIT nativeHeightChanged();
30  Q_EMIT imageChanged();
31  if (oldImageNull != m_image.isNull()) {
32  Q_EMIT nullChanged();
33  }
34 }
35 
36 QImage ImageItem::image() const
37 {
38  return m_image;
39 }
40 
41 void ImageItem::resetImage()
42 {
43  setImage(QImage());
44 }
45 
46 void ImageItem::setSmooth(const bool smooth)
47 {
48  if (smooth == m_smooth) {
49  return;
50  }
51  m_smooth = smooth;
52  update();
53 }
54 
55 bool ImageItem::smooth() const
56 {
57  return m_smooth;
58 }
59 
60 int ImageItem::nativeWidth() const
61 {
62  return m_image.size().width() / m_image.devicePixelRatio();
63 }
64 
65 int ImageItem::nativeHeight() const
66 {
67  return m_image.size().height() / m_image.devicePixelRatio();
68 }
69 
70 ImageItem::FillMode ImageItem::fillMode() const
71 {
72  return m_fillMode;
73 }
74 
75 void ImageItem::setFillMode(ImageItem::FillMode mode)
76 {
77  if (mode == m_fillMode) {
78  return;
79  }
80 
81  m_fillMode = mode;
82  updatePaintedRect();
83  update();
84  Q_EMIT fillModeChanged();
85 }
86 
87 void ImageItem::paint(QPainter *painter)
88 {
89  if (m_image.isNull()) {
90  return;
91  }
92  painter->save();
93  painter->setRenderHint(QPainter::Antialiasing, m_smooth);
95 
96  if (m_fillMode == TileVertically) {
97  painter->scale(width() / (qreal)m_image.width(), 1);
98  }
99 
100  if (m_fillMode == TileHorizontally) {
101  painter->scale(1, height() / (qreal)m_image.height());
102  }
103 
104  if (m_fillMode >= Tile) {
105  painter->drawTiledPixmap(m_paintedRect, QPixmap::fromImage(m_image));
106  } else {
107  painter->drawImage(m_paintedRect, m_image, m_image.rect());
108  }
109 
110  painter->restore();
111 }
112 
113 bool ImageItem::isNull() const
114 {
115  return m_image.isNull();
116 }
117 
118 int ImageItem::paintedWidth() const
119 {
120  if (m_image.isNull()) {
121  return 0;
122  }
123 
124  return m_paintedRect.width();
125 }
126 
127 int ImageItem::paintedHeight() const
128 {
129  if (m_image.isNull()) {
130  return 0;
131  }
132 
133  return m_paintedRect.height();
134 }
135 
136 int ImageItem::verticalPadding() const
137 {
138  if (m_image.isNull()) {
139  return 0;
140  }
141 
142  return (height() - m_paintedRect.height()) / 2;
143 }
144 
145 int ImageItem::horizontalPadding() const
146 {
147  if (m_image.isNull()) {
148  return 0;
149  }
150 
151  return (width() - m_paintedRect.width()) / 2;
152 }
153 
154 void ImageItem::updatePaintedRect()
155 {
156  if (m_image.isNull()) {
157  return;
158  }
159 
160  QRect sourceRect = m_paintedRect;
161 
162  QRect destRect;
163 
164  switch (m_fillMode) {
165  case PreserveAspectFit: {
166  QSize scaled = m_image.size();
167 
168  scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatio);
169  destRect = QRect(QPoint(0, 0), scaled);
170  destRect.moveCenter(boundingRect().center().toPoint());
171  break;
172  }
173  case PreserveAspectCrop: {
174  QSize scaled = m_image.size();
175 
176  scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatioByExpanding);
177  destRect = QRect(QPoint(0, 0), scaled);
178  destRect.moveCenter(boundingRect().center().toPoint());
179  break;
180  }
181  case TileVertically: {
182  destRect = boundingRect().toRect();
183  destRect.setWidth(destRect.width() / (width() / (qreal)m_image.width()));
184  break;
185  }
186  case TileHorizontally: {
187  destRect = boundingRect().toRect();
188  destRect.setHeight(destRect.height() / (height() / (qreal)m_image.height()));
189  break;
190  }
191  case Stretch:
192  case Tile:
193  default:
194  destRect = boundingRect().toRect();
195  }
196 
197  if (destRect != sourceRect) {
198  m_paintedRect = destRect;
199  Q_EMIT paintedHeightChanged();
200  Q_EMIT paintedWidthChanged();
201  Q_EMIT verticalPaddingChanged();
202  Q_EMIT horizontalPaddingChanged();
203  }
204 }
205 
206 void ImageItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
207 {
208  QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);
209  updatePaintedRect();
210 }
int width() const const
void setRenderHint(QPainter::RenderHint hint, bool on)
void scale(qreal sx, qreal sy)
void save()
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
void drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &position)
int height() const const
void scale(int width, int height, Qt::AspectRatioMode mode)
QImage image() const
The image was is displayed.
bool isNull() const const
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
qreal devicePixelRatio() const const
int width() const const
void setWidth(int width)
QRect rect() const const
QTextStream & center(QTextStream &stream)
void restore()
int width() const const
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
void setHeight(int height)
KeepAspectRatio
int height() const const
QSize size() const const
void update(Part *part, const QByteArray &data, qint64 dataSize)
int height() const const
void moveCenter(const QPoint &position)
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 18 2021 23:08:19 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.