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

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