2016-04-25 84 views
1

我需要从REST API调用中获取jpeg图像。我使用XMLHttpRequest,因为请求需要身份验证头(即,我不能只创建一个图像并将源设置为URL:passwd @ url)。从QML响应XmlHttpRequest(REST)显示图像

我想我可以使用Canvas并通过将REST数据设置为CanvasImageData对象来调用drawImage。但是,它不会画任何东西,也不会产生错误。 REST调用返回Content-Type:image/jpeg和Transfer-Encoding:分块。

这种方法应该工作,还是我错过了别的东西?有更好的建议吗?

// map_request.imageBytes is a property that holds the binary response from the REST query 
Canvas { 
id: location_map 
width: 2400 
height: 1500 
contextType: '2d' 

onPaint: { 
    if (context && map_request.imageBytes) 
    { 
    var cid = context.createImageData(width, height); 
    cid.data = map_request.imageBytes; 
    context.drawImage(cid, 0, 0); 
    } 
} 
+2

'cid.data'必须是RGBA顺序的图像像素数据,而不是原始图像数据。你能从服务器以base64编码的字符串接收图像吗?在这种情况下,您可以创建一个图像为'img.source ='data:image/png; base64,...编码的数据在这里...'。另一个解决方法是使用自定义图像提供程序。 – folibis

+0

你知道,这应该是一个答案upvote @folibis :) – BaCaRoZzo

+0

我怀疑我需要切换到自定义图像提供商,因为我无法获得base64编码的图像数据。感谢您澄清CanvasImageData的格式。请随时为我的问题创建一个答案,然后我会为您添加标记。 – Bargonaut

回答

0

正确的解决方案是创建一个QQuickImageProvider作为@folibis指示。但是,由于我使用Qt5.5,我无法创建一个QQuickAsyncImageProvider(在Qt5.6中引入)。相反,您必须在构建QQuickImageProvider时将标志设置为QQmlImageProviderBase :: ForceAsynchronousImageLoading。该标志确保调用requestImage不会阻止主GUI线程。

但是,requestImage期望返回图像,从而导致挑战从网络获取图像数据而不阻塞该线程。 QNetworkAccessManager用信号返回它的状态,QQuickImageProvider不是QObject,所以我做了一个辅助类来监视QNetworkReply的信号。

class ReplyMonitor : public QObject 
{ 
    Q_OBJECT 
public: 
    ReplyMonitor(QNetworkAccessManager *); 

public Q_SLOTS: 
    void handleReplyFinished(); 
    void handleSslErrors(QNetworkReply *, const QList<QSslError> &); 
    void handleAuthenticationRequired(QNetworkReply *, QAuthenticator *); 

public: 
    bool finished; 
}; 

ReplyMonitor::ReplyMonitor(QNetworkAccessManager *mgr) 
    : finished(false) 
{ 
    connect(mgr, SIGNAL(finished(QNetworkReply *)), this, SLOT(handleReplyFinished())); 
    connect(mgr, SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &)), 
      this, SLOT(handleSslErrors(QNetworkReply*, const QList<QSslError> &))); 
    connect(mgr, SIGNAL(authenticationRequired(QNetworkReply *, QAuthenticator *)), 
      this, SLOT(handleAuthenticationRequired(QNetworkReply*, QAuthenticator*))); 
} 

void ReplyMonitor::handleReplyFinished() 
{ 
    finished = true; 
} 
requestImage()

然后我检查finished并调用

while (!monitor->finished) 
    { 
    QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); 
    } 

之前,我创建图像的

if (reply->error() == QNetworkReply::NoError) 
    { 
    image.loadFromData(reply->readAll()); 
    } 

我奥姆返回提供了创建QNetworkRequest的详细信息,因为这是详细记录的。