二进制打开和复制图像文件 c++

Binary open and copy image file c++

本文关键字:图像 文件 c++ 复制 二进制      更新时间:2023-10-16

我想将一个图像文件复制到另一个新文件。这是我执行此操作的方法:

    std::ofstream myOutpue;
    std::ifstream mySource;
    //int i = 0;
    mySource.open(ofn.lpstrFile, std::ios::binary);
    myOutpue.open("im4.jpg", std::ios::binary);
    char buffer;
    char bufferToSave[100];
    if (mySource.is_open())
    {
        //client->sendFilePacket(FileStates::START_SAVE, buffer, false,i);
        i++;
        while (!mySource.eof())
        {
            mySource >> std::noskipws >> buffer;
            myOutpue << buffer;
            //client->sendFilePacket(FileStates::CONTINUE_SAVE, buffer, false,i);
            i++;
        }
    }
    i++;
    //client->sendFilePacket(FileStates::END_SAVE, buffer, true,i);
    mySource.close();
    //myOutpue.close();

此方法工作正常,但我的问题是我想复制 char/bit 并将其发送到另一个客户端。当我通过每个字符执行此操作时,无法正常工作,因此我想制作一个更大的buffor(例如char t[512])或类似的东西并将它们复制到新文件中。

我尝试这样做:

    std::ofstream myOutpue;
    std::ifstream mySource;
    mySource.open(ofn.lpstrFile, std::ios::binary);
    myOutpue.open("im4.jpg", std::ios::binary);
    char buffer;
    char bufferToSave[100];
    if (mySource.is_open())
    {
        //client->sendFilePacket(FileStates::START_SAVE, buffer, false,i);
        i++;
        while (!mySource.eof())
        {
            if (i == 100)
            {
                for (int i = 0; i < 100; i++)myOutpue << bufferToSave[i];
                i = 0;
            }
            mySource >> std::noskipws >> buffer;
            bufferToSave[i] = buffer;
            //myOutpue << buffer;
            //client->sendFilePacket(FileStates::CONTINUE_SAVE, buffer, false,i);
            i++;
        }
    }
    i++;
    //client->sendFilePacket(FileStates::END_SAVE, buffer, true,i);
    mySource.close();
    myOutpue.close();

但是我得到的图像我无法打开。

所以我的问题是如何读取文件以从中获取更多位,并为我创建与原始图像相同的图像。

原始文件复制算法中存在错误,永远不应使用 eof() 作为结束标志进行循环。

请参阅:为什么循环条件中的 iostream::eof 被认为是错误的?

复制文件可以很简单,如下所示:

    std::ofstream("output.jpg", std::ios::binary) << std::ifstream("input.jpg", std::ios::binary).rdbuf();

它在传递std::istream缓冲区时使用输出运算符的特殊重载(使用 rdbuf() )。它复制整个流。

读取整个缓冲区时,应使用std::istream::read

    std::ifstream ifs("input.jpg", std::ios::binary)
    char buffer[1025]; // create a buffer
    // keep going as long as the reading succeeds
    while(ifs.read(buffer, sizeof(buffer)))
    {
        // ifs.gcount() is the number of chars read successfully
        client->sendFilePacket(buffer, ifs.gcount()); // send all bytes
    }
我知道

已经很长时间了,但是阅读这些主题我找到了解决方案:

    std::ifstream ifs(ofn.lpstrFile, std::ios::binary);
    std::ofstream myOutpue;
    char buffer[1024]; // create a buffer
    myOutpue.open("output.jpg", std::ios::binary);
    //client->sendFilePacket(FileStates::START_SAVE, buffer, false, i);
    while (ifs.read(buffer, sizeof(buffer)))
    {
        myOutpue.write(buffer, ifs.gcount());
    }
    //
    myOutpue.write(buffer, ifs.gcount());
    myOutpue.close();

注意:我的答案类似于@dawcza94,但为了避免黑屏,循环后您必须保存其余的读数,因为在循环中您只保存适合缓冲区的内容,其余部分您忽略。有时,其余部分可能只有几个字符长,看起来图像的大小相同,但事实并非如此。

注意2:我在这里发帖是为了帮助那些仍然像我一样陷入困境的人!!

C++ FAQ:

您可能希望使用 iostream 的 read() 和 write() 方法,而不是它的>> 和 <<运算符。 read() 和 write() 更适合二进制模式;>> 和 <<更适合文本模式。

您可以指定要read多少。通过gcount您可以询问成功读取了多少字符。write也是如此。

我尝试使用以下代码:

    std::ifstream ifs(ofn.lpstrFile, std::ios::binary);
    std::ofstream myOutpue;
    char buffer[1024]; // create a buffer
    myOutpue.open("output.jpg", std::ios::binary);
    //client->sendFilePacket(FileStates::START_SAVE, buffer, false, i);
    while (ifs.read(buffer, sizeof(buffer)))
    {
        //client->sendFilePacket(FileStates::CONTINUE_SAVE, buffer, false, ifs.gcount());
        myOutpue.write(buffer, ifs.gcount());
    }
    //client->sendFilePacket(FileStates::END_SAVE, buffer, true, i);
    myOutpue.close();

但是当我这样做时,在我的图像副本中,我只得到了原始图像的一半和黑屏的一半(kb的数量与原始文件中相同),所以我不知道这有什么问题?

不要使用"手动"复制,而是尝试使用 ifstream::read 方法