如何在SVG中包含来自互联网的图像Qt将显示?
我一直收到错误:
couldn't create image from "http://www.colorwiki.com/images/2/22/Lindbloom.jpg"
SVG:
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="http://www.colorwiki.com/images/2/22/Lindbloom.jpg" x="0" y="0"
height="100" width="100" />
</svg>
如果图像是本地图像,则可以正常工作 - 它只能用于远程图像。
答案 0 :(得分:0)
您必须重写从QtextBrowser继承的Class,以下是我的解决方案: 头文件:
#ifndef QHTMLBROWSER_H
#define QHTMLBROWSER_H
#include <QtNetwork/QtNetwork>
#include <QTextBrowser>
#include <QTextDocument>
#include <QHash>
#include <QRegExp>
#include <QCryptographicHash>
#include <QApplication>
class QHtmlBrowser : public QTextBrowser
{
Q_OBJECT
public:
explicit QHtmlBrowser(QWidget *parent=0);
~QHtmlBrowser();
void load(const QString &strHtml);
void addResource(const QString& key, const QByteArray& bytes);
void showHtml(const QString& strHtml, int timeoutSeconds);
signals:
void loadFinished();
private:
QString mHtml;
QHash<QString, QByteArray> mResources;
public slots:
void onLoadFinished();
};
#endif // QHTMLBROWSER_H
Cpp文件:
#include "qhtmlbrowser.h"
#include <QtGui/QVBoxLayout>
#include "globalsetting.h"
/*only provide the function GlobalSetting::getServer(),
full url like : http://www.colorwiki.com
*/
#define hit_ext(p) \
else if (src.endsWith(#p, Qt::CaseInsensitive)) \
ext = #p
#define index_tag "question"
#define images_tag "http://"
QString setUrl(QUrl& parentUrl, const QString& path)
{
QString srcUrl;
QString hostPath = parentUrl.host();
if (parentUrl.port() != 80 && parentUrl.port()>0)
hostPath += ":" + QString::number(parentUrl.port());
hostPath += parentUrl.path();
int pos = hostPath.lastIndexOf('/');
if (pos > -1)
hostPath = hostPath.left(pos);
srcUrl = hostPath + "/" + path;
while (srcUrl.contains("//"))
srcUrl.replace("//", "/");
srcUrl = "http://" + srcUrl;
return srcUrl;
}
/*
Because the Qtextbrowser only support the simple width=**, height=**, not support the
style="width:**px;height:**px", this function to change the style format.
*/
QString formatStyle(QString sStyle)
{
QStringList stylelist = sStyle.split(";");
QRegExp rx("(\\d+)"); // match digit.
QString s_result;
foreach(QString st , stylelist)
{
int pos=0;
QString temp;
QString str = st.toLower();
while ((pos = rx.indexIn(str, pos)) != -1) {
temp=rx.cap(0);
pos += rx.matchedLength();
}
if (str.contains("width"))
{
s_result = s_result+ " "+"width="+temp+" ";
}else if (str.contains("height"))
{
s_result = s_result+ " "+"height="+temp+" ";
}
}
return s_result;
}
void showQuestion(QHtmlBrowser *browser, const QString& strHtml, int timeoutSeconds)
{
browser->showHtml(strHtml, timeoutSeconds);
}
void QHtmlBrowser::showHtml(const QString& strHtml, int timeoutSeconds)
{
QNetworkAccessManager network;
QNetworkRequest request;
QByteArray requestContent;
bool timeout;
QUrl url(GlobalSetting::getServer());
QString content = strHtml;
//QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive);
QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*style\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive);
imgTagRegex.setMinimal(true);
QStringList imgSrcList;
QStringList imgTagList;
QStringList imgStyleList;
int offset = 0;
QString s_test;
while( (offset = imgTagRegex.indexIn(content, offset)) != -1){
offset += imgTagRegex.matchedLength();
imgTagList.append(imgTagRegex.cap(0));
imgSrcList.append(imgTagRegex.cap(1));
imgStyleList.append(imgTagRegex.cap(2));
}
QString srcUrl;
//QString resourcePrefix(GlobalSetting::g_server);
QString ext;
int index = -1;
QDateTime stamp;
foreach(QString src, imgSrcList)
{
index++;
srcUrl.clear();
if (src.startsWith("http://", Qt::CaseInsensitive))
srcUrl = src;
else
{
if (0){}
hit_ext(.png);
hit_ext(.jpeg);
hit_ext(.jpg);
hit_ext(.gif);
hit_ext(.svg);
else continue;
if (src.startsWith("://") || src.startsWith("file://", Qt::CaseInsensitive)) continue;
srcUrl = setUrl(url, src);
request.setUrl(srcUrl);
requestContent = srcUrl.toUtf8();
request.setHeader(QNetworkRequest::ContentLengthHeader, requestContent.length());
//QCryptographicHash hash(QCryptographicHash::Md5);
if (QNetworkReply* reply = network.get(request))
{
timeout = false;
stamp = QDateTime::currentDateTime();
while (reply->isRunning())
{
QApplication::processEvents();
if (stamp.secsTo(QDateTime::currentDateTime()) > timeoutSeconds)
{
reply->abort();
timeout = true;
break;
}
}
if (timeout)
{
delete reply;
continue;
}
/*
// give up crypt the link of image src for speed up the display in embedded system.
QString imgFile = resourcePrefix + "/";
hash.addData(srcUrl.toUtf8());
foreach(char c, hash.result())
{
int cInt = (int)c;
if (cInt < 10)
imgFile += "0" + QString::number(cInt, 16).left(1);
else
imgFile += QString::number(cInt, 16).left(2);
}
imgFile += ext;
*/
QString target = imgTagList[index];
QString style = imgStyleList[index];
if(target.contains("style"))
{
int istart=target.indexOf("style");
int iend = target.indexOf(style)+style.size();
QString fstyle = target.mid(istart, iend-istart+1);
target.replace(fstyle, formatStyle(style));
}
//target.replace(src, imgFile);
target.replace(src, srcUrl);
//addResource(imgFile, reply->readAll());
addResource(srcUrl, reply->readAll());
content.replace(imgTagList[index], target);
delete reply;
}
}
}
addResource(index_tag, content.toUtf8());
emit loadFinished();
}
void QHtmlBrowser::onLoadFinished()
{
QTextDocument* document = new QTextDocument(this);
if (mResources.contains(index_tag))
{
foreach(QString key, mResources.keys())
{
if (key.startsWith(images_tag))
{
document->addResource(QTextDocument::ImageResource, key, QVariant(mResources[key]));
//document->adjustSize();
}
}
document->setHtml(QString::fromUtf8(mResources[index_tag]));
//this->setLineWrapColumnOrWidth(200);
this->setDocument(document);
}
}
QHtmlBrowser::QHtmlBrowser(QWidget *parent)
:QTextBrowser(parent)
{
this->setReadOnly(true);
//this->setLineWrapColumnOrWidth();
this->setContextMenuPolicy(Qt::NoContextMenu);
this->setAcceptRichText(true);
this->setAutoFormatting(QTextEdit::AutoAll);
connect(this, SIGNAL(loadFinished()), SLOT(onLoadFinished()));
}
QHtmlBrowser::~QHtmlBrowser()
{
}
void QHtmlBrowser::load(const QString &strHtml)
{
mHtml = strHtml;
QtConcurrent::run(showQuestion, this, strHtml, 30);
}
void QHtmlBrowser::addResource(const QString &key, const QByteArray &bytes)
{
if (mResources.contains(key))
mResources[key] = bytes;
else
mResources.insert(key, bytes);
}