Я пытаюсь создать решение, которое позволяет мне читать образы OpenExr в Java и использовать пиксельные данные для текстур в JOGL. Поскольку в Java нет бесплатной библиотеки OpenExr (не нашел ничего, что работает), моя идея заключалась в том, чтобы написать небольшую программу на C++ с использованием библиотеки ILM OpenExr и обернуть ее Swig, чтобы я мог использовать JNI для загрузки и использования dll в Ява.OpenExr, Swig и Java
Я построил библиотеку OpenExr и установил Swig в Visual Studio 2005. Он уже создает DLL, которая позволяет мне получать размеры изображения, поэтому я предполагаю, что цепочка инструментов работает правильно.
двутавровой Файл:
#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);
};
СРР файл:
#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 sturct:
#include <half.h>
#ifndef RGBASTRUCT_H
#define RGBASTRUCT_H
struct Rgba{
half r;
half g;
half b;
half a;
};
#endif
Интерфейс Файл Swig:
/* 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: [email protected] || g: [email protected] || b: [email protected] || a: [email protected]
Первоначальная идея состояла в том, что я должен скопировать пиксельные данные в какой-то момент в буфер Java для использования в JOGL. Поэтому я написал метод getScruct (int i, int j), чтобы получить rgba-данные одного пикселя и максимально упростить интерфейс JNI.
Проблема в том, что Swig не знает, как преобразовать половинный тип данных ILM в тип данных Java. Сначала я попытался сохранить значения float в Rgba-struct, потому что Swig знает, как их преобразовать. Соответственно в OpenExr документ преобразования половина плавать не должно быть никаких проблем, но каждый раз, когда я пытаюсь что-то вроде этого:
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" ([email protected]@@[email protected]@B)
Другой soltuton что Я придумал использовать типовую карту Swig и сообщить обертке, чтобы преобразовать ILM наполовину в Java float, но я не уверен, что это возможно.
Потому что я очень мало знаю о C++ и VS, и это первый раз, когда я работаю с Swig и JNI. Я абсолютно не знаю, как это решить.
Итак, кто-нибудь знает, как решить эту проблему, чтобы я мог получить данные в виде java-данных?
Спасибо за помощь, но все, что я получаю, это сообщение об ошибке, которое swig не может найти файл half.h. Единственный жизнеспособный вариант, похоже, заключается в том, чтобы добавить #include в раздел заголовка файла интерфейса (в соответствии с документом swig). И я до сих пор не уверен, что это касается моей проблемы, если swig автоматически обматывает половину openExr в java-float. –
Scyla
Вы должны дать swig те же флаги включения, что и для компилятора C (с -I) –