gpt4 book ai didi

c++ - 将 exr/pfm 保存为小端

转载 作者:行者123 更新时间:2023-11-28 04:03:03 37 4
gpt4 key购买 nike

我将一个 bmp 文件加载到一个 CImg 对象中,并将它保存到 pfm 文件中。成功的。我将这个 .pfm 文件用于另一个库,但是这个库不接受大端,只接受小端

    CImg<float> image;
image.load_bmp(_T("D:\\Temp\\memorial.bmp"));
image.normalize(0.0, 1.0);
image.save_pfm(_T("D:\\Temp\\memorial.pfm"));

那么,如何将bmp 文件保存为pfm 文件little endian不是 big endian。 .这可能吗?

稍后编辑:

我检查了 .pfm 头文件中的前 5 个元素。这是没有invert_endianness的结果:

CImg<float> image;
image.load_bmp(_T("D:\\Temp\\memorial.bmp"));
image.normalize(0.0, 1.0);
image.save_pfm(_T("D:\\Temp\\memorial.pfm"));

PF
512
768
1.0
=øøù=€€=‘>

这是invert_endianness的结果:

CImg<float> image;
image.load_bmp(_T("D:\\Temp\\memorial.bmp"));
image.invert_endianness();
image.normalize(0.0, 1.0);
image.save_pfm(_T("D:\\Temp\\memorial.pfm"));

PF
512
768
1.0
?yôx?!ù=‚ì:„ç‹?

结果是一样的。

最佳答案

这绝对不是一个正确的答案,但暂时可以作为一种解决方法。

我没有找到如何使用 CImg 的函数正确地反转字节顺序,所以我修改了生成的文件。这是一个黑客。结果在 GIMP 中打开很好,看起来非常接近原始图像,但我不能说它是否适用于您正在使用的库。可能值得一试。

代码中的注释:

#include "CImg/CImg.h"

#include <algorithm>
#include <filesystem> // >= C++17 must be selected as Language Standard
#include <ios>
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>

using namespace cimg_library;
namespace fs = std::filesystem;

// a class to remove temporary files
class remove_after_use {
public:
remove_after_use(const std::string& filename) : name(filename) {}
remove_after_use(const remove_after_use&) = delete;
remove_after_use& operator=(const remove_after_use&) = delete;

const char* c_str() const { return name.c_str(); }
operator std::string const& () const { return name; }

~remove_after_use() {
try {
fs::remove(name);
}
catch (const std::exception & ex) {
std::cerr << "remove_after_use: " << ex.what() << "\n";
}
}
private:
std::string name;
};

// The function to hack the file saved by CImg
template<typename T>
bool save_pfm_endianness_inverted(const T& img, const std::string& filename) {
remove_after_use tempfile("tmp.pfm");

// get CImg's endianness inverted image and save it to a temporary file
img.get_invert_endianness().save_pfm(tempfile.c_str());

// open the final file
std::ofstream os(filename, std::ios::binary);

// read "tmp.pfm" and modify
// The Scale Factor / Endianness line
if (std::ifstream is; os && (is = std::ifstream(tempfile, std::ios::binary))) {
std::string lines[3];
// Read the 3 PFM header lines as they happen to be formatted by
// CImg. Will maybe not work with another library.
size_t co = 0;
for (; co < std::size(lines) && std::getline(is, lines[co]); ++co);

if (co == std::size(lines)) { // success
// write the first two lines back unharmed:
os << lines[0] << '\n' << lines[1] << '\n';

if (lines[2].empty()) {
std::cerr << "something is wrong with the pfm header\n";
return false;
}

// add a '-' if it's missing, remove it if it's there:
if (lines[2][0] == '-') { // remove the - to invert
os << lines[2].substr(1);
}
else { // add a - to invert
os << '-' << lines[2] << '\n';
}

// copy all the rest as-is:
std::copy(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>{},
std::ostreambuf_iterator<char>(os));
}
else {
std::cerr << "failed reading pfm header\n";
return false;
}
}
else {
std::cerr << "opening files failed\n";
return false;
}
return true;
}

int main()
{
CImg<float> img("memorial.bmp");
img.normalize(0.f, 1.f);
std::cout << "saved ok: " << std::boolalpha
<< save_pfm_endianness_inverted(img, "memorial.pfm") << "\n";
}

关于c++ - 将 exr/pfm 保存为小端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59192684/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com