CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
painted_image_item.cpp
Go to the documentation of this file.
1
9#include <spdlog/spdlog.h>
10#include <QPainter>
11#include <QColorSpace>
12#include <QMutexLocker>
13#include <algorithm>
14
16
18 : QQuickPaintedItem(parent)
19{
20 spdlog::debug("[PaintedImageItem:aintedImageItem]: Created");
21}
22
23// Sets the full image to be displayed.
24// Updates the internal image data and schedules a repaint.
25void PaintedImageItem::setImage(std::unique_ptr<Core::Common::ImageRegion> image)
26{
27 if (!image || !image->isValid()) {
28 spdlog::warn("[PaintedImageItem::setImage]: Invalid image");
29 return;
30 }
31
32 spdlog::info("[PaintedImageItem::setImage]: {}x{}", image->width(), image->height());
33
34 {
35 QMutexLocker lock(&m_image_mutex);
36 m_full_image = std::move(image);
37 m_current_qimage = convertImageRegionToQImage(*m_full_image);
38 }
39
41}
42
43void PaintedImageItem::updateTile(std::unique_ptr<Core::Common::ImageRegion> tile)
44{
45 if (!tile || !tile->isValid()) {
46 spdlog::warn("[PaintedImageItem::updateTile]: Invalid tile");
47 return;
48 }
49
50 const int tile_w { static_cast<int>(tile->width()) };
51 const int tile_h { static_cast<int>(tile->height()) };
52
53 {
54 QMutexLocker lock(&m_image_mutex);
55
56 // ALWAYS full replacement - we receive the complete downsampled image
57 // The name "updateTile" is misleading; it's always the full display image
58 m_full_image = std::move(tile);
59 m_current_qimage = convertImageRegionToQImage(*m_full_image);
60 }
61
62 spdlog::debug("[PaintedImageItem::updateTile]: Replaced with {}x{}", tile_w, tile_h);
63
64 // Thread-safe update - must be called from GUI thread
65 QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
66}
67
68// Paints the image using QPainter.
69void PaintedImageItem::paint(QPainter* painter)
70{
71 if (!painter || !isImagePaintValid()) {
72 return;
73 }
74
75 QMutexLocker lock(&m_image_mutex);
76
77 painter->save();
78 painter->translate(m_pan);
79 painter->scale(m_zoom, m_zoom);
80 painter->drawImage(QPointF(0, 0), m_current_qimage);
81 painter->restore();
82}
83
84// Converts an ImageRegion to a QImage.
85QImage PaintedImageItem::convertImageRegionToQImage(const Core::Common::ImageRegion& region) const
86{
87 if (!region.isValid()) {
88 spdlog::error("[PaintedImageItem::convertImageRegionToQImage]: Invalid region");
89 return QImage();
90 }
91
92 const int w { static_cast<int>(region.width()) };
93 const int h { static_cast<int>(region.height()) };
94
95 QImage linear_img(
96 reinterpret_cast<const uchar*>(region.m_data.data()),
97 w, h,
98 w * 4 * static_cast<int>(sizeof(float)),
99 QImage::Format_RGBA32FPx4
100 );
101 linear_img.setColorSpace(QColorSpace(QColorSpace::SRgbLinear));
102
103 return linear_img.convertedToColorSpace(QColorSpace(QColorSpace::SRgb))
104 .convertToFormat(QImage::Format_RGBA8888);
105}
106
107bool PaintedImageItem::isImagePaintValid() const
108{
109 QMutexLocker lock(&m_image_mutex);
110 return m_full_image && m_full_image->isValid() && !m_current_qimage.isNull();
111}
112
113
115{
116 emit zoomChanged(new_zoom);
117 update();
118}
119
120void PaintedImageItem::onPanChanged(const QPointF& new_pan)
121{
122 emit panChanged(new_pan);
123 update();
124}
125
127{
128 emit imageSizeChanged();
129 update();
130}
131} // namespace CaptureMoment::UI::Rendering
std::unique_ptr< Core::Common::ImageRegion > m_full_image
Unique pointer to the full image data displayed by this item.
QMutex m_image_mutex
Mutex protecting access to m_full_image and related state. Ensures thread-safe updates to the image d...
QPointF m_pan
Current pan offset applied to the image.
float m_zoom
Current zoom level applied to the image.
void paint(QPainter *painter) override
Paints the image using QPainter.
void onPanChanged(const QPointF &new_pan) override
void setImage(std::unique_ptr< Core::Common::ImageRegion > image) override
Sets the full image to be displayed.
void updateTile(std::unique_ptr< Core::Common::ImageRegion > tile) override
Updates a specific tile of the displayed image.
void imageSizeChanged()
Signal emitted when the image dimensions change (width or height).
void panChanged(const QPointF &pan)
Signal emitted when the pan offset changes.
PaintedImageItem(QQuickItem *parent=nullptr)
Constructs a new PaintedImageItem.
void zoomChanged(float zoom)
Signal emitted when the zoom value changes.
Namespace containing Qt-specific UI components for CaptureMoment.
Simple image display using QQuickPaintedItem and QPainter (Qt 6)
Represents a rectangular region of an image and its pixel data.
constexpr ImageDim height() const noexcept
constexpr ImageDim width() const noexcept
std::vector< float > m_data
Pixel data (row-major layout).
constexpr bool isValid() const noexcept
Validates the integrity of the ImageRegion (Overflow-Safe Version).
CaptureMoment — footer