2012-05-25 3 views
0

Я пытаюсь создать решение, которое позволяет мне читать образы 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-данных?

ответ

0

Я нашел решение, которое работает для меня.После того, как я добавил препроцессора макросы:

OPENEXR_DLL и PLATFORM_WINDOWS

в Visual Studio, я был в состоянии бросить на половину значения в поплавка и преобразует их SWIG в правильное Java типа данных.

1

Это потому, что для SWIG не определена структура half. Попробуйте включить заголовочный файл с

%include "half.h" 

и вы должны получить доступ к типу половине

+0

Спасибо за помощь, но все, что я получаю, это сообщение об ошибке, которое swig не может найти файл half.h. Единственный жизнеспособный вариант, похоже, заключается в том, чтобы добавить #include в раздел заголовка файла интерфейса (в соответствии с документом swig). И я до сих пор не уверен, что это касается моей проблемы, если swig автоматически обматывает половину openExr в java-float. – Scyla

+0

Вы должны дать swig те же флаги включения, что и для компилятора C (с -I ) –

Смежные вопросы