C++ 如果图像文件的内容在字符数组中,如何使用 cv::imdecode?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4271489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:59:10  来源:igfitidea点击:

How to use cv::imdecode, if the contents of an image file are in a char array?

c++opencv

提问by Richard Knop

I have a jpeg image in buffer jpegBuffer. I'm trying to pass it to cv::imdecode function:

我在缓冲区 jpegBuffer 中有一个 jpeg 图像。我试图将它传递给 cv::imdecode 函数:

Mat matrixJprg = imdecode(Mat(jpegBuffer), 1);

I get this error:

我收到此错误:

/home/richard/Desktop/richard/client/src/main.cc:108: error: no matching function for call to ‘cv::Mat::Mat(char*&)'

This is how I fill jpegBuffer:

这就是我填充 jpegBuffer 的方式:

FILE* pFile;
long lSize;
char * jpegBuffer;
pFile = fopen ("img.jpg", "rb");
if (pFile == NULL)
{
    exit (1);
}

// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file.
jpegBuffer = (char*) malloc (lSize);
if (jpegBuffer == NULL)
{
    exit (2);
}

// copy the file into the buffer.
fread (jpegBuffer, 1, lSize, pFile);

// terminate
fclose (pFile);

回答by ronag

Mat has no constructor that takes a char* argument. Try this instead:

Mat 没有接受 char* 参数的构造函数。试试这个:

std::ifstream file("img.jpg");
std::vector<char> data;

file >> std::noskipws;
std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(data));

Mat matrixJprg = imdecode(Mat(data), 1);

EDIT:

编辑:

You should also take a look at LoadImageM.

您还应该看看LoadImageM

If you have your data already in a char* buffer one way is to copy the data into an std::vector.

如果您的数据已经在 char* 缓冲区中,一种方法是将数据复制到 std::vector 中。

std::vector<char> data(buf, buf + size);

回答by Programmer

I had to do the-same thing and my image data was already in chararray format and was arriving from a network and a plugin source. The current answershows how to do this but it requires copying the data into a vector firstwhich is a waste of time and resources.

我不得不做同样的事情,我的图像数据已经是char数组格式,并且来自网络和插件源。当前的答案显示了如何做到这一点,但它需要先将数据复制到向量中,这会浪费时间和资源。

This is possible to do directly without creating a copy of it. You were so close with your imdecode(Mat(jpegBuffer), 1);code in your question.

这可以直接完成而无需创建它的副本。你imdecode(Mat(jpegBuffer), 1);在你的问题中与你的代码非常接近。

You need to use the constructor overload for the Matclass below:

您需要为Mat下面的类使用构造函数重载:

Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);

To create this Mat, pass 1to the rows, the size of the array to the cols, CV_8UC1to the type and the char array itself to the data param. Pass this Matto the cv::imdecodefunction with the mat as the first param and CV_LOAD_IMAGE_UNCHANGEDas the second param.

要创建这个Mat,传递1给行、数组的大小到列、CV_8UC1类型和字符数组本身到数据参数。将此传递Matcv::imdecode具有 mat 作为第一个参数和CV_LOAD_IMAGE_UNCHANGED第二个参数的函数。

Basic example:

基本示例

char *buffer = dataFromNetwork;
int bufferLength = sizeOfDataFromNetwork;

cv::Mat matImg;
matImg = cv::imdecode(cv::Mat(1, bufferLength, CV_8UC1, buffer), CV_LOAD_IMAGE_UNCHANGED);


Complete Example(Reads file named "test.jpg" into char array and uses imdecodeto decode the data from the char array then displays it):

完整示例(将名为“test.jpg”的文件读入字符数组并用于imdecode解码字符数组中的数据然后显示它):

int main() {

    //Open image file to read from
    char imgPath[] = "./test.jpg";
    ifstream fileImg(imgPath, ios::binary);
    fileImg.seekg(0, std::ios::end);
    int bufferLength = fileImg.tellg();
    fileImg.seekg(0, std::ios::beg);

    if (fileImg.fail())
    {
        cout << "Failed to read image" << endl;
        cin.get();
        return -1;
    }

    //Read image data into char array
    char *buffer = new char[bufferLength];
    fileImg.read(buffer, bufferLength);

    //Decode data into Mat 
    cv::Mat matImg;
    matImg = cv::imdecode(cv::Mat(1, bufferLength, CV_8UC1, buffer), CV_LOAD_IMAGE_UNCHANGED);

    //Create Window and display it
    namedWindow("Image from Char Array", CV_WINDOW_AUTOSIZE);
    if (!(matImg.empty()))
    {
        imshow("Image from Char Array", matImg);
    }
    waitKey(0);

    delete[] buffer;

    return 0;
}