1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <qglobal.h>
5
6#include "qpixmap.h"
7#include <qpa/qplatformpixmap.h>
8#include "qimagepixmapcleanuphooks_p.h"
9
10#include "qbitmap.h"
11#include "qimage.h"
12#include "qpainter.h"
13#include "qdatastream.h"
14#include "qbuffer.h"
15#include <private/qguiapplication_p.h>
16#include "qevent.h"
17#include "qfile.h"
18#include "qfileinfo.h"
19#include "qpixmapcache.h"
20#include "qdatetime.h"
21#include "qimagereader.h"
22#include "qimagewriter.h"
23#include "qpaintengine.h"
24#include "qscreen.h"
25#include "qthread.h"
26#include "qdebug.h"
27
28#include <qpa/qplatformintegration.h>
29
30#include "qpixmap_raster_p.h"
31#include "private/qhexstring_p.h"
32
33#include <qtgui_tracepoints_p.h>
34
35#include <memory>
36
37QT_BEGIN_NAMESPACE
38
39using namespace Qt::StringLiterals;
40
41Q_TRACE_PARAM_REPLACE(Qt::AspectRatioMode, int);
42Q_TRACE_PARAM_REPLACE(Qt::TransformationMode, int);
43
44// MSVC 19.28 does show spurious warning "C4723: potential divide by 0" for code that divides
45// by height() in release builds. Anyhow, all the code paths in this file are only executed
46// for valid QPixmap's, where height() cannot be 0. Therefore disable the warning.
47QT_WARNING_DISABLE_MSVC(4723)
48
49static bool qt_pixmap_thread_test()
50{
51 if (Q_UNLIKELY(!QCoreApplication::instance())) {
52 qFatal(msg: "QPixmap: Must construct a QGuiApplication before a QPixmap");
53 return false;
54 }
55 if (QGuiApplicationPrivate::instance()
56 && !QThread::isMainThread()
57 && !QGuiApplicationPrivate::platformIntegration()->hasCapability(cap: QPlatformIntegration::ThreadedPixmaps)) {
58 qWarning(msg: "QPixmap: It is not safe to use pixmaps outside the GUI thread on this platform");
59 return false;
60 }
61 return true;
62}
63
64void QPixmap::doInit(int w, int h, int type)
65{
66 if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType)
67 data = QPlatformPixmap::create(w, h, type: (QPlatformPixmap::PixelType) type);
68 else
69 data = nullptr;
70}
71
72/*!
73 Constructs a null pixmap.
74
75 \sa isNull()
76*/
77
78QPixmap::QPixmap()
79 : QPaintDevice()
80{
81 (void) qt_pixmap_thread_test();
82 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
83}
84
85/*!
86 \fn QPixmap::QPixmap(int width, int height)
87
88 Constructs a pixmap with the given \a width and \a height. If
89 either \a width or \a height is zero, a null pixmap is
90 constructed.
91
92 \warning This will create a QPixmap with uninitialized data. Call
93 fill() to fill the pixmap with an appropriate color before drawing
94 onto it with QPainter.
95
96 \sa isNull()
97*/
98
99QPixmap::QPixmap(int w, int h)
100 : QPixmap(QSize(w, h))
101{
102}
103
104/*!
105 \overload
106
107 Constructs a pixmap of the given \a size.
108
109 \warning This will create a QPixmap with uninitialized data. Call
110 fill() to fill the pixmap with an appropriate color before drawing
111 onto it with QPainter.
112*/
113
114QPixmap::QPixmap(const QSize &size)
115 : QPixmap(size, QPlatformPixmap::PixmapType)
116{
117}
118
119/*!
120 \internal
121*/
122QPixmap::QPixmap(const QSize &s, int type)
123{
124 if (!qt_pixmap_thread_test())
125 doInit(w: 0, h: 0, type: static_cast<QPlatformPixmap::PixelType>(type));
126 else
127 doInit(w: s.width(), h: s.height(), type: static_cast<QPlatformPixmap::PixelType>(type));
128}
129
130/*!
131 \internal
132*/
133QPixmap::QPixmap(QPlatformPixmap *d)
134 : QPaintDevice(), data(d)
135{
136}
137
138/*!
139 Constructs a pixmap from the file with the given \a fileName. If the
140 file does not exist or is of an unknown format, the pixmap becomes a
141 null pixmap.
142
143 The loader attempts to read the pixmap using the specified \a
144 format. If the \a format is not specified (which is the default),
145 the loader probes the file for a header to guess the file format.
146
147 The file name can either refer to an actual file on disk or to
148 one of the application's embedded resources. See the
149 \l{resources.html}{Resource System} overview for details on how
150 to embed images and other resource files in the application's
151 executable.
152
153 If the image needs to be modified to fit in a lower-resolution
154 result (e.g. converting from 32-bit to 8-bit), use the \a
155 flags to control the conversion.
156
157 The \a fileName, \a format and \a flags parameters are
158 passed on to load(). This means that the data in \a fileName is
159 not compiled into the binary. If \a fileName contains a relative
160 path (e.g. the filename only) the relevant file must be found
161 relative to the runtime working directory.
162
163 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
164 Image Files}
165*/
166
167QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
168 : QPaintDevice()
169{
170 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
171 if (!qt_pixmap_thread_test())
172 return;
173
174 load(fileName, format, flags);
175}
176
177/*!
178 Constructs a pixmap that is a copy of the given \a pixmap.
179
180 \sa copy()
181*/
182
183QPixmap::QPixmap(const QPixmap &pixmap)
184 : QPaintDevice()
185{
186 if (!qt_pixmap_thread_test()) {
187 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
188 return;
189 }
190 if (pixmap.paintingActive()) { // make a deep copy
191 pixmap.copy().swap(other&: *this);
192 } else {
193 data = pixmap.data;
194 }
195}
196
197/*! \fn QPixmap::QPixmap(QPixmap &&other)
198 Move-constructs a QPixmap instance from \a other.
199
200 \sa swap() operator=(QPixmap&&)
201*/
202
203QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QPlatformPixmap)
204
205/*!
206 Constructs a pixmap from the given \a xpm data, which must be a
207 valid XPM image.
208
209 Errors are silently ignored.
210
211 Note that it's possible to squeeze the XPM variable a little bit
212 by using an unusual declaration:
213
214 \snippet code/src_gui_image_qimage.cpp 2
215
216 The extra \c const makes the entire definition read-only, which is
217 slightly more efficient (for example, when the code is in a shared
218 library) and ROMable when the application is to be stored in ROM.
219*/
220#ifndef QT_NO_IMAGEFORMAT_XPM
221QPixmap::QPixmap(const char * const xpm[])
222 : QPaintDevice()
223{
224 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
225 if (!xpm)
226 return;
227
228 QImage image(xpm);
229 if (!image.isNull()) {
230 if (data && data->pixelType() == QPlatformPixmap::BitmapType)
231 *this = QBitmap::fromImage(image: std::move(image));
232 else
233 *this = fromImage(image: std::move(image));
234 }
235}
236#endif
237
238
239/*!
240 Destroys the pixmap.
241*/
242
243QPixmap::~QPixmap()
244{
245 Q_ASSERT(!data || data->ref.loadRelaxed() >= 1); // Catch if ref-counting changes again
246}
247
248/*!
249 \internal
250*/
251int QPixmap::devType() const
252{
253 return QInternal::Pixmap;
254}
255
256/*!
257 \fn QPixmap QPixmap::copy(int x, int y, int width, int height) const
258 \overload
259
260 Returns a deep copy of the subset of the pixmap that is specified
261 by the rectangle QRect( \a x, \a y, \a width, \a height).
262*/
263
264/*!
265 \fn QPixmap QPixmap::copy(const QRect &rectangle) const
266
267 Returns a deep copy of the subset of the pixmap that is specified
268 by the given \a rectangle. For more information on deep copies,
269 see the \l {Implicit Data Sharing} documentation.
270
271 If the given \a rectangle is empty, the whole image is copied.
272
273 \sa operator=(), QPixmap(), {QPixmap#Pixmap
274 Transformations}{Pixmap Transformations}
275*/
276QPixmap QPixmap::copy(const QRect &rect) const
277{
278 if (isNull())
279 return QPixmap();
280
281 QRect r(0, 0, width(), height());
282 if (!rect.isEmpty())
283 r = r.intersected(other: rect);
284
285 QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
286 d->copy(data: data.data(), rect: r);
287 return QPixmap(d);
288}
289
290/*!
291 \fn QPixmap::scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed)
292
293 This convenience function is equivalent to calling QPixmap::scroll(\a dx,
294 \a dy, QRect(\a x, \a y, \a width, \a height), \a exposed).
295
296 \sa QWidget::scroll(), QGraphicsItem::scroll()
297*/
298
299/*!
300 Scrolls the area \a rect of this pixmap by (\a dx, \a dy). The exposed
301 region is left unchanged. You can optionally pass a pointer to an empty
302 QRegion to get the region that is \a exposed by the scroll operation.
303
304 \snippet code/src_gui_image_qpixmap.cpp 2
305
306 You cannot scroll while there is an active painter on the pixmap.
307
308 \sa QWidget::scroll(), QGraphicsItem::scroll()
309*/
310void QPixmap::scroll(int dx, int dy, const QRect &rect, QRegion *exposed)
311{
312 if (isNull() || (dx == 0 && dy == 0))
313 return;
314 QRect dest = rect & this->rect();
315 QRect src = dest.translated(dx: -dx, dy: -dy) & dest;
316 if (src.isEmpty()) {
317 if (exposed)
318 *exposed += dest;
319 return;
320 }
321
322 detach();
323
324 if (!data->scroll(dx, dy, rect: src)) {
325 // Fallback
326 QPixmap pix = *this;
327 QPainter painter(&pix);
328 painter.setCompositionMode(QPainter::CompositionMode_Source);
329 painter.drawPixmap(targetRect: src.translated(dx, dy), pixmap: *this, sourceRect: src);
330 painter.end();
331 *this = pix;
332 }
333
334 if (exposed) {
335 *exposed += dest;
336 *exposed -= src.translated(dx, dy);
337 }
338}
339
340/*!
341 Assigns the given \a pixmap to this pixmap and returns a reference
342 to this pixmap.
343
344 \sa copy(), QPixmap()
345*/
346
347QPixmap &QPixmap::operator=(const QPixmap &pixmap)
348{
349 if (paintingActive()) {
350 qWarning(msg: "QPixmap::operator=: Cannot assign to pixmap during painting");
351 return *this;
352 }
353 if (pixmap.paintingActive()) { // make a deep copy
354 pixmap.copy().swap(other&: *this);
355 } else {
356 data = pixmap.data;
357 }
358 return *this;
359}
360
361/*!
362 \fn QPixmap &QPixmap::operator=(QPixmap &&other)
363
364 Move-assigns \a other to this QPixmap instance.
365
366 \since 5.2
367*/
368
369/*!
370 \fn void QPixmap::swap(QPixmap &other)
371 \memberswap{pixmap}
372*/
373
374/*!
375 Returns the pixmap as a QVariant.
376*/
377QPixmap::operator QVariant() const
378{
379 return QVariant::fromValue(value: *this);
380}
381
382/*!
383 \fn bool QPixmap::operator!() const
384
385 Returns \c true if this is a null pixmap; otherwise returns \c false.
386
387 \sa isNull()
388*/
389
390/*!
391 Converts the pixmap to a QImage. Returns a null image if the
392 conversion fails.
393
394 If the pixmap has 1-bit depth, the returned image will also be 1
395 bit deep. Images with more bits will be returned in a format
396 closely represents the underlying system. Usually this will be
397 QImage::Format_ARGB32_Premultiplied for pixmaps with an alpha and
398 QImage::Format_RGB32 or QImage::Format_RGB16 for pixmaps without
399 alpha.
400
401 Note that for the moment, alpha masks on monochrome images are
402 ignored.
403
404 \sa fromImage(), {QImage#Image Formats}{Image Formats}
405*/
406QImage QPixmap::toImage() const
407{
408 if (isNull())
409 return QImage();
410
411 return data->toImage();
412}
413
414/*!
415 \fn QTransform QPixmap::trueMatrix(const QTransform &matrix, int width, int height)
416
417 Returns the actual matrix used for transforming a pixmap with the
418 given \a width, \a height and \a matrix.
419
420 When transforming a pixmap using the transformed() function, the
421 transformation matrix is internally adjusted to compensate for
422 unwanted translation, i.e. transformed() returns the smallest
423 pixmap containing all transformed points of the original
424 pixmap. This function returns the modified matrix, which maps
425 points correctly from the original pixmap into the new pixmap.
426
427 \sa transformed(), {QPixmap#Pixmap Transformations}{Pixmap
428 Transformations}
429*/
430QTransform QPixmap::trueMatrix(const QTransform &m, int w, int h)
431{
432 return QImage::trueMatrix(m, w, h);
433}
434
435/*!
436 \fn bool QPixmap::isQBitmap() const
437
438 Returns \c true if this is a QBitmap; otherwise returns \c false.
439*/
440
441bool QPixmap::isQBitmap() const
442{
443 return data && data->type == QPlatformPixmap::BitmapType;
444}
445
446/*!
447 \fn bool QPixmap::isNull() const
448
449 Returns \c true if this is a null pixmap; otherwise returns \c false.
450
451 A null pixmap has zero width, zero height and no contents. You
452 cannot draw in a null pixmap.
453*/
454bool QPixmap::isNull() const
455{
456 return !data || data->isNull();
457}
458
459/*!
460 \fn int QPixmap::width() const
461
462 Returns the width of the pixmap.
463
464 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
465*/
466int QPixmap::width() const
467{
468 return data ? data->width() : 0;
469}
470
471/*!
472 \fn int QPixmap::height() const
473
474 Returns the height of the pixmap.
475
476 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
477*/
478int QPixmap::height() const
479{
480 return data ? data->height() : 0;
481}
482
483/*!
484 \fn QSize QPixmap::size() const
485
486 Returns the size of the pixmap.
487
488 \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
489 Information}
490*/
491QSize QPixmap::size() const
492{
493 return data ? QSize(data->width(), data->height()) : QSize(0, 0);
494}
495
496/*!
497 \fn QRect QPixmap::rect() const
498
499 Returns the pixmap's enclosing rectangle.
500
501 \sa {QPixmap#Pixmap Information}{Pixmap Information}
502*/
503QRect QPixmap::rect() const
504{
505 return data ? QRect(0, 0, data->width(), data->height()) : QRect();
506}
507
508/*!
509 \fn int QPixmap::depth() const
510
511 Returns the depth of the pixmap.
512
513 The pixmap depth is also called bits per pixel (bpp) or bit planes
514 of a pixmap. A null pixmap has depth 0.
515
516 \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
517 Information}
518*/
519int QPixmap::depth() const
520{
521 return data ? data->depth() : 0;
522}
523
524/*!
525 Sets a mask bitmap.
526
527 This function merges the \a mask with the pixmap's alpha channel. A pixel
528 value of 1 on the mask means the pixmap's pixel is unchanged; a value of 0
529 means the pixel is transparent. The mask must have the same size as this
530 pixmap.
531
532 Setting a null mask resets the mask, leaving the previously transparent
533 pixels black. The effect of this function is undefined when the pixmap is
534 being painted on.
535
536 \warning This is potentially an expensive operation.
537
538 \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
539 QBitmap
540*/
541void QPixmap::setMask(const QBitmap &mask)
542{
543 if (paintingActive()) {
544 qWarning(msg: "QPixmap::setMask: Cannot set mask while pixmap is being painted on");
545 return;
546 }
547
548 if (!mask.isNull() && mask.size() != size()) {
549 qWarning(msg: "QPixmap::setMask() mask size differs from pixmap size");
550 return;
551 }
552
553 if (isNull())
554 return;
555
556 if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
557 return;
558
559 detach();
560 data->setMask(mask);
561}
562
563/*!
564 Returns the device pixel ratio for the pixmap. This is the
565 ratio between \e{device pixels} and \e{device independent pixels}.
566
567 Use this function when calculating layout geometry based on
568 the pixmap size: QSize layoutSize = image.size() / image.devicePixelRatio()
569
570 The default value is 1.0.
571
572 \sa setDevicePixelRatio(), QImageReader
573*/
574qreal QPixmap::devicePixelRatio() const
575{
576 if (!data)
577 return qreal(1.0);
578 return data->devicePixelRatio();
579}
580
581/*!
582 Sets the device pixel ratio for the pixmap. This is the
583 ratio between image pixels and device-independent pixels.
584
585 The default \a scaleFactor is 1.0. Setting it to something else has
586 two effects:
587
588 QPainters that are opened on the pixmap will be scaled. For
589 example, painting on a 200x200 image if with a ratio of 2.0
590 will result in effective (device-independent) painting bounds
591 of 100x100.
592
593 Code paths in Qt that calculate layout geometry based on the
594 pixmap size will take the ratio into account:
595 QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio()
596 The net effect of this is that the pixmap is displayed as
597 high-DPI pixmap rather than a large pixmap
598 (see \l{Drawing High Resolution Versions of Pixmaps and Images}).
599
600 \sa devicePixelRatio(), deviceIndependentSize()
601*/
602void QPixmap::setDevicePixelRatio(qreal scaleFactor)
603{
604 if (isNull())
605 return;
606
607 if (scaleFactor == data->devicePixelRatio())
608 return;
609
610 detach();
611 data->setDevicePixelRatio(scaleFactor);
612}
613
614/*!
615 Returns the size of the pixmap in device independent pixels.
616
617 This value should be used when using the pixmap size in user interface
618 size calculations.
619
620 The return value is equivalent to pixmap.size() / pixmap.devicePixelRatio().
621
622 \since 6.2
623*/
624QSizeF QPixmap::deviceIndependentSize() const
625{
626 if (!data)
627 return QSizeF(0, 0);
628 return QSizeF(data->width(), data->height()) / data->devicePixelRatio();
629}
630
631#ifndef QT_NO_IMAGE_HEURISTIC_MASK
632/*!
633 Creates and returns a heuristic mask for this pixmap.
634
635 The function works by selecting a color from one of the corners
636 and then chipping away pixels of that color, starting at all the
637 edges. If \a clipTight is true (the default) the mask is just
638 large enough to cover the pixels; otherwise, the mask is larger
639 than the data pixels.
640
641 The mask may not be perfect but it should be reasonable, so you
642 can do things such as the following:
643
644 \snippet code/src_gui_image_qpixmap.cpp 1
645
646 This function is slow because it involves converting to/from a
647 QImage, and non-trivial computations.
648
649 \sa QImage::createHeuristicMask(), createMaskFromColor()
650*/
651QBitmap QPixmap::createHeuristicMask(bool clipTight) const
652{
653 QBitmap m = QBitmap::fromImage(image: toImage().createHeuristicMask(clipTight));
654 return m;
655}
656#endif
657
658/*!
659 Creates and returns a mask for this pixmap based on the given \a
660 maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the
661 maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels
662 matching the maskColor will be opaque.
663
664 This function is slow because it involves converting to/from a
665 QImage.
666
667 \sa createHeuristicMask(), QImage::createMaskFromColor()
668*/
669QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
670{
671 QImage image = toImage().convertToFormat(f: QImage::Format_ARGB32);
672 return QBitmap::fromImage(image: std::move(image).createMaskFromColor(color: maskColor.rgba(), mode));
673}
674
675/*!
676 Loads a pixmap from the file with the given \a fileName. Returns
677 true if the pixmap was successfully loaded; otherwise invalidates
678 the pixmap and returns \c false.
679
680 The loader attempts to read the pixmap using the specified \a
681 format. If the \a format is not specified (which is the default),
682 the loader probes the file for a header to guess the file format.
683
684 The file name can either refer to an actual file on disk or to one
685 of the application's embedded resources. See the
686 \l{resources.html}{Resource System} overview for details on how to
687 embed pixmaps and other resource files in the application's
688 executable.
689
690 If the data needs to be modified to fit in a lower-resolution
691 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
692 control the conversion.
693
694 Note that QPixmaps are automatically added to the QPixmapCache
695 when loaded from a file in main thread; the key used is internal
696 and cannot be acquired.
697
698 \sa loadFromData(), {QPixmap#Reading and Writing Image
699 Files}{Reading and Writing Image Files}
700*/
701
702bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
703{
704 if (!fileName.isEmpty()) {
705
706 QFileInfo info(fileName);
707 // Note: If no extension is provided, we try to match the
708 // file against known plugin extensions
709 if (info.completeSuffix().isEmpty() || info.exists()) {
710 const bool inGuiThread = qApp->thread() == QThread::currentThread();
711
712 QString key = "qt_pixmap"_L1
713 % info.absoluteFilePath()
714 % HexString<uint>(info.lastModified(tz: QTimeZone::UTC).toSecsSinceEpoch())
715 % HexString<quint64>(info.size())
716 % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
717
718 if (inGuiThread && QPixmapCache::find(key, pixmap: this))
719 return true;
720
721 data = QPlatformPixmap::create(w: 0, h: 0, type: data ? data->pixelType() : QPlatformPixmap::PixmapType);
722
723 if (data->fromFile(filename: fileName, format, flags)) {
724 if (inGuiThread)
725 QPixmapCache::insert(key, pixmap: *this);
726 return true;
727 }
728 }
729 }
730
731 if (!isNull()) {
732 if (isQBitmap())
733 *this = QBitmap();
734 else
735 data.reset();
736 }
737 return false;
738}
739
740/*!
741 \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
742
743 Loads a pixmap from the \a len first bytes of the given binary \a
744 data. Returns \c true if the pixmap was loaded successfully;
745 otherwise invalidates the pixmap and returns \c false.
746
747 The loader attempts to read the pixmap using the specified \a
748 format. If the \a format is not specified (which is the default),
749 the loader probes the file for a header to guess the file format.
750
751 If the data needs to be modified to fit in a lower-resolution
752 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
753 control the conversion.
754
755 \sa load(), {QPixmap#Reading and Writing Image Files}{Reading and
756 Writing Image Files}
757*/
758
759bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
760{
761 if (len == 0 || buf == nullptr) {
762 data.reset();
763 return false;
764 }
765
766 data = QPlatformPixmap::create(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
767
768 if (data->fromData(buffer: buf, len, format, flags))
769 return true;
770
771 data.reset();
772 return false;
773}
774
775/*!
776 \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
777
778 \overload
779
780 Loads a pixmap from the binary \a data using the specified \a
781 format and conversion \a flags.
782*/
783
784
785/*!
786 Saves the pixmap to the file with the given \a fileName using the
787 specified image file \a format and \a quality factor. Returns \c true
788 if successful; otherwise returns \c false.
789
790 The \a quality factor must be in the range [0,100] or -1. Specify
791 0 to obtain small compressed files, 100 for large uncompressed
792 files, and -1 to use the default settings.
793
794 If \a format is \nullptr, an image format will be chosen from
795 \a fileName's suffix.
796
797 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
798 Image Files}
799*/
800
801bool QPixmap::save(const QString &fileName, const char *format, int quality) const
802{
803 if (isNull())
804 return false; // nothing to save
805 QImageWriter writer(fileName, format);
806 return doImageIO(io: &writer, quality);
807}
808
809/*!
810 \overload
811
812 This function writes a QPixmap to the given \a device using the
813 specified image file \a format and \a quality factor. This can be
814 used, for example, to save a pixmap directly into a QByteArray:
815
816 \snippet image/image.cpp 1
817*/
818
819bool QPixmap::save(QIODevice* device, const char* format, int quality) const
820{
821 if (isNull())
822 return false; // nothing to save
823 QImageWriter writer(device, format);
824 return doImageIO(io: &writer, quality);
825}
826
827/*! \internal
828*/
829bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
830{
831 if (quality > 100 || quality < -1)
832 qWarning(msg: "QPixmap::save: quality out of range [-1,100]");
833 if (quality >= 0)
834 writer->setQuality(qMin(a: quality,b: 100));
835 return writer->write(image: toImage());
836}
837
838
839/*!
840 Fills the pixmap with the given \a color.
841
842 The effect of this function is undefined when the pixmap is
843 being painted on.
844
845 \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
846*/
847
848void QPixmap::fill(const QColor &color)
849{
850 if (isNull())
851 return;
852
853 // Some people are probably already calling fill while a painter is active, so to not break
854 // their programs, only print a warning and return when the fill operation could cause a crash.
855 if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) {
856 qWarning(msg: "QPixmap::fill: Cannot fill while pixmap is being painted on");
857 return;
858 }
859
860 if (data->ref.loadRelaxed() == 1) {
861 // detach() will also remove this pixmap from caches, so
862 // it has to be called even when ref == 1.
863 detach();
864 } else {
865 // Don't bother to make a copy of the data object, since
866 // it will be filled with new pixel data anyway.
867 QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
868 d->resize(width: data->width(), height: data->height());
869 d->setDevicePixelRatio(data->devicePixelRatio());
870 data = d;
871 }
872 data->fill(color);
873}
874
875/*!
876 Returns a number that identifies this QPixmap. Distinct QPixmap
877 objects can only have the same cache key if they refer to the same
878 contents.
879
880 The cacheKey() will change when the pixmap is altered.
881*/
882qint64 QPixmap::cacheKey() const
883{
884 if (isNull())
885 return 0;
886
887 Q_ASSERT(data);
888 return data->cacheKey();
889}
890
891#if 0
892static void sendResizeEvents(QWidget *target)
893{
894 QResizeEvent e(target->size(), QSize());
895 QApplication::sendEvent(target, &e);
896
897 const QObjectList children = target->children();
898 for (int i = 0; i < children.size(); ++i) {
899 QWidget *child = static_cast<QWidget*>(children.at(i));
900 if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
901 sendResizeEvents(child);
902 }
903}
904#endif
905
906
907/*****************************************************************************
908 QPixmap stream functions
909 *****************************************************************************/
910#if !defined(QT_NO_DATASTREAM)
911/*!
912 \relates QPixmap
913
914 Writes the given \a pixmap to the given \a stream as a PNG
915 image. Note that writing the stream to a file will not produce a
916 valid image file.
917
918 \sa QPixmap::save(), {Serializing Qt Data Types}
919*/
920
921QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
922{
923 return stream << pixmap.toImage();
924}
925
926/*!
927 \relates QPixmap
928
929 Reads an image from the given \a stream into the given \a pixmap.
930
931 \sa QPixmap::load(), {Serializing Qt Data Types}
932*/
933
934QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
935{
936 QImage image;
937 stream >> image;
938
939 if (image.isNull()) {
940 pixmap = QPixmap();
941 } else if (image.depth() == 1) {
942 pixmap = QBitmap::fromImage(image: std::move(image));
943 } else {
944 pixmap = QPixmap::fromImage(image: std::move(image));
945 }
946 return stream;
947}
948
949#endif // QT_NO_DATASTREAM
950
951/*!
952 \internal
953*/
954
955bool QPixmap::isDetached() const
956{
957 return data && data->ref.loadRelaxed() == 1;
958}
959
960/*!
961 Replaces this pixmap's data with the given \a image using the
962 specified \a flags to control the conversion. The \a flags
963 argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
964 Passing 0 for \a flags sets all the default options. Returns \c true
965 if the result is that this pixmap is not null.
966
967 \sa fromImage()
968*/
969bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
970{
971 detach();
972 if (image.isNull() || !data)
973 *this = QPixmap::fromImage(image, flags);
974 else
975 data->fromImage(image, flags);
976 return !isNull();
977}
978
979/*!
980 \fn QPixmap QPixmap::scaled(int width, int height,
981 Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode
982 transformMode) const
983
984 \overload
985
986 Returns a copy of the pixmap scaled to a rectangle with the given
987 \a width and \a height according to the given \a aspectRatioMode and
988 \a transformMode.
989
990 If either the \a width or the \a height is zero or negative, this
991 function returns a null pixmap.
992*/
993
994/*!
995 \fn QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode
996 aspectRatioMode, Qt::TransformationMode transformMode) const
997
998 Scales the pixmap to the given \a size, using the aspect ratio and
999 transformation modes specified by \a aspectRatioMode and \a
1000 transformMode.
1001
1002 \image qimage-scaling.png
1003
1004 \list
1005 \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
1006 is scaled to \a size.
1007 \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
1008 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
1009 \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
1010 the pixmap is scaled to a rectangle as small as possible
1011 outside \a size, preserving the aspect ratio.
1012 \endlist
1013
1014 If the given \a size is empty, this function returns a null
1015 pixmap.
1016
1017
1018 In some cases it can be more beneficial to draw the pixmap to a
1019 painter with a scale set rather than scaling the pixmap. This is
1020 the case when the painter is for instance based on OpenGL or when
1021 the scale factor changes rapidly.
1022
1023 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1024 Transformations}
1025
1026*/
1027QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
1028{
1029 if (isNull()) {
1030 qWarning(msg: "QPixmap::scaled: Pixmap is a null pixmap");
1031 return QPixmap();
1032 }
1033 if (s.isEmpty())
1034 return QPixmap();
1035
1036 QSize newSize = size();
1037 newSize.scale(s, mode: aspectMode);
1038 newSize.rwidth() = qMax(a: newSize.width(), b: 1);
1039 newSize.rheight() = qMax(a: newSize.height(), b: 1);
1040 if (newSize == size())
1041 return *this;
1042
1043 Q_TRACE_SCOPE(QPixmap_scaled, s, aspectMode, mode);
1044
1045 QTransform wm = QTransform::fromScale(dx: (qreal)newSize.width() / width(),
1046 dy: (qreal)newSize.height() / height());
1047 QPixmap pix = transformed(wm, mode);
1048 return pix;
1049}
1050
1051/*!
1052 \fn QPixmap QPixmap::scaledToWidth(int width, Qt::TransformationMode
1053 mode) const
1054
1055 Returns a scaled copy of the image. The returned image is scaled
1056 to the given \a width using the specified transformation \a mode.
1057 The height of the pixmap is automatically calculated so that the
1058 aspect ratio of the pixmap is preserved.
1059
1060 If \a width is 0 or negative, a null pixmap is returned.
1061
1062 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1063 Transformations}
1064*/
1065QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const
1066{
1067 if (isNull()) {
1068 qWarning(msg: "QPixmap::scaleWidth: Pixmap is a null pixmap");
1069 return copy();
1070 }
1071 if (w <= 0)
1072 return QPixmap();
1073
1074 Q_TRACE_SCOPE(QPixmap_scaledToWidth, w, mode);
1075
1076 qreal factor = (qreal) w / width();
1077 QTransform wm = QTransform::fromScale(dx: factor, dy: factor);
1078 return transformed(wm, mode);
1079}
1080
1081/*!
1082 \fn QPixmap QPixmap::scaledToHeight(int height,
1083 Qt::TransformationMode mode) const
1084
1085 Returns a scaled copy of the image. The returned image is scaled
1086 to the given \a height using the specified transformation \a mode.
1087 The width of the pixmap is automatically calculated so that the
1088 aspect ratio of the pixmap is preserved.
1089
1090 If \a height is 0 or negative, a null pixmap is returned.
1091
1092 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1093 Transformations}
1094*/
1095QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const
1096{
1097 if (isNull()) {
1098 qWarning(msg: "QPixmap::scaleHeight: Pixmap is a null pixmap");
1099 return copy();
1100 }
1101 if (h <= 0)
1102 return QPixmap();
1103
1104 Q_TRACE_SCOPE(QPixmap_scaledToHeight, h, mode);
1105
1106 qreal factor = (qreal) h / height();
1107 QTransform wm = QTransform::fromScale(dx: factor, dy: factor);
1108 return transformed(wm, mode);
1109}
1110
1111/*!
1112 Returns a copy of the pixmap that is transformed using the given
1113 transformation \a transform and transformation \a mode. The original
1114 pixmap is not changed.
1115
1116 The transformation \a transform is internally adjusted to compensate
1117 for unwanted translation; i.e. the pixmap produced is the smallest
1118 pixmap that contains all the transformed points of the original
1119 pixmap. Use the trueMatrix() function to retrieve the actual
1120 matrix used for transforming the pixmap.
1121
1122 This function is slow because it involves transformation to a
1123 QImage, non-trivial computations and a transformation back to a
1124 QPixmap.
1125
1126 \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
1127 Transformations}
1128*/
1129QPixmap QPixmap::transformed(const QTransform &transform,
1130 Qt::TransformationMode mode) const
1131{
1132 if (isNull() || transform.type() <= QTransform::TxTranslate)
1133 return *this;
1134
1135 return data->transformed(matrix: transform, mode);
1136}
1137
1138/*!
1139 \class QPixmap
1140 \inmodule QtGui
1141
1142 \brief The QPixmap class is an off-screen image representation
1143 that can be used as a paint device.
1144
1145 \ingroup painting
1146 \ingroup shared
1147
1148
1149 Qt provides four classes for handling image data: QImage, QPixmap,
1150 QBitmap and QPicture. QImage is designed and optimized for I/O,
1151 and for direct pixel access and manipulation, while QPixmap is
1152 designed and optimized for showing images on screen. QBitmap is
1153 only a convenience class that inherits QPixmap, ensuring a depth
1154 of 1. The isQBitmap() function returns \c true if a QPixmap object is
1155 really a bitmap, otherwise returns \c false. Finally, the QPicture class
1156 is a paint device that records and replays QPainter commands.
1157
1158 A QPixmap can easily be displayed on the screen using QLabel or
1159 one of QAbstractButton's subclasses (such as QPushButton and
1160 QToolButton). QLabel has a pixmap property, whereas
1161 QAbstractButton has an icon property.
1162
1163 QPixmap objects can be passed around by value since the QPixmap
1164 class uses implicit data sharing. For more information, see the \l
1165 {Implicit Data Sharing} documentation. QPixmap objects can also be
1166 streamed.
1167
1168 Note that the pixel data in a pixmap is internal and is managed by
1169 the underlying window system. Because QPixmap is a QPaintDevice
1170 subclass, QPainter can be used to draw directly onto pixmaps.
1171 Pixels can only be accessed through QPainter functions or by
1172 converting the QPixmap to a QImage. However, the fill() function
1173 is available for initializing the entire pixmap with a given color.
1174
1175 There are functions to convert between QImage and
1176 QPixmap. Typically, the QImage class is used to load an image
1177 file, optionally manipulating the image data, before the QImage
1178 object is converted into a QPixmap to be shown on
1179 screen. Alternatively, if no manipulation is desired, the image
1180 file can be loaded directly into a QPixmap.
1181
1182 QPixmap provides a collection of functions that can be used to
1183 obtain a variety of information about the pixmap. In addition,
1184 there are several functions that enables transformation of the
1185 pixmap.
1186
1187 \section1 Reading and Writing Image Files
1188
1189 QPixmap provides several ways of reading an image file: The file
1190 can be loaded when constructing the QPixmap object, or by using
1191 the load() or loadFromData() functions later on. When loading an
1192 image, the file name can either refer to an actual file on disk or
1193 to one of the application's embedded resources. See \l{The Qt
1194 Resource System} overview for details on how to embed images and
1195 other resource files in the application's executable.
1196
1197 Simply call the save() function to save a QPixmap object.
1198
1199 The complete list of supported file formats are available through
1200 the QImageReader::supportedImageFormats() and
1201 QImageWriter::supportedImageFormats() functions. New file formats
1202 can be added as plugins. By default, Qt supports the following
1203 formats:
1204
1205 \table
1206 \header \li Format \li Description \li Qt's support
1207 \row \li BMP \li Windows Bitmap \li Read/write
1208 \row \li GIF \li Graphic Interchange Format (optional) \li Read
1209 \row \li JPG \li Joint Photographic Experts Group \li Read/write
1210 \row \li JPEG \li Joint Photographic Experts Group \li Read/write
1211 \row \li PNG \li Portable Network Graphics \li Read/write
1212 \row \li PBM \li Portable Bitmap \li Read
1213 \row \li PGM \li Portable Graymap \li Read
1214 \row \li PPM \li Portable Pixmap \li Read/write
1215 \row \li XBM \li X11 Bitmap \li Read/write
1216 \row \li XPM \li X11 Pixmap \li Read/write
1217 \endtable
1218
1219 \section1 Pixmap Information
1220
1221 QPixmap provides a collection of functions that can be used to
1222 obtain a variety of information about the pixmap:
1223
1224 \table
1225 \header
1226 \li \li Available Functions
1227 \row
1228 \li Geometry
1229 \li
1230 The size(), width() and height() functions provide information
1231 about the pixmap's size. The rect() function returns the image's
1232 enclosing rectangle.
1233
1234 \row
1235 \li Alpha component
1236 \li
1237
1238 The hasAlphaChannel() returns \c true if the pixmap has a format that
1239 respects the alpha channel, otherwise returns \c false. The hasAlpha(),
1240 setMask() and mask() functions are legacy and should not be used.
1241 They are potentially very slow.
1242
1243 The createHeuristicMask() function creates and returns a 1-bpp
1244 heuristic mask (i.e. a QBitmap) for this pixmap. It works by
1245 selecting a color from one of the corners and then chipping away
1246 pixels of that color, starting at all the edges. The
1247 createMaskFromColor() function creates and returns a mask (i.e. a
1248 QBitmap) for the pixmap based on a given color.
1249
1250 \row
1251 \li Low-level information
1252 \li
1253
1254 The depth() function returns the depth of the pixmap. The
1255 defaultDepth() function returns the default depth, i.e. the depth
1256 used by the application on the given screen.
1257
1258 The cacheKey() function returns a number that uniquely
1259 identifies the contents of the QPixmap object.
1260
1261 \endtable
1262
1263 \section1 Pixmap Conversion
1264
1265 A QPixmap object can be converted into a QImage using the
1266 toImage() function. Likewise, a QImage can be converted into a
1267 QPixmap using the fromImage(). If this is too expensive an
1268 operation, you can use QBitmap::fromImage() instead.
1269
1270 To convert a QPixmap to and from HICON you can use the
1271 QImage::toHICON() and QImage::fromHICON() functions respectively
1272 (after converting the QPixmap to a QImage, as explained above).
1273
1274 \section1 Pixmap Transformations
1275
1276 QPixmap supports a number of functions for creating a new pixmap
1277 that is a transformed version of the original:
1278
1279 The scaled(), scaledToWidth() and scaledToHeight() functions
1280 return scaled copies of the pixmap, while the copy() function
1281 creates a QPixmap that is a plain copy of the original one.
1282
1283 The transformed() function returns a copy of the pixmap that is
1284 transformed with the given transformation matrix and
1285 transformation mode: Internally, the transformation matrix is
1286 adjusted to compensate for unwanted translation,
1287 i.e. transformed() returns the smallest pixmap containing all
1288 transformed points of the original pixmap. The static trueMatrix()
1289 function returns the actual matrix used for transforming the
1290 pixmap.
1291
1292 \sa QBitmap, QImage, QImageReader, QImageWriter
1293*/
1294
1295
1296/*!
1297 \typedef QPixmap::DataPtr
1298 \internal
1299*/
1300
1301/*!
1302 \fn DataPtr &QPixmap::data_ptr()
1303 \internal
1304*/
1305
1306/*!
1307 Returns \c true if this pixmap has an alpha channel, \e or has a
1308 mask, otherwise returns \c false.
1309
1310 \sa hasAlphaChannel(), mask()
1311*/
1312bool QPixmap::hasAlpha() const
1313{
1314 return data && data->hasAlphaChannel();
1315}
1316
1317/*!
1318 Returns \c true if the pixmap has a format that respects the alpha
1319 channel, otherwise returns \c false.
1320
1321 \sa hasAlpha()
1322*/
1323bool QPixmap::hasAlphaChannel() const
1324{
1325 return data && data->hasAlphaChannel();
1326}
1327
1328/*!
1329 \internal
1330*/
1331int QPixmap::metric(PaintDeviceMetric metric) const
1332{
1333 return data ? data->metric(metric) : 0;
1334}
1335
1336/*!
1337 \internal
1338*/
1339QPaintEngine *QPixmap::paintEngine() const
1340{
1341 return data ? data->paintEngine() : nullptr;
1342}
1343
1344/*!
1345 \fn QBitmap QPixmap::mask() const
1346
1347 Extracts a bitmap mask from the pixmap's alpha channel.
1348
1349 \warning This is potentially an expensive operation. The mask of
1350 the pixmap is extracted dynamically from the pixeldata.
1351
1352 \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
1353*/
1354QBitmap QPixmap::mask() const
1355{
1356 return data ? data->mask() : QBitmap();
1357}
1358
1359/*!
1360 Returns the default pixmap depth used by the application.
1361
1362 On all platforms the depth of the primary screen will be returned.
1363
1364 \note QGuiApplication must be created before calling this function.
1365
1366 \sa depth(), QColormap::depth(), {QPixmap#Pixmap Information}{Pixmap Information}
1367
1368*/
1369int QPixmap::defaultDepth()
1370{
1371 QScreen *primary = QGuiApplication::primaryScreen();
1372 if (Q_LIKELY(primary))
1373 return primary->depth();
1374 qWarning(msg: "QPixmap: QGuiApplication must be created before calling defaultDepth().");
1375 return 0;
1376}
1377
1378/*!
1379 Detaches the pixmap from shared pixmap data.
1380
1381 A pixmap is automatically detached by Qt whenever its contents are
1382 about to change. This is done in almost all QPixmap member
1383 functions that modify the pixmap (fill(), fromImage(),
1384 load(), etc.), and in QPainter::begin() on a pixmap.
1385
1386 There are two exceptions in which detach() must be called
1387 explicitly, that is when calling the handle() or the
1388 x11PictureHandle() function (only available on X11). Otherwise,
1389 any modifications done using system calls, will be performed on
1390 the shared data.
1391
1392 The detach() function returns immediately if there is just a
1393 single reference or if the pixmap has not been initialized yet.
1394*/
1395void QPixmap::detach()
1396{
1397 if (!data)
1398 return;
1399
1400 // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
1401 // the actual underlying runtime pixmap data.
1402 QPlatformPixmap *pd = handle();
1403 QPlatformPixmap::ClassId id = pd->classId();
1404 if (id == QPlatformPixmap::RasterClass) {
1405 QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
1406 rasterData->image.detach();
1407 }
1408
1409 if (data->is_cached && data->ref.loadRelaxed() == 1)
1410 QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());
1411
1412 if (data->ref.loadRelaxed() != 1) {
1413 *this = copy();
1414 }
1415 ++data->detach_no;
1416}
1417
1418/*!
1419 \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1420
1421 Converts the given \a image to a pixmap using the specified \a
1422 flags to control the conversion. The \a flags argument is a
1423 bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a
1424 flags sets all the default options.
1425
1426 In case of monochrome and 8-bit images, the image is first
1427 converted to a 32-bit pixmap and then filled with the colors in
1428 the color table. If this is too expensive an operation, you can
1429 use QBitmap::fromImage() instead.
1430
1431 \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1432*/
1433QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1434{
1435 if (image.isNull())
1436 return QPixmap();
1437
1438 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1439 qWarning(msg: "QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
1440 return QPixmap();
1441 }
1442
1443 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1444 data->fromImage(image, flags);
1445 return QPixmap(data.release());
1446}
1447
1448/*!
1449 \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
1450 \since 5.3
1451 \overload
1452
1453 Converts the given \a image to a pixmap without copying if possible.
1454*/
1455
1456
1457/*!
1458 \internal
1459*/
1460QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
1461{
1462 if (image.isNull())
1463 return QPixmap();
1464
1465 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1466 qWarning(msg: "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
1467 return QPixmap();
1468 }
1469
1470 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1471 data->fromImageInPlace(image, flags);
1472 return QPixmap(data.release());
1473}
1474
1475/*!
1476 \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1477
1478 Create a QPixmap from an image read directly from an \a imageReader.
1479 The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1480 Passing 0 for \a flags sets all the default options.
1481
1482 On some systems, reading an image directly to QPixmap can use less memory than
1483 reading a QImage to convert it to QPixmap.
1484
1485 \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1486*/
1487QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1488{
1489 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1490 qWarning(msg: "QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
1491 return QPixmap();
1492 }
1493
1494 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1495 data->fromImageReader(imageReader, flags);
1496 return QPixmap(data.release());
1497}
1498
1499/*!
1500 \internal
1501*/
1502QPlatformPixmap* QPixmap::handle() const
1503{
1504 return data.data();
1505}
1506
1507#ifndef QT_NO_DEBUG_STREAM
1508QDebug operator<<(QDebug dbg, const QPixmap &r)
1509{
1510 QDebugStateSaver saver(dbg);
1511 dbg.resetFormat();
1512 dbg.nospace();
1513 dbg << "QPixmap(";
1514 if (r.isNull()) {
1515 dbg << "null";
1516 } else {
1517 dbg << r.size() << ",depth=" << r.depth()
1518 << ",devicePixelRatio=" << r.devicePixelRatio()
1519 << ",cacheKey=" << Qt::showbase << Qt::hex << r.cacheKey() << Qt::dec << Qt::noshowbase;
1520 }
1521 dbg << ')';
1522 return dbg;
1523}
1524#endif
1525
1526QT_END_NAMESPACE
1527

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/gui/image/qpixmap.cpp