gpt4 book ai didi

java - OpenExr、Swig 和 Java

转载 作者:行者123 更新时间:2023-12-01 15:22:06 26 4
gpt4 key购买 nike

我尝试创建一个解决方案,允许我在 Java 中读取 OpenExr 图像并在 JOGL 中使用纹理的像素数据。因为 Java 中没有免费的 OpenExr 库(没有找到任何有效的东西),所以我的想法是利用 ILM OpenExr 库编写一个小型 C++ 程序,并用 Swig 包装它,这样我就可以使用 JNI 来加载和使用 dll Java。

我构建了 OpenExr 库并在 Visual Studio 2005 中设置了 Swig。它已经创建了一个 dll,允许我获取图像的尺寸,因此我猜测工具链运行正常。

.h 文件:

#include <ImfRgbaFile.h>
#include <ImathBox.h>
#include <ImathVec.h>
#include <ImfRgba.h>
#include <ImfArray.h>
#include <iostream>
#include "String.h"
#include "RgbaStruct.h"

using namespace std;

class OpenExrReader {

private:
int width;
int height;
Imf::Array2D<Imf::Rgba> newPixels;
Rgba rgba;

public:

//constructor
OpenExrReader::OpenExrReader();
//destructor
OpenExrReader::~OpenExrReader();
//methods
int OpenExrReader::readExrFile(const char *filePath);
int OpenExrReader::getHeight();
int OpenExrReader::getWidth();
Rgba OpenExrReader::getScruct(int i, int j);
};

cpp文件:

#include "OpenExrReader.h"

OpenExrReader::OpenExrReader() {

width = 0;
height = 0;
}

OpenExrReader::~OpenExrReader() {

}

int OpenExrReader::readExrFile(const char *filePath) {

const char* fileName = filePath;

try {

Imf::RgbaInputFile file(fileName);
Imath::Box2i dw = file.dataWindow();
Imath::V2i dim(dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1);

width = dw.max.x - dw.min.x + 1;
height = dw.max.y - dw.min.y + 1;

newPixels.resizeErase(height, width);

int dx = dw.min.x;
int dy = dw.min.y;

file.setFrameBuffer(&newPixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
file.readPixels(dw.min.y, dw.max.y);
}
catch (Iex::BaseExc &e) {

std::cerr << e.what() << std::endl;
}

return 0;
}

int OpenExrReader::getHeight() {

return height;
}

int OpenExrReader::getWidth() {

return width;
}

Rgba OpenExrReader::getScruct(int i, int j) {

struct Rgba rgba = {newPixels[i][j].r,
newPixels[i][j].g,
newPixels[i][j].b,
newPixels[i][j].a};

return rgba;
}

Rgba 结构:

#include <half.h>

#ifndef RGBASTRUCT_H
#define RGBASTRUCT_H

struct Rgba{

half r;
half g;
half b;
half a;
};

#endif

Swig 接口(interface)文件:

/* File : OpenExrReader.i */
%module OpenExrReaderDll

%{
/* Put header files here or function declarations like below */
#include "OpenExrReader.h"
#include "RgbaStruct.h"
%}
%include "OpenExrReader.h"
%include "RgbaStruct.h"

Java测试程序:

public class OpenExrReaderMain {

static {

System.loadLibrary("OpenExrReader");
}

/**
* @param args
*/
public static void main(String[] args) {

OpenExrReader reader = new OpenExrReader();
reader.readExrFile("C:\\path\\someExrFile.exr");

int height = reader.getHeight();
int width = reader.getWidth();

for(int i = 0; i < height; i++) {

for(int j = 0; j < width; j++) {

Rgba rgba = reader.getScruct(i, j);

SWIGTYPE_p_half r = rgba.getR();
SWIGTYPE_p_half g = rgba.getG();
SWIGTYPE_p_half b = rgba.getB();
SWIGTYPE_p_half a = rgba.getA();

System.out.print("r: " + r + " || ");
System.out.print("g: " + g + " || ");
System.out.print("b: " + b + " || ");
System.out.print("a: " + a);
System.out.println();
}
}
}
}

就像我说的,这是有效的,但我不是为每个像素获取像素数据:

r: SWIGTYPE_p_half@6b8741 || g: SWIGTYPE_p_half@17cfa2a || b: SWIGTYPE_p_half@c0a52 || a: SWIGTYPE_p_half@79c3e2

最初的想法是我必须在某个时刻将像素数据复制到 Java 缓冲区中才能在 JOGL 中使用它。因此我编写了 getScruct(int i, int j) 方法来获取一个像素的 rgba 数据并保持 JNI 接口(interface)尽可能简单。

现在的问题是 Swig 不知道如何将 ILM half 数据类型转换为 Java 数据类型。起初,我尝试将浮点值存储在 Rgba 结构中,因为 Swig 知道如何转换这些值。根据 OpenExr 文档,将一半转换为 float 应该没有问题,但每次我尝试这样的操作时:

half a = newPixels[i][j].r;
float b = a;

我从 VS 收到一条错误消息,内容如下:

OpenExrReader.obj : error LNK2001: unresolved external symbol "private: static union half::uif const * const half::_toFloat" (?_toFloat@half@@0QBTuif@1@B)

我想到的另一个解决方案是使用 Swig 类型映射并告诉包装器将 ILM 一半转换为 Java float ,但我不确定这是否可能。

因为我对c++和VS知之甚少,而且这是我第一次使用Swig和JNI,所以我完全不知道如何解决这个问题。

那么,有谁知道如何解决这个问题,以便我可以将像素数据转换为 java 数据类型?

最佳答案

这是因为 half 结构没有为 SWIG 定义。尝试包含头文件

%include "half.h"

你应该可以访问半个类型

关于java - OpenExr、Swig 和 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10749608/

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