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 && qApp->thread() != QThread::currentThread()
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
372 Swaps pixmap \a other with this pixmap. This operation is very
373 fast and never fails.
374*/
375
376/*!
377 Returns the pixmap as a QVariant.
378*/
379QPixmap::operator QVariant() const
380{
381 return QVariant::fromValue(value: *this);
382}
383
384/*!
385 \fn bool QPixmap::operator!() const
386
387 Returns \c true if this is a null pixmap; otherwise returns \c false.
388
389 \sa isNull()
390*/
391
392/*!
393 Converts the pixmap to a QImage. Returns a null image if the
394 conversion fails.
395
396 If the pixmap has 1-bit depth, the returned image will also be 1
397 bit deep. Images with more bits will be returned in a format
398 closely represents the underlying system. Usually this will be
399 QImage::Format_ARGB32_Premultiplied for pixmaps with an alpha and
400 QImage::Format_RGB32 or QImage::Format_RGB16 for pixmaps without
401 alpha.
402
403 Note that for the moment, alpha masks on monochrome images are
404 ignored.
405
406 \sa fromImage(), {QImage#Image Formats}{Image Formats}
407*/
408QImage QPixmap::toImage() const
409{
410 if (isNull())
411 return QImage();
412
413 return data->toImage();
414}
415
416/*!
417 \fn QTransform QPixmap::trueMatrix(const QTransform &matrix, int width, int height)
418
419 Returns the actual matrix used for transforming a pixmap with the
420 given \a width, \a height and \a matrix.
421
422 When transforming a pixmap using the transformed() function, the
423 transformation matrix is internally adjusted to compensate for
424 unwanted translation, i.e. transformed() returns the smallest
425 pixmap containing all transformed points of the original
426 pixmap. This function returns the modified matrix, which maps
427 points correctly from the original pixmap into the new pixmap.
428
429 \sa transformed(), {QPixmap#Pixmap Transformations}{Pixmap
430 Transformations}
431*/
432QTransform QPixmap::trueMatrix(const QTransform &m, int w, int h)
433{
434 return QImage::trueMatrix(m, w, h);
435}
436
437/*!
438 \fn bool QPixmap::isQBitmap() const
439
440 Returns \c true if this is a QBitmap; otherwise returns \c false.
441*/
442
443bool QPixmap::isQBitmap() const
444{
445 return data && data->type == QPlatformPixmap::BitmapType;
446}
447
448/*!
449 \fn bool QPixmap::isNull() const
450
451 Returns \c true if this is a null pixmap; otherwise returns \c false.
452
453 A null pixmap has zero width, zero height and no contents. You
454 cannot draw in a null pixmap.
455*/
456bool QPixmap::isNull() const
457{
458 return !data || data->isNull();
459}
460
461/*!
462 \fn int QPixmap::width() const
463
464 Returns the width of the pixmap.
465
466 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
467*/
468int QPixmap::width() const
469{
470 return data ? data->width() : 0;
471}
472
473/*!
474 \fn int QPixmap::height() const
475
476 Returns the height of the pixmap.
477
478 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
479*/
480int QPixmap::height() const
481{
482 return data ? data->height() : 0;
483}
484
485/*!
486 \fn QSize QPixmap::size() const
487
488 Returns the size of the pixmap.
489
490 \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
491 Information}
492*/
493QSize QPixmap::size() const
494{
495 return data ? QSize(data->width(), data->height()) : QSize(0, 0);
496}
497
498/*!
499 \fn QRect QPixmap::rect() const
500
501 Returns the pixmap's enclosing rectangle.
502
503 \sa {QPixmap#Pixmap Information}{Pixmap Information}
504*/
505QRect QPixmap::rect() const
506{
507 return data ? QRect(0, 0, data->width(), data->height()) : QRect();
508}
509
510/*!
511 \fn int QPixmap::depth() const
512
513 Returns the depth of the pixmap.
514
515 The pixmap depth is also called bits per pixel (bpp) or bit planes
516 of a pixmap. A null pixmap has depth 0.
517
518 \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
519 Information}
520*/
521int QPixmap::depth() const
522{
523 return data ? data->depth() : 0;
524}
525
526/*!
527 Sets a mask bitmap.
528
529 This function merges the \a mask with the pixmap's alpha channel. A pixel
530 value of 1 on the mask means the pixmap's pixel is unchanged; a value of 0
531 means the pixel is transparent. The mask must have the same size as this
532 pixmap.
533
534 Setting a null mask resets the mask, leaving the previously transparent
535 pixels black. The effect of this function is undefined when the pixmap is
536 being painted on.
537
538 \warning This is potentially an expensive operation.
539
540 \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
541 QBitmap
542*/
543void QPixmap::setMask(const QBitmap &mask)
544{
545 if (paintingActive()) {
546 qWarning(msg: "QPixmap::setMask: Cannot set mask while pixmap is being painted on");
547 return;
548 }
549
550 if (!mask.isNull() && mask.size() != size()) {
551 qWarning(msg: "QPixmap::setMask() mask size differs from pixmap size");
552 return;
553 }
554
555 if (isNull())
556 return;
557
558 if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
559 return;
560
561 detach();
562 data->setMask(mask);
563}
564
565/*!
566 Returns the device pixel ratio for the pixmap. This is the
567 ratio between \e{device pixels} and \e{device independent pixels}.
568
569 Use this function when calculating layout geometry based on
570 the pixmap size: QSize layoutSize = image.size() / image.devicePixelRatio()
571
572 The default value is 1.0.
573
574 \sa setDevicePixelRatio(), QImageReader
575*/
576qreal QPixmap::devicePixelRatio() const
577{
578 if (!data)
579 return qreal(1.0);
580 return data->devicePixelRatio();
581}
582
583/*!
584 Sets the device pixel ratio for the pixmap. This is the
585 ratio between image pixels and device-independent pixels.
586
587 The default \a scaleFactor is 1.0. Setting it to something else has
588 two effects:
589
590 QPainters that are opened on the pixmap will be scaled. For
591 example, painting on a 200x200 image if with a ratio of 2.0
592 will result in effective (device-independent) painting bounds
593 of 100x100.
594
595 Code paths in Qt that calculate layout geometry based on the
596 pixmap size will take the ratio into account:
597 QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio()
598 The net effect of this is that the pixmap is displayed as
599 high-DPI pixmap rather than a large pixmap
600 (see \l{Drawing High Resolution Versions of Pixmaps and Images}).
601
602 \sa devicePixelRatio(), deviceIndependentSize()
603*/
604void QPixmap::setDevicePixelRatio(qreal scaleFactor)
605{
606 if (isNull())
607 return;
608
609 if (scaleFactor == data->devicePixelRatio())
610 return;
611
612 detach();
613 data->setDevicePixelRatio(scaleFactor);
614}
615
616/*!
617 Returns the size of the pixmap in device independent pixels.
618
619 This value should be used when using the pixmap size in user interface
620 size calculations.
621
622 The return value is equivalent to pixmap.size() / pixmap.devicePixelRatio().
623
624 \since 6.2
625*/
626QSizeF QPixmap::deviceIndependentSize() const
627{
628 if (!data)
629 return QSizeF(0, 0);
630 return QSizeF(data->width(), data->height()) / data->devicePixelRatio();
631}
632
633#ifndef QT_NO_IMAGE_HEURISTIC_MASK
634/*!
635 Creates and returns a heuristic mask for this pixmap.
636
637 The function works by selecting a color from one of the corners
638 and then chipping away pixels of that color, starting at all the
639 edges. If \a clipTight is true (the default) the mask is just
640 large enough to cover the pixels; otherwise, the mask is larger
641 than the data pixels.
642
643 The mask may not be perfect but it should be reasonable, so you
644 can do things such as the following:
645
646 \snippet code/src_gui_image_qpixmap.cpp 1
647
648 This function is slow because it involves converting to/from a
649 QImage, and non-trivial computations.
650
651 \sa QImage::createHeuristicMask(), createMaskFromColor()
652*/
653QBitmap QPixmap::createHeuristicMask(bool clipTight) const
654{
655 QBitmap m = QBitmap::fromImage(image: toImage().createHeuristicMask(clipTight));
656 return m;
657}
658#endif
659
660/*!
661 Creates and returns a mask for this pixmap based on the given \a
662 maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the
663 maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels
664 matching the maskColor will be opaque.
665
666 This function is slow because it involves converting to/from a
667 QImage.
668
669 \sa createHeuristicMask(), QImage::createMaskFromColor()
670*/
671QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
672{
673 QImage image = toImage().convertToFormat(f: QImage::Format_ARGB32);
674 return QBitmap::fromImage(image: std::move(image).createMaskFromColor(color: maskColor.rgba(), mode));
675}
676
677/*!
678 Loads a pixmap from the file with the given \a fileName. Returns
679 true if the pixmap was successfully loaded; otherwise invalidates
680 the pixmap and returns \c false.
681
682 The loader attempts to read the pixmap using the specified \a
683 format. If the \a format is not specified (which is the default),
684 the loader probes the file for a header to guess the file format.
685
686 The file name can either refer to an actual file on disk or to one
687 of the application's embedded resources. See the
688 \l{resources.html}{Resource System} overview for details on how to
689 embed pixmaps and other resource files in the application's
690 executable.
691
692 If the data needs to be modified to fit in a lower-resolution
693 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
694 control the conversion.
695
696 Note that QPixmaps are automatically added to the QPixmapCache
697 when loaded from a file in main thread; the key used is internal
698 and cannot be acquired.
699
700 \sa loadFromData(), {QPixmap#Reading and Writing Image
701 Files}{Reading and Writing Image Files}
702*/
703
704bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
705{
706 if (!fileName.isEmpty()) {
707
708 QFileInfo info(fileName);
709 // Note: If no extension is provided, we try to match the
710 // file against known plugin extensions
711 if (info.completeSuffix().isEmpty() || info.exists()) {
712 const bool inGuiThread = qApp->thread() == QThread::currentThread();
713
714 QString key = "qt_pixmap"_L1
715 % info.absoluteFilePath()
716 % HexString<uint>(info.lastModified(tz: QTimeZone::UTC).toSecsSinceEpoch())
717 % HexString<quint64>(info.size())
718 % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
719
720 if (inGuiThread && QPixmapCache::find(key, pixmap: this))
721 return true;
722
723 data = QPlatformPixmap::create(w: 0, h: 0, type: data ? data->pixelType() : QPlatformPixmap::PixmapType);
724
725 if (data->fromFile(filename: fileName, format, flags)) {
726 if (inGuiThread)
727 QPixmapCache::insert(key, pixmap: *this);
728 return true;
729 }
730 }
731 }
732
733 if (!isNull()) {
734 if (isQBitmap())
735 *this = QBitmap();
736 else
737 data.reset();
738 }
739 return false;
740}
741
742/*!
743 \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
744
745 Loads a pixmap from the \a len first bytes of the given binary \a
746 data. Returns \c true if the pixmap was loaded successfully;
747 otherwise invalidates the pixmap and returns \c false.
748
749 The loader attempts to read the pixmap using the specified \a
750 format. If the \a format is not specified (which is the default),
751 the loader probes the file for a header to guess the file format.
752
753 If the data needs to be modified to fit in a lower-resolution
754 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
755 control the conversion.
756
757 \sa load(), {QPixmap#Reading and Writing Image Files}{Reading and
758 Writing Image Files}
759*/
760
761bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
762{
763 if (len == 0 || buf == nullptr) {
764 data.reset();
765 return false;
766 }
767
768 data = QPlatformPixmap::create(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
769
770 if (data->fromData(buffer: buf, len, format, flags))
771 return true;
772
773 data.reset();
774 return false;
775}
776
777/*!
778 \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
779
780 \overload
781
782 Loads a pixmap from the binary \a data using the specified \a
783 format and conversion \a flags.
784*/
785
786
787/*!
788 Saves the pixmap to the file with the given \a fileName using the
789 specified image file \a format and \a quality factor. Returns \c true
790 if successful; otherwise returns \c false.
791
792 The \a quality factor must be in the range [0,100] or -1. Specify
793 0 to obtain small compressed files, 100 for large uncompressed
794 files, and -1 to use the default settings.
795
796 If \a format is \nullptr, an image format will be chosen from
797 \a fileName's suffix.
798
799 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
800 Image Files}
801*/
802
803bool QPixmap::save(const QString &fileName, const char *format, int quality) const
804{
805 if (isNull())
806 return false; // nothing to save
807 QImageWriter writer(fileName, format);
808 return doImageIO(io: &writer, quality);
809}
810
811/*!
812 \overload
813
814 This function writes a QPixmap to the given \a device using the
815 specified image file \a format and \a quality factor. This can be
816 used, for example, to save a pixmap directly into a QByteArray:
817
818 \snippet image/image.cpp 1
819*/
820
821bool QPixmap::save(QIODevice* device, const char* format, int quality) const
822{
823 if (isNull())
824 return false; // nothing to save
825 QImageWriter writer(device, format);
826 return doImageIO(io: &writer, quality);
827}
828
829/*! \internal
830*/
831bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
832{
833 if (quality > 100 || quality < -1)
834 qWarning(msg: "QPixmap::save: quality out of range [-1,100]");
835 if (quality >= 0)
836 writer->setQuality(qMin(a: quality,b: 100));
837 return writer->write(image: toImage());
838}
839
840
841/*!
842 Fills the pixmap with the given \a color.
843
844 The effect of this function is undefined when the pixmap is
845 being painted on.
846
847 \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
848*/
849
850void QPixmap::fill(const QColor &color)
851{
852 if (isNull())
853 return;
854
855 // Some people are probably already calling fill while a painter is active, so to not break
856 // their programs, only print a warning and return when the fill operation could cause a crash.
857 if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) {
858 qWarning(msg: "QPixmap::fill: Cannot fill while pixmap is being painted on");
859 return;
860 }
861
862 if (data->ref.loadRelaxed() == 1) {
863 // detach() will also remove this pixmap from caches, so
864 // it has to be called even when ref == 1.
865 detach();
866 } else {
867 // Don't bother to make a copy of the data object, since
868 // it will be filled with new pixel data anyway.
869 QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
870 d->resize(width: data->width(), height: data->height());
871 d->setDevicePixelRatio(data->devicePixelRatio());
872 data = d;
873 }
874 data->fill(color);
875}
876
877/*!
878 Returns a number that identifies this QPixmap. Distinct QPixmap
879 objects can only have the same cache key if they refer to the same
880 contents.
881
882 The cacheKey() will change when the pixmap is altered.
883*/
884qint64 QPixmap::cacheKey() const
885{
886 if (isNull())
887 return 0;
888
889 Q_ASSERT(data);
890 return data->cacheKey();
891}
892
893#if 0
894static void sendResizeEvents(QWidget *target)
895{
896 QResizeEvent e(target->size(), QSize());
897 QApplication::sendEvent(target, &e);
898
899 const QObjectList children = target->children();
900 for (int i = 0; i < children.size(); ++i) {
901 QWidget *child = static_cast<QWidget*>(children.at(i));
902 if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
903 sendResizeEvents(child);
904 }
905}
906#endif
907
908
909/*****************************************************************************
910 QPixmap stream functions
911 *****************************************************************************/
912#if !defined(QT_NO_DATASTREAM)
913/*!
914 \relates QPixmap
915
916 Writes the given \a pixmap to the given \a stream as a PNG
917 image. Note that writing the stream to a file will not produce a
918 valid image file.
919
920 \sa QPixmap::save(), {Serializing Qt Data Types}
921*/
922
923QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
924{
925 return stream << pixmap.toImage();
926}
927
928/*!
929 \relates QPixmap
930
931 Reads an image from the given \a stream into the given \a pixmap.
932
933 \sa QPixmap::load(), {Serializing Qt Data Types}
934*/
935
936QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
937{
938 QImage image;
939 stream >> image;
940
941 if (image.isNull()) {
942 pixmap = QPixmap();
943 } else if (image.depth() == 1) {
944 pixmap = QBitmap::fromImage(image: std::move(image));
945 } else {
946 pixmap = QPixmap::fromImage(image: std::move(image));
947 }
948 return stream;
949}
950
951#endif // QT_NO_DATASTREAM
952
953/*!
954 \internal
955*/
956
957bool QPixmap::isDetached() const
958{
959 return data && data->ref.loadRelaxed() == 1;
960}
961
962/*!
963 Replaces this pixmap's data with the given \a image using the
964 specified \a flags to control the conversion. The \a flags
965 argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
966 Passing 0 for \a flags sets all the default options. Returns \c true
967 if the result is that this pixmap is not null.
968
969 \sa fromImage()
970*/
971bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
972{
973 detach();
974 if (image.isNull() || !data)
975 *this = QPixmap::fromImage(image, flags);
976 else
977 data->fromImage(image, flags);
978 return !isNull();
979}
980
981/*!
982 \fn QPixmap QPixmap::scaled(int width, int height,
983 Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode
984 transformMode) const
985
986 \overload
987
988 Returns a copy of the pixmap scaled to a rectangle with the given
989 \a width and \a height according to the given \a aspectRatioMode and
990 \a transformMode.
991
992 If either the \a width or the \a height is zero or negative, this
993 function returns a null pixmap.
994*/
995
996/*!
997 \fn QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode
998 aspectRatioMode, Qt::TransformationMode transformMode) const
999
1000 Scales the pixmap to the given \a size, using the aspect ratio and
1001 transformation modes specified by \a aspectRatioMode and \a
1002 transformMode.
1003
1004 \image qimage-scaling.png
1005
1006 \list
1007 \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
1008 is scaled to \a size.
1009 \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
1010 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
1011 \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
1012 the pixmap is scaled to a rectangle as small as possible
1013 outside \a size, preserving the aspect ratio.
1014 \endlist
1015
1016 If the given \a size is empty, this function returns a null
1017 pixmap.
1018
1019
1020 In some cases it can be more beneficial to draw the pixmap to a
1021 painter with a scale set rather than scaling the pixmap. This is
1022 the case when the painter is for instance based on OpenGL or when
1023 the scale factor changes rapidly.
1024
1025 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1026 Transformations}
1027
1028*/
1029QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
1030{
1031 if (isNull()) {
1032 qWarning(msg: "QPixmap::scaled: Pixmap is a null pixmap");
1033 return QPixmap();
1034 }
1035 if (s.isEmpty())
1036 return QPixmap();
1037
1038 QSize newSize = size();
1039 newSize.scale(s, mode: aspectMode);
1040 newSize.rwidth() = qMax(a: newSize.width(), b: 1);
1041 newSize.rheight() = qMax(a: newSize.height(), b: 1);
1042 if (newSize == size())
1043 return *this;
1044
1045 Q_TRACE_SCOPE(QPixmap_scaled, s, aspectMode, mode);
1046
1047 QTransform wm = QTransform::fromScale(dx: (qreal)newSize.width() / width(),
1048 dy: (qreal)newSize.height() / height());
1049 QPixmap pix = transformed(wm, mode);
1050 return pix;
1051}
1052
1053/*!
1054 \fn QPixmap QPixmap::scaledToWidth(int width, Qt::TransformationMode
1055 mode) const
1056
1057 Returns a scaled copy of the image. The returned image is scaled
1058 to the given \a width using the specified transformation \a mode.
1059 The height of the pixmap is automatically calculated so that the
1060 aspect ratio of the pixmap is preserved.
1061
1062 If \a width is 0 or negative, a null pixmap is returned.
1063
1064 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1065 Transformations}
1066*/
1067QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const
1068{
1069 if (isNull()) {
1070 qWarning(msg: "QPixmap::scaleWidth: Pixmap is a null pixmap");
1071 return copy();
1072 }
1073 if (w <= 0)
1074 return QPixmap();
1075
1076 Q_TRACE_SCOPE(QPixmap_scaledToWidth, w, mode);
1077
1078 qreal factor = (qreal) w / width();
1079 QTransform wm = QTransform::fromScale(dx: factor, dy: factor);
1080 return transformed(wm, mode);
1081}
1082
1083/*!
1084 \fn QPixmap QPixmap::scaledToHeight(int height,
1085 Qt::TransformationMode mode) const
1086
1087 Returns a scaled copy of the image. The returned image is scaled
1088 to the given \a height using the specified transformation \a mode.
1089 The width of the pixmap is automatically calculated so that the
1090 aspect ratio of the pixmap is preserved.
1091
1092 If \a height is 0 or negative, a null pixmap is returned.
1093
1094 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1095 Transformations}
1096*/
1097QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const
1098{
1099 if (isNull()) {
1100 qWarning(msg: "QPixmap::scaleHeight: Pixmap is a null pixmap");
1101 return copy();
1102 }
1103 if (h <= 0)
1104 return QPixmap();
1105
1106 Q_TRACE_SCOPE(QPixmap_scaledToHeight, h, mode);
1107
1108 qreal factor = (qreal) h / height();
1109 QTransform wm = QTransform::fromScale(dx: factor, dy: factor);
1110 return transformed(wm, mode);
1111}
1112
1113/*!
1114 Returns a copy of the pixmap that is transformed using the given
1115 transformation \a transform and transformation \a mode. The original
1116 pixmap is not changed.
1117
1118 The transformation \a transform is internally adjusted to compensate
1119 for unwanted translation; i.e. the pixmap produced is the smallest
1120 pixmap that contains all the transformed points of the original
1121 pixmap. Use the trueMatrix() function to retrieve the actual
1122 matrix used for transforming the pixmap.
1123
1124 This function is slow because it involves transformation to a
1125 QImage, non-trivial computations and a transformation back to a
1126 QPixmap.
1127
1128 \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
1129 Transformations}
1130*/
1131QPixmap QPixmap::transformed(const QTransform &transform,
1132 Qt::TransformationMode mode) const
1133{
1134 if (isNull() || transform.type() <= QTransform::TxTranslate)
1135 return *this;
1136
1137 return data->transformed(matrix: transform, mode);
1138}
1139
1140/*!
1141 \class QPixmap
1142 \inmodule QtGui
1143
1144 \brief The QPixmap class is an off-screen image representation
1145 that can be used as a paint device.
1146
1147 \ingroup painting
1148 \ingroup shared
1149
1150
1151 Qt provides four classes for handling image data: QImage, QPixmap,
1152 QBitmap and QPicture. QImage is designed and optimized for I/O,
1153 and for direct pixel access and manipulation, while QPixmap is
1154 designed and optimized for showing images on screen. QBitmap is
1155 only a convenience class that inherits QPixmap, ensuring a depth
1156 of 1. The isQBitmap() function returns \c true if a QPixmap object is
1157 really a bitmap, otherwise returns \c false. Finally, the QPicture class
1158 is a paint device that records and replays QPainter commands.
1159
1160 A QPixmap can easily be displayed on the screen using QLabel or
1161 one of QAbstractButton's subclasses (such as QPushButton and
1162 QToolButton). QLabel has a pixmap property, whereas
1163 QAbstractButton has an icon property.
1164
1165 QPixmap objects can be passed around by value since the QPixmap
1166 class uses implicit data sharing. For more information, see the \l
1167 {Implicit Data Sharing} documentation. QPixmap objects can also be
1168 streamed.
1169
1170 Note that the pixel data in a pixmap is internal and is managed by
1171 the underlying window system. Because QPixmap is a QPaintDevice
1172 subclass, QPainter can be used to draw directly onto pixmaps.
1173 Pixels can only be accessed through QPainter functions or by
1174 converting the QPixmap to a QImage. However, the fill() function
1175 is available for initializing the entire pixmap with a given color.
1176
1177 There are functions to convert between QImage and
1178 QPixmap. Typically, the QImage class is used to load an image
1179 file, optionally manipulating the image data, before the QImage
1180 object is converted into a QPixmap to be shown on
1181 screen. Alternatively, if no manipulation is desired, the image
1182 file can be loaded directly into a QPixmap.
1183
1184 QPixmap provides a collection of functions that can be used to
1185 obtain a variety of information about the pixmap. In addition,
1186 there are several functions that enables transformation of the
1187 pixmap.
1188
1189 \section1 Reading and Writing Image Files
1190
1191 QPixmap provides several ways of reading an image file: The file
1192 can be loaded when constructing the QPixmap object, or by using
1193 the load() or loadFromData() functions later on. When loading an
1194 image, the file name can either refer to an actual file on disk or
1195 to one of the application's embedded resources. See \l{The Qt
1196 Resource System} overview for details on how to embed images and
1197 other resource files in the application's executable.
1198
1199 Simply call the save() function to save a QPixmap object.
1200
1201 The complete list of supported file formats are available through
1202 the QImageReader::supportedImageFormats() and
1203 QImageWriter::supportedImageFormats() functions. New file formats
1204 can be added as plugins. By default, Qt supports the following
1205 formats:
1206
1207 \table
1208 \header \li Format \li Description \li Qt's support
1209 \row \li BMP \li Windows Bitmap \li Read/write
1210 \row \li GIF \li Graphic Interchange Format (optional) \li Read
1211 \row \li JPG \li Joint Photographic Experts Group \li Read/write
1212 \row \li JPEG \li Joint Photographic Experts Group \li Read/write
1213 \row \li PNG \li Portable Network Graphics \li Read/write
1214 \row \li PBM \li Portable Bitmap \li Read
1215 \row \li PGM \li Portable Graymap \li Read
1216 \row \li PPM \li Portable Pixmap \li Read/write
1217 \row \li XBM \li X11 Bitmap \li Read/write
1218 \row \li XPM \li X11 Pixmap \li Read/write
1219 \endtable
1220
1221 \section1 Pixmap Information
1222
1223 QPixmap provides a collection of functions that can be used to
1224 obtain a variety of information about the pixmap:
1225
1226 \table
1227 \header
1228 \li \li Available Functions
1229 \row
1230 \li Geometry
1231 \li
1232 The size(), width() and height() functions provide information
1233 about the pixmap's size. The rect() function returns the image's
1234 enclosing rectangle.
1235
1236 \row
1237 \li Alpha component
1238 \li
1239
1240 The hasAlphaChannel() returns \c true if the pixmap has a format that
1241 respects the alpha channel, otherwise returns \c false. The hasAlpha(),
1242 setMask() and mask() functions are legacy and should not be used.
1243 They are potentially very slow.
1244
1245 The createHeuristicMask() function creates and returns a 1-bpp
1246 heuristic mask (i.e. a QBitmap) for this pixmap. It works by
1247 selecting a color from one of the corners and then chipping away
1248 pixels of that color, starting at all the edges. The
1249 createMaskFromColor() function creates and returns a mask (i.e. a
1250 QBitmap) for the pixmap based on a given color.
1251
1252 \row
1253 \li Low-level information
1254 \li
1255
1256 The depth() function returns the depth of the pixmap. The
1257 defaultDepth() function returns the default depth, i.e. the depth
1258 used by the application on the given screen.
1259
1260 The cacheKey() function returns a number that uniquely
1261 identifies the contents of the QPixmap object.
1262
1263 \endtable
1264
1265 \section1 Pixmap Conversion
1266
1267 A QPixmap object can be converted into a QImage using the
1268 toImage() function. Likewise, a QImage can be converted into a
1269 QPixmap using the fromImage(). If this is too expensive an
1270 operation, you can use QBitmap::fromImage() instead.
1271
1272 To convert a QPixmap to and from HICON you can use the
1273 QImage::toHICON() and QImage::fromHICON() functions respectively
1274 (after converting the QPixmap to a QImage, as explained above).
1275
1276 \section1 Pixmap Transformations
1277
1278 QPixmap supports a number of functions for creating a new pixmap
1279 that is a transformed version of the original:
1280
1281 The scaled(), scaledToWidth() and scaledToHeight() functions
1282 return scaled copies of the pixmap, while the copy() function
1283 creates a QPixmap that is a plain copy of the original one.
1284
1285 The transformed() function returns a copy of the pixmap that is
1286 transformed with the given transformation matrix and
1287 transformation mode: Internally, the transformation matrix is
1288 adjusted to compensate for unwanted translation,
1289 i.e. transformed() returns the smallest pixmap containing all
1290 transformed points of the original pixmap. The static trueMatrix()
1291 function returns the actual matrix used for transforming the
1292 pixmap.
1293
1294 \sa QBitmap, QImage, QImageReader, QImageWriter
1295*/
1296
1297
1298/*!
1299 \typedef QPixmap::DataPtr
1300 \internal
1301*/
1302
1303/*!
1304 \fn DataPtr &QPixmap::data_ptr()
1305 \internal
1306*/
1307
1308/*!
1309 Returns \c true if this pixmap has an alpha channel, \e or has a
1310 mask, otherwise returns \c false.
1311
1312 \sa hasAlphaChannel(), mask()
1313*/
1314bool QPixmap::hasAlpha() const
1315{
1316 return data && data->hasAlphaChannel();
1317}
1318
1319/*!
1320 Returns \c true if the pixmap has a format that respects the alpha
1321 channel, otherwise returns \c false.
1322
1323 \sa hasAlpha()
1324*/
1325bool QPixmap::hasAlphaChannel() const
1326{
1327 return data && data->hasAlphaChannel();
1328}
1329
1330/*!
1331 \internal
1332*/
1333int QPixmap::metric(PaintDeviceMetric metric) const
1334{
1335 return data ? data->metric(metric) : 0;
1336}
1337
1338/*!
1339 \internal
1340*/
1341QPaintEngine *QPixmap::paintEngine() const
1342{
1343 return data ? data->paintEngine() : nullptr;
1344}
1345
1346/*!
1347 \fn QBitmap QPixmap::mask() const
1348
1349 Extracts a bitmap mask from the pixmap's alpha channel.
1350
1351 \warning This is potentially an expensive operation. The mask of
1352 the pixmap is extracted dynamically from the pixeldata.
1353
1354 \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
1355*/
1356QBitmap QPixmap::mask() const
1357{
1358 return data ? data->mask() : QBitmap();
1359}
1360
1361/*!
1362 Returns the default pixmap depth used by the application.
1363
1364 On all platforms the depth of the primary screen will be returned.
1365
1366 \note QGuiApplication must be created before calling this function.
1367
1368 \sa depth(), QColormap::depth(), {QPixmap#Pixmap Information}{Pixmap Information}
1369
1370*/
1371int QPixmap::defaultDepth()
1372{
1373 QScreen *primary = QGuiApplication::primaryScreen();
1374 if (Q_LIKELY(primary))
1375 return primary->depth();
1376 qWarning(msg: "QPixmap: QGuiApplication must be created before calling defaultDepth().");
1377 return 0;
1378}
1379
1380/*!
1381 Detaches the pixmap from shared pixmap data.
1382
1383 A pixmap is automatically detached by Qt whenever its contents are
1384 about to change. This is done in almost all QPixmap member
1385 functions that modify the pixmap (fill(), fromImage(),
1386 load(), etc.), and in QPainter::begin() on a pixmap.
1387
1388 There are two exceptions in which detach() must be called
1389 explicitly, that is when calling the handle() or the
1390 x11PictureHandle() function (only available on X11). Otherwise,
1391 any modifications done using system calls, will be performed on
1392 the shared data.
1393
1394 The detach() function returns immediately if there is just a
1395 single reference or if the pixmap has not been initialized yet.
1396*/
1397void QPixmap::detach()
1398{
1399 if (!data)
1400 return;
1401
1402 // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
1403 // the actual underlying runtime pixmap data.
1404 QPlatformPixmap *pd = handle();
1405 QPlatformPixmap::ClassId id = pd->classId();
1406 if (id == QPlatformPixmap::RasterClass) {
1407 QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
1408 rasterData->image.detach();
1409 }
1410
1411 if (data->is_cached && data->ref.loadRelaxed() == 1)
1412 QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());
1413
1414 if (data->ref.loadRelaxed() != 1) {
1415 *this = copy();
1416 }
1417 ++data->detach_no;
1418}
1419
1420/*!
1421 \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1422
1423 Converts the given \a image to a pixmap using the specified \a
1424 flags to control the conversion. The \a flags argument is a
1425 bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a
1426 flags sets all the default options.
1427
1428 In case of monochrome and 8-bit images, the image is first
1429 converted to a 32-bit pixmap and then filled with the colors in
1430 the color table. If this is too expensive an operation, you can
1431 use QBitmap::fromImage() instead.
1432
1433 \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1434*/
1435QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1436{
1437 if (image.isNull())
1438 return QPixmap();
1439
1440 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1441 qWarning(msg: "QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
1442 return QPixmap();
1443 }
1444
1445 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1446 data->fromImage(image, flags);
1447 return QPixmap(data.release());
1448}
1449
1450/*!
1451 \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
1452 \since 5.3
1453 \overload
1454
1455 Converts the given \a image to a pixmap without copying if possible.
1456*/
1457
1458
1459/*!
1460 \internal
1461*/
1462QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
1463{
1464 if (image.isNull())
1465 return QPixmap();
1466
1467 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1468 qWarning(msg: "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
1469 return QPixmap();
1470 }
1471
1472 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1473 data->fromImageInPlace(image, flags);
1474 return QPixmap(data.release());
1475}
1476
1477/*!
1478 \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1479
1480 Create a QPixmap from an image read directly from an \a imageReader.
1481 The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1482 Passing 0 for \a flags sets all the default options.
1483
1484 On some systems, reading an image directly to QPixmap can use less memory than
1485 reading a QImage to convert it to QPixmap.
1486
1487 \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1488*/
1489QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1490{
1491 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1492 qWarning(msg: "QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
1493 return QPixmap();
1494 }
1495
1496 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1497 data->fromImageReader(imageReader, flags);
1498 return QPixmap(data.release());
1499}
1500
1501/*!
1502 \internal
1503*/
1504QPlatformPixmap* QPixmap::handle() const
1505{
1506 return data.data();
1507}
1508
1509#ifndef QT_NO_DEBUG_STREAM
1510QDebug operator<<(QDebug dbg, const QPixmap &r)
1511{
1512 QDebugStateSaver saver(dbg);
1513 dbg.resetFormat();
1514 dbg.nospace();
1515 dbg << "QPixmap(";
1516 if (r.isNull()) {
1517 dbg << "null";
1518 } else {
1519 dbg << r.size() << ",depth=" << r.depth()
1520 << ",devicePixelRatio=" << r.devicePixelRatio()
1521 << ",cacheKey=" << Qt::showbase << Qt::hex << r.cacheKey() << Qt::dec << Qt::noshowbase;
1522 }
1523 dbg << ')';
1524 return dbg;
1525}
1526#endif
1527
1528QT_END_NAMESPACE
1529

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