Kstars

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

KDE's Doxygen guidelines are available online.