1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40/*!
41 \class QImageWriter
42 \brief The QImageWriter class provides a format independent interface
43 for writing images to files or other devices.
44
45 \inmodule QtGui
46 \reentrant
47 \ingroup painting
48 \ingroup io
49
50 QImageWriter supports setting format specific options, such as
51 compression level and quality, prior to storing the
52 image. If you do not need such options, you can use QImage::save()
53 or QPixmap::save() instead.
54
55 To store an image, you start by constructing a QImageWriter
56 object. Pass either a file name or a device pointer, and the
57 image format to QImageWriter's constructor. You can then set
58 several options, such as quality (by calling setQuality()).
59 canWrite() returns \c true if QImageWriter can write the image
60 (i.e., the image format is supported and the device is open for
61 writing). Call write() to write the image to the device.
62
63 If any error occurs when writing the image, write() will return
64 false. You can then call error() to find the type of error that
65 occurred, or errorString() to get a human readable description of
66 what went wrong.
67
68 Call supportedImageFormats() for a list of formats that
69 QImageWriter can write. QImageWriter supports all built-in image
70 formats, in addition to any image format plugins that support
71 writing.
72
73 \note QImageWriter assumes exclusive control over the file or
74 device that is assigned. Any attempts to modify the assigned file
75 or device during the lifetime of the QImageWriter object will
76 yield undefined results. If immediate access to a resource is
77 desired, the use of a scope is the recommended method.
78
79 For example:
80
81 \snippet qimagewriter/main.cpp 0
82
83 \sa QImageReader, QImageIOHandler, QImageIOPlugin, QColorSpace
84*/
85
86/*!
87 \enum QImageWriter::ImageWriterError
88
89 This enum describes errors that can occur when writing images with
90 QImageWriter.
91
92 \value DeviceError QImageWriter encountered a device error when
93 writing the image data. Consult your device for more details on
94 what went wrong.
95
96 \value UnsupportedFormatError Qt does not support the requested
97 image format.
98
99 \value InvalidImageError An attempt was made to write an invalid QImage. An
100 example of an invalid image would be a null QImage.
101
102 \value UnknownError An unknown error occurred. If you get this
103 value after calling write(), it is most likely caused by a bug in
104 QImageWriter.
105*/
106
107#include "qimagewriter.h"
108
109#include <qbytearray.h>
110#include <qfile.h>
111#include <qfileinfo.h>
112#include <qimage.h>
113#include <qimageiohandler.h>
114#include <qset.h>
115#include <qvariant.h>
116
117// factory loader
118#include <qcoreapplication.h>
119#include <private/qfactoryloader_p.h>
120
121// image handlers
122#include <private/qbmphandler_p.h>
123#include <private/qppmhandler_p.h>
124#include <private/qxbmhandler_p.h>
125#include <private/qxpmhandler_p.h>
126#ifndef QT_NO_IMAGEFORMAT_PNG
127#include <private/qpnghandler_p.h>
128#endif
129
130#include <private/qimagereaderwriterhelpers_p.h>
131
132#include <algorithm>
133
134QT_BEGIN_NAMESPACE
135
136static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
137 const QByteArray &format)
138{
139 QByteArray form = format.toLower();
140 QByteArray suffix;
141 QImageIOHandler *handler = nullptr;
142
143#ifndef QT_NO_IMAGEFORMATPLUGIN
144 typedef QMultiMap<int, QString> PluginKeyMap;
145
146 // check if any plugins can write the image
147 auto l = QImageReaderWriterHelpers::pluginLoader();
148 const PluginKeyMap keyMap = l->keyMap();
149 int suffixPluginIndex = -1;
150#endif
151
152 if (device && format.isEmpty()) {
153 // if there's no format, see if \a device is a file, and if so, find
154 // the file suffix and find support for that format among our plugins.
155 // this allows plugins to override our built-in handlers.
156 if (QFile *file = qobject_cast<QFile *>(object: device)) {
157 if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
158#ifndef QT_NO_IMAGEFORMATPLUGIN
159 const int index = keyMap.key(avalue: QString::fromLatin1(str: suffix), defaultKey: -1);
160 if (index != -1)
161 suffixPluginIndex = index;
162#endif
163 }
164 }
165 }
166
167 QByteArray testFormat = !form.isEmpty() ? form : suffix;
168
169#ifndef QT_NO_IMAGEFORMATPLUGIN
170 if (suffixPluginIndex != -1) {
171 // when format is missing, check if we can find a plugin for the
172 // suffix.
173 const int index = keyMap.key(avalue: QString::fromLatin1(str: suffix), defaultKey: -1);
174 if (index != -1) {
175 QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(object: l->instance(index));
176 if (plugin && (plugin->capabilities(device, format: suffix) & QImageIOPlugin::CanWrite))
177 handler = plugin->create(device, format: suffix);
178 }
179 }
180#endif // QT_NO_IMAGEFORMATPLUGIN
181
182 // check if any built-in handlers can write the image
183 if (!handler && !testFormat.isEmpty()) {
184 if (false) {
185#ifndef QT_NO_IMAGEFORMAT_PNG
186 } else if (testFormat == "png") {
187 handler = new QPngHandler;
188#endif
189#ifndef QT_NO_IMAGEFORMAT_BMP
190 } else if (testFormat == "bmp") {
191 handler = new QBmpHandler;
192 } else if (testFormat == "dib") {
193 handler = new QBmpHandler(QBmpHandler::DibFormat);
194#endif
195#ifndef QT_NO_IMAGEFORMAT_XPM
196 } else if (testFormat == "xpm") {
197 handler = new QXpmHandler;
198#endif
199#ifndef QT_NO_IMAGEFORMAT_XBM
200 } else if (testFormat == "xbm") {
201 handler = new QXbmHandler;
202 handler->setOption(option: QImageIOHandler::SubType, value: testFormat);
203#endif
204#ifndef QT_NO_IMAGEFORMAT_PPM
205 } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm"
206 || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") {
207 handler = new QPpmHandler;
208 handler->setOption(option: QImageIOHandler::SubType, value: testFormat);
209#endif
210 }
211 }
212
213#ifndef QT_NO_IMAGEFORMATPLUGIN
214 if (!testFormat.isEmpty()) {
215 const int keyCount = keyMap.size();
216 for (int i = 0; i < keyCount; ++i) {
217 QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(object: l->instance(index: i));
218 if (plugin && (plugin->capabilities(device, format: testFormat) & QImageIOPlugin::CanWrite)) {
219 delete handler;
220 handler = plugin->create(device, format: testFormat);
221 break;
222 }
223 }
224 }
225#endif // QT_NO_IMAGEFORMATPLUGIN
226
227 if (!handler)
228 return nullptr;
229
230 handler->setDevice(device);
231 if (!testFormat.isEmpty())
232 handler->setFormat(testFormat);
233 return handler;
234}
235
236class QImageWriterPrivate
237{
238public:
239 QImageWriterPrivate(QImageWriter *qq);
240
241 bool canWriteHelper();
242
243 // device
244 QByteArray format;
245 QIODevice *device;
246 bool deleteDevice;
247 QImageIOHandler *handler;
248
249 // image options
250 int quality;
251 int compression;
252 float gamma;
253 QString description;
254 QString text;
255 QByteArray subType;
256 bool optimizedWrite;
257 bool progressiveScanWrite;
258 QImageIOHandler::Transformations transformation;
259
260 // error
261 QImageWriter::ImageWriterError imageWriterError;
262 QString errorString;
263
264 QImageWriter *q;
265};
266
267/*!
268 \internal
269*/
270QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq)
271{
272 device = nullptr;
273 deleteDevice = false;
274 handler = nullptr;
275 quality = -1;
276 compression = -1;
277 gamma = 0.0;
278 optimizedWrite = false;
279 progressiveScanWrite = false;
280 imageWriterError = QImageWriter::UnknownError;
281 errorString = QImageWriter::tr(sourceText: "Unknown error");
282 transformation = QImageIOHandler::TransformationNone;
283
284 q = qq;
285}
286
287bool QImageWriterPrivate::canWriteHelper()
288{
289 if (!device) {
290 imageWriterError = QImageWriter::DeviceError;
291 errorString = QImageWriter::tr(sourceText: "Device is not set");
292 return false;
293 }
294 if (!device->isOpen()) {
295 if (!device->open(mode: QIODevice::WriteOnly)) {
296 imageWriterError = QImageWriter::DeviceError;
297 errorString = QImageWriter::tr(sourceText: "Cannot open device for writing: %1").arg(a: device->errorString());
298 return false;
299 }
300 }
301 if (!device->isWritable()) {
302 imageWriterError = QImageWriter::DeviceError;
303 errorString = QImageWriter::tr(sourceText: "Device not writable");
304 return false;
305 }
306 if (!handler && (handler = createWriteHandlerHelper(device, format)) == nullptr) {
307 imageWriterError = QImageWriter::UnsupportedFormatError;
308 errorString = QImageWriter::tr(sourceText: "Unsupported image format");
309 return false;
310 }
311 return true;
312}
313
314/*!
315 Constructs an empty QImageWriter object. Before writing, you must
316 call setFormat() to set an image format, then setDevice() or
317 setFileName().
318*/
319QImageWriter::QImageWriter()
320 : d(new QImageWriterPrivate(this))
321{
322}
323
324/*!
325 Constructs a QImageWriter object using the device \a device and
326 image format \a format.
327*/
328QImageWriter::QImageWriter(QIODevice *device, const QByteArray &format)
329 : d(new QImageWriterPrivate(this))
330{
331 d->device = device;
332 d->format = format;
333}
334
335/*!
336 Constructs a QImageWriter objects that will write to a file with
337 the name \a fileName, using the image format \a format. If \a
338 format is not provided, QImageWriter will detect the image format
339 by inspecting the extension of \a fileName.
340*/
341QImageWriter::QImageWriter(const QString &fileName, const QByteArray &format)
342 : QImageWriter(new QFile(fileName), format)
343{
344 d->deleteDevice = true;
345}
346
347/*!
348 Destructs the QImageWriter object.
349*/
350QImageWriter::~QImageWriter()
351{
352 if (d->deleteDevice)
353 delete d->device;
354 delete d->handler;
355 delete d;
356}
357
358/*!
359 Sets the format QImageWriter will use when writing images, to \a
360 format. \a format is a case insensitive text string. Example:
361
362 \snippet code/src_gui_image_qimagewriter.cpp 0
363
364 You can call supportedImageFormats() for the full list of formats
365 QImageWriter supports.
366
367 \sa format()
368*/
369void QImageWriter::setFormat(const QByteArray &format)
370{
371 d->format = format;
372}
373
374/*!
375 Returns the format QImageWriter uses for writing images.
376
377 \sa setFormat()
378*/
379QByteArray QImageWriter::format() const
380{
381 return d->format;
382}
383
384/*!
385 Sets QImageWriter's device to \a device. If a device has already
386 been set, the old device is removed from QImageWriter and is
387 otherwise left unchanged.
388
389 If the device is not already open, QImageWriter will attempt to
390 open the device in \l QIODevice::WriteOnly mode by calling
391 open(). Note that this does not work for certain devices, such as
392 QProcess, QTcpSocket and QUdpSocket, where more logic is required
393 to open the device.
394
395 \sa device(), setFileName()
396*/
397void QImageWriter::setDevice(QIODevice *device)
398{
399 if (d->device && d->deleteDevice)
400 delete d->device;
401
402 d->device = device;
403 d->deleteDevice = false;
404 delete d->handler;
405 d->handler = nullptr;
406}
407
408/*!
409 Returns the device currently assigned to QImageWriter, or \nullptr
410 if no device has been assigned.
411*/
412QIODevice *QImageWriter::device() const
413{
414 return d->device;
415}
416
417/*!
418 Sets the file name of QImageWriter to \a fileName. Internally,
419 QImageWriter will create a QFile and open it in \l
420 QIODevice::WriteOnly mode, and use this file when writing images.
421
422 \sa fileName(), setDevice()
423*/
424void QImageWriter::setFileName(const QString &fileName)
425{
426 setDevice(new QFile(fileName));
427 d->deleteDevice = true;
428}
429
430/*!
431 If the currently assigned device is a QFile, or if setFileName()
432 has been called, this function returns the name of the file
433 QImageWriter writes to. Otherwise (i.e., if no device has been
434 assigned or the device is not a QFile), an empty QString is
435 returned.
436
437 \sa setFileName(), setDevice()
438*/
439QString QImageWriter::fileName() const
440{
441 QFile *file = qobject_cast<QFile *>(object: d->device);
442 return file ? file->fileName() : QString();
443}
444
445/*!
446 Sets the quality setting of the image format to \a quality.
447
448 Some image formats, in particular lossy ones, entail a tradeoff between a)
449 visual quality of the resulting image, and b) encoding execution time and
450 compression level. This function sets the level of that tradeoff for image
451 formats that support it. For other formats, this value is ignored.
452
453 The value range of \a quality depends on the image format. For example,
454 the "jpeg" format supports a quality range from 0 (low visual quality, high
455 compression) to 100 (high visual quality, low compression).
456
457 \sa quality()
458*/
459void QImageWriter::setQuality(int quality)
460{
461 d->quality = quality;
462}
463
464/*!
465 Returns the quality setting of the image format.
466
467 \sa setQuality()
468*/
469int QImageWriter::quality() const
470{
471 return d->quality;
472}
473
474/*!
475 This is an image format specific function that set the compression
476 of an image. For image formats that do not support setting the
477 compression, this value is ignored.
478
479 The value range of \a compression depends on the image format. For
480 example, the "tiff" format supports two values, 0(no compression) and
481 1(LZW-compression).
482
483 \sa compression()
484*/
485void QImageWriter::setCompression(int compression)
486{
487 d->compression = compression;
488}
489
490/*!
491 Returns the compression of the image.
492
493 \sa setCompression()
494*/
495int QImageWriter::compression() const
496{
497 return d->compression;
498}
499
500#if QT_DEPRECATED_SINCE(5, 15)
501/*!
502 \obsolete Use QColorSpace conversion on the QImage instead.
503
504 This is an image format specific function that sets the gamma
505 level of the image to \a gamma. For image formats that do not
506 support setting the gamma level, this value is ignored.
507
508 The value range of \a gamma depends on the image format. For
509 example, the "png" format supports a gamma range from 0.0 to 1.0.
510
511 \sa quality()
512*/
513void QImageWriter::setGamma(float gamma)
514{
515 d->gamma = gamma;
516}
517
518/*!
519 \obsolete Use QImage::colorSpace() and QColorSpace::gamma() instead.
520
521 Returns the gamma level of the image.
522
523 \sa setGamma()
524*/
525float QImageWriter::gamma() const
526{
527 return d->gamma;
528}
529#endif
530
531/*!
532 \since 5.4
533
534 This is an image format specific function that sets the
535 subtype of the image to \a type. Subtype can be used by
536 a handler to determine which format it should use while
537 saving the image.
538
539 For example, saving an image in DDS format with A8R8G8R8 subtype:
540
541 \snippet code/src_gui_image_qimagewriter.cpp 3
542*/
543void QImageWriter::setSubType(const QByteArray &type)
544{
545 d->subType = type;
546}
547
548/*!
549 \since 5.4
550
551 Returns the subtype of the image.
552
553 \sa setSubType()
554*/
555QByteArray QImageWriter::subType() const
556{
557 return d->subType;
558}
559
560/*!
561 \since 5.4
562
563 Returns the list of subtypes supported by an image.
564*/
565QList<QByteArray> QImageWriter::supportedSubTypes() const
566{
567 if (!supportsOption(option: QImageIOHandler::SupportedSubTypes))
568 return QList<QByteArray>();
569 return qvariant_cast<QList<QByteArray> >(v: d->handler->option(option: QImageIOHandler::SupportedSubTypes));
570}
571
572/*!
573 \since 5.5
574
575 This is an image format-specific function which sets the \a optimize flags when
576 writing images. For image formats that do not support setting an \a optimize flag,
577 this value is ignored.
578
579 The default is false.
580
581 \sa optimizedWrite()
582*/
583void QImageWriter::setOptimizedWrite(bool optimize)
584{
585 d->optimizedWrite = optimize;
586}
587
588/*!
589 \since 5.5
590
591 Returns whether optimization has been turned on for writing the image.
592
593 \sa setOptimizedWrite()
594*/
595bool QImageWriter::optimizedWrite() const
596{
597 return d->optimizedWrite;
598}
599
600/*!
601 \since 5.5
602
603 This is an image format-specific function which turns on \a progressive scanning
604 when writing images. For image formats that do not support setting a \a progressive
605 scan flag, this value is ignored.
606
607 The default is false.
608
609 \sa progressiveScanWrite()
610*/
611
612void QImageWriter::setProgressiveScanWrite(bool progressive)
613{
614 d->progressiveScanWrite = progressive;
615}
616
617/*!
618 \since 5.5
619
620 Returns whether the image should be written as a progressive image.
621
622 \sa setProgressiveScanWrite()
623*/
624bool QImageWriter::progressiveScanWrite() const
625{
626 return d->progressiveScanWrite;
627}
628
629/*!
630 \since 5.5
631
632 Sets the image transformations metadata including orientation to \a transform.
633
634 If transformation metadata is not supported by the image format,
635 the transform is applied before writing.
636
637 \sa transformation(), write()
638*/
639void QImageWriter::setTransformation(QImageIOHandler::Transformations transform)
640{
641 d->transformation = transform;
642}
643
644/*!
645 \since 5.5
646
647 Returns the transformation and orientation the image has been set to written with.
648
649 \sa setTransformation()
650*/
651QImageIOHandler::Transformations QImageWriter::transformation() const
652{
653 return d->transformation;
654}
655
656#if QT_DEPRECATED_SINCE(5, 13)
657/*!
658 \obsolete
659
660 Use setText() instead.
661
662 This is an image format specific function that sets the
663 description of the image to \a description. For image formats that
664 do not support setting the description, this value is ignored.
665
666 The contents of \a description depends on the image format.
667
668 \sa description()
669*/
670void QImageWriter::setDescription(const QString &description)
671{
672 d->description = description;
673}
674
675/*!
676 \obsolete
677
678 Use QImageReader::text() instead.
679
680 Returns the description of the image.
681
682 \sa setDescription()
683*/
684QString QImageWriter::description() const
685{
686 return d->description;
687}
688#endif
689
690/*!
691 \since 4.1
692
693 Sets the image text associated with the key \a key to
694 \a text. This is useful for storing copyright information
695 or other information about the image. Example:
696
697 \snippet code/src_gui_image_qimagewriter.cpp 1
698
699 If you want to store a single block of data
700 (e.g., a comment), you can pass an empty key, or use
701 a generic key like "Description".
702
703 The key and text will be embedded into the
704 image data after calling write().
705
706 Support for this option is implemented through
707 QImageIOHandler::Description.
708
709 \sa QImage::setText(), QImageReader::text()
710*/
711void QImageWriter::setText(const QString &key, const QString &text)
712{
713 if (!d->description.isEmpty())
714 d->description += QLatin1String("\n\n");
715 d->description += key.simplified() + QLatin1String(": ") + text.simplified();
716}
717
718/*!
719 Returns \c true if QImageWriter can write the image; i.e., the image
720 format is supported and the assigned device is open for reading.
721
722 \sa write(), setDevice(), setFormat()
723*/
724bool QImageWriter::canWrite() const
725{
726 if (QFile *file = qobject_cast<QFile *>(object: d->device)) {
727 const bool remove = !file->isOpen() && !file->exists();
728 const bool result = d->canWriteHelper();
729
730 // This looks strange (why remove if it doesn't exist?) but the issue
731 // here is that canWriteHelper will create the file in the process of
732 // checking if the write can succeed. If it subsequently fails, we
733 // should remove that empty file.
734 if (!result && remove)
735 file->remove();
736 return result;
737 }
738
739 return d->canWriteHelper();
740}
741
742extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient);
743
744/*!
745 Writes the image \a image to the assigned device or file
746 name. Returns \c true on success; otherwise returns \c false. If the
747 operation fails, you can call error() to find the type of error
748 that occurred, or errorString() to get a human readable
749 description of the error.
750
751 \sa canWrite(), error(), errorString()
752*/
753bool QImageWriter::write(const QImage &image)
754{
755 // Do this before canWrite, so it doesn't create a file if this fails.
756 if (Q_UNLIKELY(image.isNull())) {
757 d->imageWriterError = QImageWriter::InvalidImageError;
758 d->errorString = QImageWriter::tr(sourceText: "Image is empty");
759 return false;
760 }
761
762 if (!canWrite())
763 return false;
764
765 QImage img = image;
766 if (d->handler->supportsOption(option: QImageIOHandler::Quality))
767 d->handler->setOption(option: QImageIOHandler::Quality, value: d->quality);
768 if (d->handler->supportsOption(option: QImageIOHandler::CompressionRatio))
769 d->handler->setOption(option: QImageIOHandler::CompressionRatio, value: d->compression);
770 if (d->handler->supportsOption(option: QImageIOHandler::Gamma))
771 d->handler->setOption(option: QImageIOHandler::Gamma, value: d->gamma);
772 if (!d->description.isEmpty() && d->handler->supportsOption(option: QImageIOHandler::Description))
773 d->handler->setOption(option: QImageIOHandler::Description, value: d->description);
774 if (!d->subType.isEmpty() && d->handler->supportsOption(option: QImageIOHandler::SubType))
775 d->handler->setOption(option: QImageIOHandler::SubType, value: d->subType);
776 if (d->handler->supportsOption(option: QImageIOHandler::OptimizedWrite))
777 d->handler->setOption(option: QImageIOHandler::OptimizedWrite, value: d->optimizedWrite);
778 if (d->handler->supportsOption(option: QImageIOHandler::ProgressiveScanWrite))
779 d->handler->setOption(option: QImageIOHandler::ProgressiveScanWrite, value: d->progressiveScanWrite);
780 if (d->handler->supportsOption(option: QImageIOHandler::ImageTransformation))
781 d->handler->setOption(option: QImageIOHandler::ImageTransformation, value: int(d->transformation));
782 else
783 qt_imageTransform(src&: img, orient: d->transformation);
784
785 if (!d->handler->write(image: img))
786 return false;
787 if (QFile *file = qobject_cast<QFile *>(object: d->device))
788 file->flush();
789 return true;
790}
791
792/*!
793 Returns the type of error that last occurred.
794
795 \sa ImageWriterError, errorString()
796*/
797QImageWriter::ImageWriterError QImageWriter::error() const
798{
799 return d->imageWriterError;
800}
801
802/*!
803 Returns a human readable description of the last error that occurred.
804
805 \sa error()
806*/
807QString QImageWriter::errorString() const
808{
809 return d->errorString;
810}
811
812/*!
813 \since 4.2
814
815 Returns \c true if the writer supports \a option; otherwise returns
816 false.
817
818 Different image formats support different options. Call this function to
819 determine whether a certain option is supported by the current format. For
820 example, the PNG format allows you to embed text into the image's metadata
821 (see text()).
822
823 \snippet code/src_gui_image_qimagewriter.cpp 2
824
825 Options can be tested after the writer has been associated with a format.
826
827 \sa QImageReader::supportsOption(), setFormat()
828*/
829bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
830{
831 if (!d->handler && (d->handler = createWriteHandlerHelper(device: d->device, format: d->format)) == nullptr) {
832 d->imageWriterError = QImageWriter::UnsupportedFormatError;
833 d->errorString = QImageWriter::tr(sourceText: "Unsupported image format");
834 return false;
835 }
836
837 return d->handler->supportsOption(option);
838}
839
840/*!
841 Returns the list of image formats supported by QImageWriter.
842
843 By default, Qt can write the following formats:
844
845 \table
846 \header \li Format \li MIME type \li Description
847 \row \li BMP \li image/bmp \li Windows Bitmap
848 \row \li JPG \li image/jpeg \li Joint Photographic Experts Group
849 \row \li PNG \li image/png \li Portable Network Graphics
850 \row \li PBM \li image/x-portable-bitmap \li Portable Bitmap
851 \row \li PGM \li image/x-portable-graymap \li Portable Graymap
852 \row \li PPM \li image/x-portable-pixmap \li Portable Pixmap
853 \row \li XBM \li image/x-xbitmap \li X11 Bitmap
854 \row \li XPM \li image/x-xpixmap \li X11 Pixmap
855 \endtable
856
857 Reading and writing SVG files is supported through the \l{Qt SVG} module.
858 The \l{Qt Image Formats} module provides support for additional image formats.
859
860 Note that the QApplication instance must be created before this function is
861 called.
862
863 \sa setFormat(), QImageReader::supportedImageFormats(), QImageIOPlugin
864*/
865QList<QByteArray> QImageWriter::supportedImageFormats()
866{
867 return QImageReaderWriterHelpers::supportedImageFormats(cap: QImageReaderWriterHelpers::CanWrite);
868}
869
870/*!
871 Returns the list of MIME types supported by QImageWriter.
872
873 Note that the QApplication instance must be created before this function is
874 called.
875
876 \sa supportedImageFormats(), QImageReader::supportedMimeTypes()
877*/
878QList<QByteArray> QImageWriter::supportedMimeTypes()
879{
880 return QImageReaderWriterHelpers::supportedMimeTypes(cap: QImageReaderWriterHelpers::CanWrite);
881}
882
883/*!
884 \since 5.12
885
886 Returns the list of image formats corresponding to \a mimeType.
887
888 Note that the QGuiApplication instance must be created before this function is
889 called.
890
891 \sa supportedImageFormats(), supportedMimeTypes()
892*/
893
894QList<QByteArray> QImageWriter::imageFormatsForMimeType(const QByteArray &mimeType)
895{
896 return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
897 cap: QImageReaderWriterHelpers::CanWrite);
898}
899
900QT_END_NAMESPACE
901

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