KQuickImageEditor

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

KDE's Doxygen guidelines are available online.