【问题标题】:Linux CGI Web API - how to stdout a binary JPEG image under C++?Linux CGI Web API - 如何在 C++ 下标准输出二进制 JPEG 图像?
【发布时间】:2015-09-03 23:30:56
【问题描述】:

我正在编写一个 Web API,在 linux 下使用 CGI。一切都很好,使用 gcc。我正在向主机返回图像(jpeg):std::cout

我从网络服务器收到 200 OK,但图像不完整。

我打算重定向到设备上打开文件夹中的文件,但这必须是安全的传输,并且不提供给知道该 URL 的任何人。

我被难住了!

sn-p 代码如下:

std:string imagePath;

syslog(LOG_DEBUG, "Processing GetImage, Image: '%s'", imagePath.c_str());
std::cout << "Content-Type: image/jpeg\n\n";
int length;
char * buffer;

ifstream is;
is.open(imagePath.c_str(), ios::in | ios::binary);
if (is.is_open())
{
    // get length of file:
    is.seekg(0, ios::end);
    length = (int)is.tellg();
    is.seekg(0, ios::beg);

    // allocate memory:
    buffer = new char[length];  // gobble up all the precious memory, I'll optimize it into a smaller buffer later  
                                // OH and VECTOR Victor!    
    syslog(LOG_DEBUG, "Reading a file: %s, of length %d", imagePath.c_str(), length);    
    // read data as a block:
    is.read(buffer, length);
    if (is)
    {
        syslog(LOG_DEBUG, "All data read successfully");
    }
    else
    {
        syslog(LOG_DEBUG, "Error reading jpg image");
        return false;
    }
    is.close();

    // Issue is this next line commented out - it doesn't output the full buffer
    // std::cout << buffer;

    // Potential solution by  Captain Obvlious - I'll test in the morning
    std::cout.write(buffer, length);
}
else
{
    syslog(LOG_DEBUG, "Error opening file: %s", imagePath.c_str());
    return false;
}
return true;

【问题讨论】:

  • 您是否尝试过使用std::cout.write
  • 哦,FWIW 停止使用 buffer = new char[length]; 之类的东西并使用 vector,您的代码会感谢您。
  • 感谢男士们的快速回复。我相信你用 std::cout.write 搞定了。多亏了你们,我离明天早上 8:30 的交付成果还有一条线。我应该知道,但我是旧时 printf 用户并强迫自己使用更合适的流。我实际上是一个为 linux 做这个跨平台的 Windows 程序员。关于 Vector/Victor - 我一定会清理并重新发布更新。

标签: c++ linux cgi jpeg cout


【解决方案1】:

正如已经向您指出的那样,您需要使用 write() 而不是 IO 格式化操作。

但您甚至不需要这样做。您无需手动将一个文件复制到另一个文件,一次复制一个缓冲区,iostreams 会很乐意为您完成。

std::ifstream is;
is.open(imagePath.c_str(), std::ios::in | std::ios::binary);
if (is.is_open())
{
    std::cout << is.rdbuf();
}

差不多了。

【讨论】:

    【解决方案2】:

    这归结为一个更简单的块。我对这个例子的 imagePath 进行了硬编码。把它放在你的 linux web 服务器的 cgi_bin 文件夹中,在 ../www_images/image0001.jpg 中放置一个 jpg 并从你的客户端通过 http:///cgi_bin/test 调用 web 服务器,然后你返回图像。

    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    
    int test()
    {
        std::ifstream fileStream;
        std::string imagePath = "../www_images/image0001.jpg";  // pass this variable in
    
        // output an image header - CGI
        syslog(LOG_DEBUG, "Processing GetImage, Image: '%s'", imagePath.c_str());
        std::cout << "Content-Type: image/jpeg\n\n";
    
        // output binary image
        fileStream.open(imagePath.c_str(), std::ios::in | std::ios::binary);
        if (fileStream.is_open())
        {
            std::cout << fileStream.rdbuf();
        }
        else
        {
            return 1;   // error - not handled in this code
        }
        return 0;
    }
    

    ps:请不要在括号中进行宗教战争。 ;)

    【讨论】:

      猜你喜欢
      • 2010-12-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      相关资源
      最近更新 更多