Kstars

imageexporter.cpp
1/*
2 SPDX-FileCopyrightText: 2013 Akarsh Simha <akarsh.simha@kdemail.net>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7/* Project Includes */
8#include "imageexporter.h"
9#include "kstars.h"
10#include "skyqpainter.h"
11#include "skymap.h"
12
13#include <KJob>
14#include <KIO/StoredTransferJob>
15
16/* Qt Includes */
17#include <QTemporaryFile>
18#include <QStatusBar>
19#include <QSvgGenerator>
20#include <QApplication>
21
22ImageExporter::ImageExporter(QObject *parent) : QObject(parent), m_includeLegend(false), m_Size(nullptr)
23{
24 m_Legend = new Legend;
25
26 // set font for legend labels
27 m_Legend->setFont(QFont("Courier New", 8));
28
29 // set up the default alpha
30 setLegendAlpha(160);
31}
32
33void ImageExporter::exportSvg(const QString &fileName)
34{
35 SkyMap *map = SkyMap::Instance();
36
37 // export as SVG
39 svgGenerator.setFileName(fileName);
40 svgGenerator.setTitle(i18n("KStars Exported Sky Image"));
41 svgGenerator.setDescription(i18n("KStars Exported Sky Image"));
42 svgGenerator.setSize(QSize(map->width(), map->height()));
43 svgGenerator.setResolution(qMax(map->logicalDpiX(), map->logicalDpiY()));
44 svgGenerator.setViewBox(QRect(0, 0, map->width(), map->height()));
45
47 painter.begin();
48
49 map->exportSkyImage(&painter);
50
51 if (m_includeLegend)
52 {
53 addLegend(&painter);
54 }
55
56 painter.end();
57}
58
59bool ImageExporter::exportRasterGraphics(const QString &fileName)
60{
61 //Determine desired image format from filename extension
62 QString ext = fileName.mid(fileName.lastIndexOf(".") + 1);
63
64 // export as raster graphics
65 const char *format = "PNG";
66
67 if (ext.toLower() == "png")
68 {
69 format = "PNG";
70 }
71 else if (ext.toLower() == "jpg" || ext.toLower() == "jpeg")
72 {
73 format = "JPG";
74 }
75 else if (ext.toLower() == "gif")
76 {
77 format = "GIF";
78 }
79 else if (ext.toLower() == "pnm")
80 {
81 format = "PNM";
82 }
83 else if (ext.toLower() == "bmp")
84 {
85 format = "BMP";
86 }
87 else
88 {
89 qWarning() << "Could not parse image format of" << fileName << "assuming PNG";
90 }
91
92 SkyMap *map = SkyMap::Instance();
93
94 int width, height;
95 if (m_Size)
96 {
97 width = m_Size->width();
98 height = m_Size->height();
99 }
100 else
101 {
102 width = map->width();
103 height = map->height();
104 }
105
106 QPixmap skyimage(map->width(), map->height());
107 QPixmap outimage(width, height);
108 outimage.fill();
109
110 map->exportSkyImage(&skyimage);
111 qApp->processEvents();
112
113 //skyImage is the size of the sky map. The requested image size is w x h.
114 //If w x h is smaller than the skymap, then we simply crop the image.
115 //If w x h is larger than the skymap, pad the skymap image with a white border.
116 if (width == map->width() && height == map->height())
117 {
118 outimage = skyimage.copy();
119 }
120
121 else
122 {
123 int dx(0), dy(0), sx(0), sy(0);
124 int sw(map->width()), sh(map->height());
125
126 if (width > map->width())
127 {
128 dx = (width - map->width()) / 2;
129 }
130
131 else
132 {
133 sx = (map->width() - width) / 2;
134 sw = width;
135 }
136
137 if (height > map->height())
138 {
139 dy = (height - map->height()) / 2;
140 }
141
142 else
143 {
144 sy = (map->height() - height) / 2;
145 sh = height;
146 }
147
148 QPainter p;
149 p.begin(&outimage);
150 p.fillRect(outimage.rect(), QBrush(Qt::white));
151 p.drawImage(dx, dy, skyimage.toImage(), sx, sy, sw, sh);
152 p.end();
153 }
154
155 if (m_includeLegend)
156 {
157 addLegend(&outimage);
158 }
159
160 if (!outimage.save(fileName, format))
161 {
162 m_lastErrorMessage = i18n("Error: Unable to save image: %1", fileName);
163 qDebug() << Q_FUNC_INFO << m_lastErrorMessage;
164 return false;
165 }
166
167 else
168 {
169 KStars::Instance()->statusBar()->showMessage(i18n("Saved image to %1", fileName));
170 return true;
171 }
172}
173void ImageExporter::addLegend(SkyQPainter *painter)
174{
175 m_Legend->paintLegend(painter);
176}
177
178void ImageExporter::addLegend(QPaintDevice *pd)
179{
180 SkyQPainter painter(KStars::Instance(), pd);
181 painter.begin();
182
183 addLegend(&painter);
184
185 painter.end();
186}
187
189{
191
192 m_lastErrorMessage = QString();
193 if (fileURL.isValid())
194 {
197 bool isLocalFile = fileURL.isLocalFile();
198
199 if (isLocalFile)
200 {
201 fname = fileURL.toLocalFile();
202 }
203
204 else
205 {
206 tmpfile.open();
207 fname = tmpfile.fileName();
208 }
209
210 //Determine desired image format from filename extension
211 QString ext = fname.mid(fname.lastIndexOf(".") + 1);
212 if (ext.toLower() == "svg")
213 {
214 exportSvg(fname);
215 }
216
217 else
218 {
219 return exportRasterGraphics(fname);
220 }
221
222 if (!isLocalFile)
223 {
224 //attempt to upload image to remote location
226 //if(!KIO::NetAccess::upload(tmpfile.fileName(), fileURL, m_KStars))
227 if (put_job->exec() == false)
228 {
229 m_lastErrorMessage = i18n("Could not upload image to remote location: %1", fileURL.url());
230 qWarning() << m_lastErrorMessage;
231 return false;
232 }
233 }
234 return true;
235 }
236 m_lastErrorMessage = i18n("Could not export image: URL %1 invalid", fileURL.url());
237 qWarning() << m_lastErrorMessage;
238 return false;
239}
240
241void ImageExporter::setLegendProperties(Legend::LEGEND_TYPE type, Legend::LEGEND_ORIENTATION orientation,
242 Legend::LEGEND_POSITION position, int alpha, bool include)
243{
244 // set background color (alpha)
245 setLegendAlpha(alpha);
246 // set legend orientation
247 m_Legend->setOrientation(orientation);
248
249 // set legend type
250 m_Legend->setType(type);
251
252 // set legend position
253 m_Legend->setPosition(position);
254
255 m_includeLegend = include;
256}
257
259{
260 delete m_Legend;
261}
262
264{
265 if (size)
266 m_Size = new QSize(*size); // make a copy, so it's safe if the original gets deleted
267 else
268 m_Size = nullptr;
269}
270
272{
273 Q_ASSERT(alpha >= 0 && alpha <= 255);
274 Q_ASSERT(m_Legend);
275 QColor bgColor = m_Legend->getBgColor();
276 bgColor.setAlpha(alpha);
277 m_Legend->setBgColor(bgColor);
278}
~ImageExporter() override
Destructor.
void setLegendAlpha(int alpha)
Set legend transparency.
void setLegendProperties(Legend::LEGEND_TYPE type, Legend::LEGEND_ORIENTATION orientation, Legend::LEGEND_POSITION position, int alpha=160, bool include=true)
Set the legend properties.
ImageExporter(QObject *parent=nullptr)
Constructor.
bool exportImage(QString url)
Exports an image with the defined settings.
void setRasterOutputSize(const QSize *size)
Set the size of output raster images.
static KStars * Instance()
Definition kstars.h:123
This is the canvas on which the sky is painted.
Definition skymap.h:54
The QPainter-based painting backend.
Definition skyqpainter.h:31
void end() override
End and finalize painting.
void begin() override
Begin painting.
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT StoredTransferJob * storedHttpPost(const QByteArray &arr, const QUrl &url, JobFlags flags=DefaultFlags)
void setAlpha(int alpha)
bool begin(QPaintDevice *device)
void drawImage(const QPoint &point, const QImage &image)
bool end()
void fillRect(const QRect &rectangle, QGradient::Preset preset)
int height() const const
int width() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
QString mid(qsizetype position, qsizetype n) const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:01 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.