从内存加载图像

时间:2013-12-22 01:39:18

标签: c++ sfml

根据documentation,可以加载sf::Texture三种不同的方式:从文件,从流,从内存。我想我需要后者,但我对此并不确定。如果我这样做,我就无法弄清楚如何使用它。

我有一个方法,给定一个可以使用的URL,需要返回sf::Sprite。我成功下载了二进制数据,并将其存储在一个字符串中(因为Http::Response::getBody()返回)。我知道这是一个事实,这是正确的数据,因为如果我写它并将其保存到文件,我可以查看图像。我不想要文件,我只需要显示图像。

这是功能:

sf::Sprite Downloader::GetPicture(const std::string &url)
{
    sf::Http http;
    std::string host = url.substr(0, url.find("net/")+4 );
    std::string uri = url.substr(url.find("net/")+4, url.size());
    http.setHost(host);
    request.setUri(uri);
    response = http.sendRequest(request);
    std::string data = response.getBody();

    //THIS IS WRONG
    sf::Texture texture;    
    texture.loadFromMemory((void*)data, sizeof(data));
    return sf::Sprite(texture);

    /* THIS WORKS, BUT I DON'T WANT TO SAVE, REOPEN, THEN DELETE AT THE END
    std::ofstream fileout("test.jpg", std::ios::binary);
    fileout << data;
    fileout.close();
    */
}

这是懒惰的loadFromMemory signaturevoid*混淆了我,这可能是问题所在。)

此外,这可能是一种完全错误的做法;可能会延长sf::InputStream,并使用loadFromStream

问题是,返回sf::Sprite的维度为0×0,大小为0,这就是我所知道的错误。

1 个答案:

答案 0 :(得分:2)

您的代码中有两个错误。凯西发现了一个,你应该使用texture.loadFromMemory(data.data(), data.length())

texture.loadFromMemory((void*)data, sizeof(data));的问题是你会加载一些垃圾而不一定是图片数据;你将加载字符串的其他属性(如长度的整数,也可能是数据本身的指针)。

另一个与white square problem有关:你返回一个精灵而不是纹理。函数返回后,纹理被破坏,精灵只会显示一个白色矩形。

您可以执行以下操作:

sf::Texture dlpicture(std::string host, std::string uri)
{
    sf::Http http(host);
    sf::Http::Request request(uri);
    auto response = http.sendRequest(request);
    auto data = response.getBody();

    sf::Texture text;
    text.loadFromMemory(data.data(), data.length());

    return text;
}

您可以使用sf::Texture texture = dlpicture("www.sfml-dev.org", "download/goodies/sfml-logo-small.png");尝试。

SFML确实支持jpg格式,但不支持其所有变体。例如,不支持渐进式jpg。你必须使用另一种格式。