imageexporter.cpp 7.34 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/***************************************************************************
                imageexporter.cpp  -  K Desktop Planetarium
                             -------------------
    begin                : Sun 13 Jan 2013 00:53:50 CST
    copyright            : (c) 2013 by Akarsh Simha
    email                : akarsh.simha@kdemail.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/


/* Project Includes */
#include "imageexporter.h"
#include "kstars.h"
#include "skyqpainter.h"
#include "skymap.h"

Jasem Mutlaq's avatar
Jasem Mutlaq committed
25 26 27
#include <KJob>
#include <KIO/StoredTransferJob>

28
/* Qt Includes */
29 30
#include <QTemporaryFile>
#include <QtSvg/QSvgGenerator>
31

32
ImageExporter::ImageExporter( QObject *parent ) : QObject( parent ), m_includeLegend( false ), m_Size( 0 )
33 34 35 36 37
{
    m_Legend = new Legend;

    // set font for legend labels
    m_Legend->setFont(QFont("Courier New", 8));
38 39 40

    // set up the default alpha
    setLegendAlpha( 160 );
41 42 43 44
}

void ImageExporter::exportSvg(const QString &fileName)
{
45
    SkyMap *map = SkyMap::Instance();
46 47 48 49

    // export as SVG
    QSvgGenerator svgGenerator;
    svgGenerator.setFileName(fileName);
50 51
    svgGenerator.setTitle(i18n("KStars Exported Sky Image"));
    svgGenerator.setDescription(i18n("KStars Exported Sky Image"));
52 53 54 55
    svgGenerator.setSize(QSize(map->width(), map->height()));
    svgGenerator.setResolution(qMax(map->logicalDpiX(), map->logicalDpiY()));
    svgGenerator.setViewBox(QRect(0, 0, map->width(), map->height()));

56
    SkyQPainter painter(KStars::Instance(), &svgGenerator);
57 58 59 60 61 62 63 64 65 66 67 68
    painter.begin();

    map->exportSkyImage(&painter);

    if( m_includeLegend )
    {
        addLegend(&painter);
    }

    painter.end();
}

69
bool ImageExporter::exportRasterGraphics(const QString &fileName)
70 71 72 73 74 75 76 77 78 79 80 81 82 83
{
    //Determine desired image format from filename extension
    QString ext = fileName.mid(fileName.lastIndexOf(".") + 1);

    // export as raster graphics
    const char* format = "PNG";

    if(ext.toLower() == "png") {format = "PNG";}
    else if(ext.toLower() == "jpg" || ext.toLower() == "jpeg" ) { format = "JPG"; }
    else if(ext.toLower() == "gif") { format = "GIF"; }
    else if(ext.toLower() == "pnm") { format = "PNM"; }
    else if(ext.toLower() == "bmp") { format = "BMP"; }
    else
    {
84
        qWarning() << i18n("Could not parse image format of %1; assuming PNG.", fileName);
85 86
    }

87
    SkyMap *map = SkyMap::Instance();
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

    int width, height;
    if ( m_Size ) {
        width = m_Size->width();
        height = m_Size->height();
    }
    else {
        width = map->width();
        height = map->height();
    }

    QPixmap skyimage(map->width(), map->height());
    QPixmap outimage(width, height);
    outimage.fill();

    map->exportSkyImage(&skyimage);
    qApp->processEvents();

    //skyImage is the size of the sky map.  The requested image size is w x h.
    //If w x h is smaller than the skymap, then we simply crop the image.
    //If w x h is larger than the skymap, pad the skymap image with a white border.
    if(width == map->width() && height == map->height())
    {
        outimage = skyimage.copy();
    }

    else
    {
        int dx(0), dy(0), sx(0), sy(0);
        int sw(map->width()), sh(map->height());

        if(width > map->width())
        {
            dx = (width - map->width())/2;
        }

        else
        {
            sx = (map->width() - width)/2;
            sw = width;
        }

        if(height > map->height())
        {
            dy = (height - map->height())/2;
        }

        else
        {
            sy = (map->height() - height)/2;
            sh = height;
        }

        QPainter p;
        p.begin(&outimage);
        p.fillRect(outimage.rect(), QBrush( Qt::white));
        p.drawImage(dx, dy, skyimage.toImage(), sx, sy, sw, sh);
        p.end();
    }

    if( m_includeLegend )
    {
        addLegend(&outimage);
    }

    if(!outimage.save(fileName, format))
    {
155
        m_lastErrorMessage = i18n("Error: Unable to save image: %1 ", fileName);
156
        qDebug() << m_lastErrorMessage;
157
        return false;
158 159 160 161
    }

    else
    {
162
        KStars::Instance()->statusBar()->showMessage(i18n ("Saved image to %1", fileName));
163
        return true;
164 165 166 167 168 169 170 171 172
    }
}
void ImageExporter::addLegend(SkyQPainter *painter)
{
    m_Legend->paintLegend(painter);
}

void ImageExporter::addLegend(QPaintDevice *pd)
{
173
    SkyQPainter painter(KStars::Instance(), pd);
174 175 176 177 178 179 180 181 182
    painter.begin();

    addLegend(&painter);

    painter.end();
}

bool ImageExporter::exportImage( QString url )
{
183
    QUrl fileURL = QUrl::fromUserInput(url);
184

185
    m_lastErrorMessage = QString();
186 187
    if(fileURL.isValid())
    {
188
        QTemporaryFile tmpfile;
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
        QString fname;
        bool isLocalFile = fileURL.isLocalFile();

        if(isLocalFile)
        {
            fname = fileURL.toLocalFile();
        }

        else
        {
            tmpfile.open();
            fname = tmpfile.fileName();
        }

        //Determine desired image format from filename extension
        QString ext = fname.mid(fname.lastIndexOf(".") + 1);
        if(ext.toLower() == "svg")
        {
            exportSvg(fname);
        }

        else
        {
212
            return exportRasterGraphics(fname);
213 214 215 216 217
        }

        if(!isLocalFile)
        {
            //attempt to upload image to remote location
Jasem Mutlaq's avatar
Jasem Mutlaq committed
218
            KIO::StoredTransferJob *put_job = KIO::storedHttpPost(&tmpfile, fileURL, -1);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
219 220
            //if(!KIO::NetAccess::upload(tmpfile.fileName(), fileURL, m_KStars))
            if (put_job->exec() == false)
221
            {
222
                m_lastErrorMessage = i18n( "Could not upload image to remote location: %1", fileURL.url());
223
                qWarning() << m_lastErrorMessage;
224 225 226 227 228
                return false;
            }
        }
        return true;
    }
229
    m_lastErrorMessage = i18n( "Could not export image: URL %1 invalid", fileURL.url() );
230
    qWarning() << m_lastErrorMessage;
231 232 233 234
    return false;
}


235
void ImageExporter::setLegendProperties( Legend::LEGEND_TYPE type, Legend::LEGEND_ORIENTATION orientation, Legend::LEGEND_POSITION position, int alpha, bool include)
236 237
{
    // set background color (alpha)
238
    setLegendAlpha( alpha );
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
    // set legend orientation
    m_Legend->setOrientation(orientation);

    // set legend type
    m_Legend->setType(type);

    // set legend position
    m_Legend->setPosition(position);

    m_includeLegend = include;
}

ImageExporter::~ImageExporter()
{
    delete m_Legend;
}

void ImageExporter::setRasterOutputSize( const QSize *size )
{
    if ( size )
        m_Size = new QSize( *size ); // make a copy, so it's safe if the original gets deleted
    else
        m_Size = 0;
}

264 265 266 267 268 269 270 271 272
void ImageExporter::setLegendAlpha( int alpha )
{
    Q_ASSERT( alpha >= 0 && alpha <= 255 );
    Q_ASSERT( m_Legend );
    QColor bgColor = m_Legend->getBgColor();
    bgColor.setAlpha(alpha);
    m_Legend->setBgColor(bgColor);
}