【问题标题】:Image shows up corrupted on localhost图像在 localhost 上显示已损坏
【发布时间】:2019-10-11 08:49:39
【问题描述】:

我对 c++ 和一般编程非常陌生。我只是想使用 opencv 读取图片并使用 boost asio 将其显示在 Web 服务器上。这是我对视频中的所有帧执行此操作之前的初始步骤。以下是我的代码 -

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <thread>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

using boost::asio::ip::tcp;
using namespace std;
using namespace cv;

int main(){
    try{
        boost::asio::io_service io_service;
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1112));

        for (;;){
            tcp::socket socket(io_service);
            acceptor.accept(socket);
            boost::system::error_code ignored_error;

            cv::Mat frame = cv::imread("x.jpg");
            vector<uchar> buff;
            vector<int> param = vector<int>(2);
            param[0]=cv::IMWRITE_JPEG_QUALITY;
            param[1]=95;
            imencode(".jpg",frame,buff,param);

            const char mess[] = "axaxaxaxasaaaaaaaaaaxax";

            std::string content(buff.begin(), buff.end());

            boost::asio::write(socket, boost::asio::buffer(content), boost::asio::transfer_all(), ignored_error);
            // boost::asio::write(socket, boost::asio::buffer(mess), boost::asio::transfer_all(), ignored_error);
        }
    }
    catch(std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
    return 0;
}

现在发送消息工作正常,但是当我尝试通过内容或 buff 发送图像时,它显示为乱码。我觉得这是因为在发送图片之前我没有发送任何有关图片的信息。但我不知道该怎么做。 或者也许我完全错了。任何帮助/建议将不胜感激。干杯!

【问题讨论】:

    标签: c++ networking webserver boost-asio


    【解决方案1】:

    我已经稍微简化了代码:

    #include <iostream>
    #include <string>
    #include <boost/asio.hpp>
    #include <opencv2/opencv.hpp>
    
    using boost::asio::ip::tcp;
    
    int main(){
        try{
            boost::asio::io_service io_service;
            tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1112));
    
            for (;;){
                tcp::socket socket(io_service);
                acceptor.accept(socket);
    
                cv::Mat frame = cv::imread("x.jpg");
                std::vector<uchar> buff;
                imencode(".jpg", frame, buff, std::vector<int> { cv::IMWRITE_JPEG_QUALITY, 95 });
    
                boost::system::error_code err;
                auto bytes_transferred = boost::asio::write(socket, boost::asio::buffer(buff), boost::asio::transfer_all(), err);
    
                std::cout << "Written: " << bytes_transferred << " (" << err.message() << ")\n";
            }
        }
        catch(std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }
    

    (具体来说,不要不必要地使用using namespace,不要不必要地复制到 std::string 中,也不要不必要地忽略错误代码)

    用它编译

    g++ test.cpp -L/usr/local/lib -pedantic -Wall -Wextra -pthread -lope^Cv_{core,imgproc,imgcodecs} -lboost_{system,thread} -o test.exe
    

    将样本 jpeg 复制为 x.jpg,在终端中运行:

    ./test.exe
    

    然后使用netcat读取结果:

    netcat localhost 1112 > verify.jpg
    

    服务器进程每次都会打印相同的消息:

    Written: 6130 (Success)
    

    (6130 字节恰好是我选择的测试图像的 95% 重新编码大小)。生成的图像 (verify.jpg) 在我的图像查看器中看起来不错。

    结论

    我认为代码可能没问题(但请检查上面的改进),您可能一直在错误地测试结果。

    【讨论】:

    • 嘿。感谢您简化代码。对我来说有点学习经验。我下载了 netcat 并在原始代码上运行它(因为我无法编译简化的代码('找不到 -lope^Cv))以获得 verify.jpg。它看起来像原始图片。但是,在浏览器中,它仍然显示为一堆随机字符。知道为什么会这样吗?
    • 更新:能够运行简化的代码。但是在浏览器中显示图片的问题依然存在。
    • 谢谢。我只需要一个大方向。我现在将尝试使用 POCO 完成我的任务,之后我将看看 Beast。干杯!
    • 顺便说一句,您现在发布了重复的问题,并且不接受答案。这看起来有点像你只是想让人们为你更加努力地工作。这不是该网站的工作方式。您只需从基础开始,遇到困难时来这里寻求帮助。现在,您了解“什么是 HTTP 响应”的基础知识:developer.mozilla.org/en-US/docs/Web/HTTP/Messages
    • 接受也是我的一个错误。道歉。在确定它帮助我解决问题之前,我接受了答案。以后我会更加注意。谢谢你的帮助。如有任何不便,我们深表歉意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2013-09-13
    • 1970-01-01
    • 2016-09-08
    • 2017-06-23
    • 2017-12-07
    • 1970-01-01
    相关资源
    最近更新 更多