| 6cf194e by Ariya Hidayat at 2008-11-03 |
1 |
/**************************************************************************** |
|
2 |
** |
| efeeab5 by David Boddie at 2009-04-03 |
3 |
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 |
** Contact: Qt Software Information (qt-info@nokia.com) |
| 6cf194e by Ariya Hidayat at 2008-11-03 |
5 |
** |
| efeeab5 by David Boddie at 2009-04-03 |
6 |
** This file is part of the Graphics Dojo project on Qt Labs. |
| 6cf194e by Ariya Hidayat at 2008-11-03 |
7 |
** |
|
8 |
** This file may be used under the terms of the GNU General Public |
| efeeab5 by David Boddie at 2009-04-03 |
9 |
** License version 2.0 or 3.0 as published by the Free Software Foundation |
| 6cf194e by Ariya Hidayat at 2008-11-03 |
10 |
** and appearing in the file LICENSE.GPL included in the packaging of |
|
11 |
** this file. Please review the following information to ensure GNU |
|
12 |
** General Public Licensing requirements will be met: |
| efeeab5 by David Boddie at 2009-04-03 |
13 |
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and |
|
14 |
** http://www.gnu.org/copyleft/gpl.html. |
| 6cf194e by Ariya Hidayat at 2008-11-03 |
15 |
** |
|
16 |
** If you are unsure which license is appropriate for your use, please |
| efeeab5 by David Boddie at 2009-04-03 |
17 |
** contact the sales department at qt-sales@nokia.com. |
| 6cf194e by Ariya Hidayat at 2008-11-03 |
18 |
** |
|
19 |
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
|
20 |
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
|
21 |
** |
|
22 |
****************************************************************************/ |
|
23 |
|
|
24 |
#include <iostream> |
|
25 |
|
|
26 |
#include <QtGui> |
|
27 |
#include <QtWebKit> |
|
28 |
|
|
29 |
class WebSnap : public QObject |
|
30 |
{ |
|
31 |
Q_OBJECT |
|
32 |
|
|
33 |
public: |
|
34 |
WebSnap(); |
|
35 |
QSize targetSize() const; |
|
36 |
void setTargetSize(const QSize &s); |
|
37 |
QImage image() const; |
|
38 |
void load(const QUrl &url, const QString &outputFileName); |
|
39 |
|
|
40 |
signals: |
|
41 |
void finished(); |
|
42 |
|
|
43 |
private slots: |
|
44 |
void saveResult(bool ok); |
|
45 |
|
|
46 |
private: |
|
47 |
QWebPage m_page; |
|
48 |
QString m_fileName; |
|
49 |
QSize m_targetSize; |
|
50 |
QImage m_image; |
|
51 |
}; |
|
52 |
|
|
53 |
WebSnap::WebSnap(): QObject() |
|
54 |
{ |
|
55 |
m_targetSize = QSize(400, 300); |
|
56 |
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(saveResult(bool))); |
|
57 |
} |
|
58 |
|
|
59 |
void WebSnap::setTargetSize(const QSize &s) |
|
60 |
{ |
|
61 |
m_targetSize = s; |
|
62 |
} |
|
63 |
|
|
64 |
QSize WebSnap::targetSize() const |
|
65 |
{ |
|
66 |
return m_targetSize; |
|
67 |
} |
|
68 |
|
|
69 |
QImage WebSnap::image() const |
|
70 |
{ |
|
71 |
return m_image; |
|
72 |
} |
|
73 |
|
|
74 |
void WebSnap::load(const QUrl &url, const QString &outputFileName) |
|
75 |
{ |
|
76 |
m_fileName = outputFileName; |
|
77 |
m_image = QImage(); |
|
78 |
m_page.mainFrame()->load(url); |
|
79 |
} |
|
80 |
|
|
81 |
void WebSnap::saveResult(bool ok) |
|
82 |
{ |
|
83 |
// crude error-checking |
|
84 |
if (!ok) { |
|
85 |
std::cerr << "Failed loading " << qPrintable(m_page.mainFrame()->url().toString()) << std::endl; |
|
86 |
emit finished(); |
|
87 |
return; |
|
88 |
} |
|
89 |
|
|
90 |
// find proper size, we stick to sensible aspect ratio |
|
91 |
QSize size = m_page.mainFrame()->contentsSize(); |
|
92 |
size.setHeight(size.width() * m_targetSize.height() / m_targetSize.width()); |
|
93 |
|
|
94 |
// create the target surface |
|
95 |
m_image = QImage(size, QImage::Format_ARGB32_Premultiplied); |
|
96 |
m_image.fill(Qt::transparent); |
|
97 |
|
|
98 |
// render and rescale |
|
99 |
QPainter p(&m_image); |
|
100 |
m_page.setViewportSize(m_page.mainFrame()->contentsSize()); |
|
101 |
m_page.mainFrame()->render(&p); |
|
102 |
p.end(); |
|
103 |
m_image = m_image.scaled(m_targetSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); |
|
104 |
|
|
105 |
if (!m_fileName.isEmpty()) { |
|
106 |
if (m_image.save(m_fileName, "png")) |
|
107 |
std::cout << "Result saved to " << qPrintable(m_fileName) << std::endl; |
|
108 |
else |
|
109 |
std::cout << "Failed to save to " << qPrintable(m_fileName) << std::endl; |
|
110 |
} |
|
111 |
|
|
112 |
emit finished(); |
|
113 |
} |
|
114 |
|
|
115 |
// shamelessly copied from Qt Demo Browser |
|
116 |
static QUrl guessUrlFromString(const QString &string) |
|
117 |
{ |
|
118 |
QString urlStr = string.trimmed(); |
|
119 |
QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); |
|
120 |
|
|
121 |
// Check if it looks like a qualified URL. Try parsing it and see. |
|
122 |
bool hasSchema = test.exactMatch(urlStr); |
|
123 |
if (hasSchema) { |
|
124 |
QUrl url(urlStr, QUrl::TolerantMode); |
|
125 |
if (url.isValid()) |
|
126 |
return url; |
|
127 |
} |
|
128 |
|
|
129 |
// Might be a file. |
|
130 |
if (QFile::exists(urlStr)) |
|
131 |
return QUrl::fromLocalFile(urlStr); |
|
132 |
|
|
133 |
// Might be a shorturl - try to detect the schema. |
|
134 |
if (!hasSchema) { |
|
135 |
int dotIndex = urlStr.indexOf(QLatin1Char('.')); |
|
136 |
if (dotIndex != -1) { |
|
137 |
QString prefix = urlStr.left(dotIndex).toLower(); |
|
138 |
QString schema = (prefix == QLatin1String("ftp")) ? prefix : QLatin1String("http"); |
|
139 |
QUrl url(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode); |
|
140 |
if (url.isValid()) |
|
141 |
return url; |
|
142 |
} |
|
143 |
} |
|
144 |
|
|
145 |
// Fall back to QUrl's own tolerant parser. |
|
146 |
return QUrl(string, QUrl::TolerantMode); |
|
147 |
} |
|
148 |
|
|
149 |
#include "websnap.moc" |
|
150 |
|
|
151 |
int main(int argc, char * argv[]) |
|
152 |
{ |
|
153 |
if ((argc < 2) || (argc == 4)) { |
|
154 |
std::cout << "Create a thumbnail preview of a web page" << std::endl << std::endl; |
|
155 |
std::cout << " websnap url [outputfile [width height]]" << std::endl << std::endl; |
|
156 |
std::cout << "Examples: " << std::endl; |
|
157 |
std::cout << " websnap www.trolltech.com" << std::endl; |
|
158 |
std::cout << " websnap www.nokia.com" << std::endl; |
|
159 |
std::cout << " websnap www.google.com google.png 400 300" << std::endl; |
|
160 |
std::cout << std::endl; |
|
161 |
return 0; |
|
162 |
} |
|
163 |
|
|
164 |
QString fileName; |
|
165 |
|
|
166 |
QUrl url = guessUrlFromString(QString::fromLatin1(argv[1])); |
|
167 |
if (argc >= 3) { |
|
168 |
fileName = QString::fromLatin1(argv[2]); |
|
169 |
} else { |
|
170 |
fileName = QFileInfo(url.path()).completeBaseName(); |
|
171 |
if (fileName.isEmpty()) |
|
172 |
fileName = "result"; |
|
173 |
fileName += ".png"; |
|
174 |
} |
|
175 |
|
|
176 |
QApplication a(argc, argv); |
|
177 |
WebSnap websnap; |
|
178 |
QObject::connect(&websnap, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); |
|
179 |
|
|
180 |
if (argc == 5) { |
|
181 |
int w = QString::fromLatin1(argv[3]).toInt(); |
|
182 |
int h = QString::fromLatin1(argv[4]).toInt(); |
|
183 |
websnap.setTargetSize(QSize(w, h)); |
|
184 |
if (!websnap.targetSize().isValid() || w <= 0 || h <= 0) { |
|
185 |
std::cerr << "Please specify a valid target size !" << std::endl; |
|
186 |
return 0; |
|
187 |
} |
|
188 |
} |
|
189 |
|
|
190 |
websnap.load(url, fileName); |
|
191 |
return a.exec(); |
|
192 |
} |
|
193 |
|