Krita Source Code Documentation
Loading...
Searching...
No Matches
imagesplit.cpp
Go to the documentation of this file.
1/*
2 * imagesplit.cc -- Part of Krita
3 *
4 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt (boud@valdyas.org)
5 * SPDX-FileCopyrightText: 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "imagesplit.h"
11
12#include <QStringList>
13#include <QDir>
14#include <QStandardPaths>
15#include <QMessageBox>
16
17#include <klocalizedstring.h>
18#include <kpluginfactory.h>
19
21#include <KoFileDialog.h>
22#include <KisDocument.h>
23
24#include <KisPart.h>
25#include <kis_debug.h>
26#include <kis_types.h>
27#include <KisViewManager.h>
28#include <kis_image.h>
29#include <kis_action.h>
30#include <kis_paint_layer.h>
31#include <kis_painter.h>
32#include <kis_paint_device.h>
33#include <KisMimeDatabase.h>
35#include <kis_guides_config.h>
36
37#include "dlg_imagesplit.h"
38
39K_PLUGIN_FACTORY_WITH_JSON(ImagesplitFactory, "kritaimagesplit.json", registerPlugin<Imagesplit>();)
40
41Imagesplit::Imagesplit(QObject *parent, const QVariantList &)
42 : KisActionPlugin(parent)
43{
44 KisAction *action = createAction("imagesplit");
45 connect(action, SIGNAL(triggered()), this, SLOT(slotImagesplit()));
46}
47
51
52bool Imagesplit::saveAsImage(const QRect &imgSize, const QString &mimeType, const QString &url)
53{
54 KisImageSP image = viewManager()->image();
55
57
58 { // make sure dst is deleted before calling 'delete exportDocument',
59 // since KisDocument checks that its image is properly deref()'d.
60 KisImageSP dst = new KisImage(document->createUndoStore(), imgSize.width(), imgSize.height(), image->colorSpace(), image->objectName());
61 dst->setResolution(image->xRes(), image->yRes());
62 document->setCurrentImage(dst);
63
64 KisPaintLayer* paintLayer = new KisPaintLayer(dst, dst->nextLayerName(), 255);
65 KisPainter gc(paintLayer->paintDevice());
66 gc.bitBlt(QPoint(0, 0), image->projection(), imgSize);
67
68 dst->addNode(paintLayer, KisNodeSP(0));
70 }
71 document->setFileBatchMode(true);
72 if (!document->exportDocumentSync(url, mimeType.toLatin1())) {
73 if (document->errorMessage().isEmpty()) {
74 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"), i18n("Could not save\n%1", document->localFilePath()));
75 } else {
76 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"), i18n("Could not save %1\nReason: %2", document->localFilePath(), document->errorMessage()));
77 }
78 return false;
79 }
80
81 delete document;
82
83 return true;
84}
85
87{
88 // Taking the title - url from caption function and removing file extension
89 QStringList strList = ((viewManager()->document())->caption()).split('.');
90 QString suffix = strList.at(0);
91
92 // Getting all mime types and converting them into names which are displayed at combo box
94 QString defaultMime = QString::fromLatin1(viewManager()->document()->mimeType());
95 if (defaultMime.isEmpty()) defaultMime = QString::fromLatin1(viewManager()->document()->nativeFormatMimeType());
96 int defaultMimeIndex = 0;
97
98 listMimeFilter.sort();
99 QStringList filteredMimeTypes;
100 QStringList listFileType;
101 int i = 0;
102 Q_FOREACH (const QString &mimeType, listMimeFilter) {
103 listFileType.append(KisMimeDatabase::descriptionForMimeType(mimeType));
104 filteredMimeTypes.append(mimeType);
105 if (mimeType == defaultMime) {
106 defaultMimeIndex = i;
107 }
108 i++;
109 }
110
111 listMimeFilter = filteredMimeTypes;
112
113 Q_ASSERT(listMimeFilter.size() == listFileType.size());
114
115 QList <qreal> xGuides = viewManager()->document()->guidesConfig().verticalGuideLines();
116 QList <qreal> yGuides = viewManager()->document()->guidesConfig().horizontalGuideLines();
117
118 std::sort(xGuides.begin(), xGuides.end());
119 std::sort(yGuides.begin(), yGuides.end());
120
121 KisImageWSP image = viewManager()->image();
122 const QTransform documentToImage =
123 QTransform::fromScale(image->xRes(), image->yRes());
124
125 for (int i = 0; i< xGuides.size(); i++) {
126 qreal line = xGuides[i];
127 xGuides[i] = documentToImage.map(QPointF(line, line)).x();
128 }
129 for (int i = 0; i< yGuides.size(); i++) {
130 qreal line = yGuides[i];
131 yGuides[i] = documentToImage.map(QPointF(line, line)).y();
132 }
133
134 qreal thumbnailRatio = qreal(200)/qMax(image->width(), image->height());
135
136 DlgImagesplit *dlgImagesplit = new DlgImagesplit(viewManager()
137 , suffix
138 , listFileType
139 , defaultMimeIndex
140 , viewManager()->document()->generatePreview(QSize(200, 200)).toImage()
141 , yGuides, xGuides, thumbnailRatio);
142 dlgImagesplit->setObjectName("Imagesplit");
143 Q_CHECK_PTR(dlgImagesplit);
144
145 if (dlgImagesplit->exec() == QDialog::Accepted) {
146
147 int numHorizontalLines = dlgImagesplit->horizontalLines();
148 int numVerticalLines = dlgImagesplit->verticalLines();
149
150 int img_width = image->width() / (numVerticalLines + 1);
151 int img_height = image->height() / (numHorizontalLines + 1);
152
153 if (dlgImagesplit->useHorizontalGuides()) {
154 numHorizontalLines = yGuides.size();
155 }
156 if (dlgImagesplit->useVerticalGuides()) {
157 numVerticalLines = xGuides.size();
158 }
159
160
161 bool stop = false;
162
163 QString mimeType;
164 QString filepath;
165 QString homepath;
166 QString suffix;
167
168 if (dlgImagesplit->autoSave()) {
169 KoFileDialog dialog(viewManager()->mainWindowAsQWidget(), KoFileDialog::OpenDirectory, "OpenDocument");
170 dialog.setCaption(i18n("Save Image on Split"));
171 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
172 QStringList mimeFilter = viewManager()->document()->importExportManager()->supportedMimeTypes(KisImportExportManager::Export);
173 QString defaultMime = QString::fromLatin1(viewManager()->document()->mimeType());
174 dialog.setMimeTypeFilters(mimeFilter, defaultMime);
175
176 QUrl directory = QUrl::fromUserInput(dialog.filename());
177
178 if (directory.isEmpty())
179 return;
180
181 mimeType = listMimeFilter.at(dlgImagesplit->cmbIndex);
182 homepath = directory.toLocalFile();
183 suffix = KisMimeDatabase::suffixesForMimeType(mimeType).first();
184 if (suffix.startsWith("*.")) {
185 suffix = suffix.remove(0, 1);
186 }
187 if (!suffix.startsWith(".")) {
188 suffix = suffix.prepend('.');
189 }
190 }
191
192 int outerLoop;
193 int innerLoop;
194
195 if (dlgImagesplit->sortHorizontal()) {
196 outerLoop = numHorizontalLines + 1;
197 innerLoop = numVerticalLines + 1;
198 }
199 else {
200 outerLoop = numVerticalLines + 1;
201 innerLoop = numHorizontalLines + 1;
202 }
203
204 xGuides.prepend(qreal(0));
205 xGuides.append(image->width());
206 yGuides.prepend(qreal(0));
207 yGuides.append(image->height());
208
209 int currentX = 0;
210 int currentY = 0;
211
212 for (int i = 0, k = 1; i < outerLoop; i++) {
213 for (int j = 0; j < innerLoop; j++, k++) {
214 int row;
215 int column;
216 if (dlgImagesplit->sortHorizontal()) {
217 row = i;
218 column = j;
219 }
220 else {
221 row = j;
222 column = i;
223 }
224
225 if (dlgImagesplit->useVerticalGuides()) {
226 currentX = xGuides[column];
227 img_width = xGuides[column+1]-currentX;
228 } else {
229 currentX = (column * img_width);
230 }
231 if (dlgImagesplit->useHorizontalGuides()) {
232 currentY = yGuides[row];
233 img_height = yGuides[row+1]-currentY;
234 } else {
235 currentY = (row * img_height);
236 }
237
238 if (dlgImagesplit->autoSave()) {
239 QString fileName = dlgImagesplit->suffix() + '_' + QString::number(k) + suffix;
240 filepath = homepath + '/' + fileName;
241 mimeType = listMimeFilter.at(dlgImagesplit->cmbIndex);
242 }
243 else {
244 KoFileDialog dialog(viewManager()->mainWindowAsQWidget(), KoFileDialog::SaveFile, "OpenDocument");
245 dialog.setCaption(i18n("Save Image on Split"));
246 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
247 dialog.setMimeTypeFilters(listMimeFilter, defaultMime);
248
249 QUrl url = QUrl::fromUserInput(dialog.filename());
250 filepath = url.toLocalFile();
251
252 mimeType = KisMimeDatabase::mimeTypeForFile(url.toLocalFile(), false);
253
254 if (url.isEmpty())
255 return;
256
257 }
258 if (!saveAsImage(QRect(currentX, currentY, img_width, img_height), mimeType, filepath)) {
259 stop = true;
260 break;
261 }
262
263 }
264 if (stop) {
265 break;
266 }
267 }
268 }
269 delete dlgImagesplit;
270}
271
272#include "imagesplit.moc"
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
bool saveAsImage(const QRect &imgSize, const QString &mimeType, const QString &url)
~Imagesplit() override
Imagesplit(QObject *parent, const QVariantList &)
void slotImagesplit()
QPointer< KisViewManager > viewManager() const
const KoColorSpace * colorSpace() const
QString nextLayerName(const QString &baseName="") const
Definition kis_image.cc:715
KisPaintDeviceSP projection() const
qint32 width() const
void initialRefreshGraph()
double xRes() const
double yRes() const
qint32 height() const
void setResolution(double xres, double yres)
static QStringList supportedMimeTypes(Direction direction)
static QStringList suffixesForMimeType(const QString &mimeType)
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
static QString descriptionForMimeType(const QString &mimeType)
Find the user-readable description for the given mimetype.
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
static KisPart * instance()
Definition KisPart.cpp:131
KisDocument * createDocument() const
Definition KisPart.cpp:230
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL
KisSharedPtr< KisNode > KisNodeSP
Definition kis_types.h:86
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisPaintDeviceSP paintDevice