Krita Source Code Documentation
Loading...
Searching...
No Matches
KisFileIconCreator.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019-2020 Agata Cacko <cacko.azh@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QFileInfo>
10#include <QApplication>
11
12#include <KoStore.h>
13
14#include <KisMimeDatabase.h>
15#include <KisDocument.h>
16#include <KisPart.h>
18#include <QFileInfo>
19
20#include <kis_painting_tweaks.h>
21#include <kis_debug.h>
23
24namespace
25{
26
29}
30
31
32QIcon createIcon(const QImage &source, const QSize &iconSize)
33{
34 QImage result;
35
36 QSize scaled = source.size().scaled(iconSize, Qt::KeepAspectRatio);
37 qreal scale = scaled.width()/(qreal)(source.width());
38
39
40
41 if (scale >= 2) {
42 // it can be treated like pixel art
43 // first scale with NN
44 int scaleInt = qRound(scale);
45 result = source.scaled(scaleInt*source.size(), Qt::KeepAspectRatio, Qt::FastTransformation);
46 // them with smooth transformation to make sure the whole icon is filled in
47 result = result.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
48 } else {
49 result = source.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
50 }
51
52 // The cropping here centers the image with the difference
53 // between the result and the expected width/height.
54 // The final size must be compared with iconSize
55 // because otherwise parts of the image may be chopped off if
56 // result > iconSize.
57 result = result.convertToFormat(QImage::Format_ARGB32) // add transparency
58 .copy((result.width() - iconSize.width()) / 2, (result.height() - iconSize.height()) / 2, iconSize.width(), iconSize.height());
59
60 // draw faint outline
61 QPainter painter(&result);
62 QColor textColor = qApp->palette().color(QPalette::Text);
63 QColor backgroundColor = qApp->palette().color(QPalette::Window);
64 QColor blendedColor = KisPaintingTweaks::blendColors(textColor, backgroundColor, 0.1);
65 painter.setPen(blendedColor);
66 painter.setBrush(QBrush(blendedColor));
67
68 painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
69 painter.drawRect(result.rect().adjusted(0, 0, -1, -1));
70
71 QColor blendedColorBrighter = KisPaintingTweaks::blendColors(textColor, backgroundColor, 0.2);
72 painter.setPen(blendedColorBrighter);
73 painter.setBrush(QBrush());
74
75 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
76 painter.drawRect(result.rect().adjusted(0, 0, -1, -1));
77
78 painter.end(); // Otherwise there will always be a copy
79
80 return QIcon(QPixmap::fromImage(result));
81}
82
83}
84
85
86bool KisFileIconCreator::createFileIcon(QString path, QIcon &icon, qreal devicePixelRatioF, QSize iconSize)
87{
88 iconSize *= devicePixelRatioF;
89 QFileInfo fi(path);
90 if (fi.exists()) {
91 QString mimeType = KisMimeDatabase::mimeTypeForFile(path);
92 if (mimeType == KisDocument::nativeFormatMimeType()
93 || mimeType == "application/x-krita-archive"
94 || mimeType == "image/openraster") {
95
96 QScopedPointer<KoStore> store(KoStore::createStore(path, KoStore::Read));
97 if (store) {
98 QString thumbnailpath;
99 if (store->hasFile(QString("Thumbnails/thumbnail.png"))){
100 thumbnailpath = QString("Thumbnails/thumbnail.png");
101 }
102 else if (store->hasFile(QString("mergedimage.png"))) {
103 thumbnailpath = QString("mergedimage.png");
104 }
105 else if (store->hasFile(QString("preview.png"))) {
106 thumbnailpath = QString("preview.png");
107 }
108 if (!thumbnailpath.isEmpty() && store->open(thumbnailpath)) {
109
110 QByteArray bytes = store->read(store->size());
111 store->close();
112 QImage img;
113 img.loadFromData(bytes);
114
115 icon = createIcon(img, iconSize);
116 return true;
117
118 } else {
119 return false;
120 }
121 } else {
122 return false;
123 }
124 } else if (mimeType == "image/tiff" || mimeType == "image/x-tiff" || mimeType == "image/jxl") {
125 // Workaround for a bug in Qt tiff QImageIO plugin
126 // XXX: Also for JPEG-XL if KImageFormats haven't updated to accommodate libjxl >= v0.9.0 API changes.
127 QScopedPointer<KisDocument> doc(KisPart::instance()->createTemporaryDocument());
128 doc->setFileBatchMode(true);
129 bool r = doc->openPath(path, KisDocument::DontAddToRecent);
130 if (r) {
131 KisPaintDeviceSP projection = doc->image()->projection();
132 const QRect bounds = projection->exactBounds();
133 QSize imageSize = bounds.size();
134 if (imageSize.width() > iconSize.width() || imageSize.height() > iconSize.height()) {
135 imageSize.scale(iconSize, Qt::KeepAspectRatio);
136 }
137 const QImage &thumbnail = projection->createThumbnail(imageSize.width(), imageSize.height(), bounds);
138 icon = createIcon(thumbnail, iconSize);
139 return true;
140 } else {
141 return false;
142 }
143 } else {
144 QImage img;
145 img.load(path);
146 if (!img.isNull()) {
147 icon = createIcon(img, iconSize);
148 return true;
149 } else {
150 return false;
151 }
152 }
153 } else {
154 return false;
155 }
156}
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
#define KIS_DECLARE_STATIC_INITIALIZER
int iconSize(qreal width, qreal height)
static QByteArray nativeFormatMimeType()
The KisFileIconCreator class creates a thumbnail from a file on disk.
bool createFileIcon(QString path, QIcon &icon, qreal devicePixelRatioF, QSize iconSize) override
createFileIcon creates an icon from the file on disk
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
QImage createThumbnail(qint32 maxw, qint32 maxh, QRect rect, qreal oversample=1, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags())
QRect exactBounds() const
static KisPart * instance()
Definition KisPart.cpp:131
static KisAbstractFileIconCreator * s_iconCreator
@ Read
Definition KoStore.h:29
static KoStore * createStore(const QString &fileName, Mode mode, const QByteArray &appIdentification=QByteArray(), Backend backend=Auto, bool writeMimetype=true)
Definition KoStore.cpp:39
#define bounds(x, a, b)
QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)