2012-05-25 140 views
0

我試圖創建一個解決方案,讓我在Java中讀取的OpenEXR圖像,並使用像素數據在JOGL紋理。由於在Java中沒有免費的OpenEXR庫(即正在工作並沒有發現什麼),我的想法是寫利用ILM的OpenEXR庫中的小C++程序,並痛飲包裹它,所以我可以使用JNI來加載和使用DLL中Java的。OpenEXR的,痛飲和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 sturct:

#include <half.h> 

#ifndef RGBASTRUCT_H 
#define RGBASTRUCT_H 

struct Rgba{ 

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

#endif 

的痛飲接口文件:

/* 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測試程序:

​​

就像我說的,這是工作,但不是像素數據我得到這個對於每個像素:

r: [email protected] || g: [email protected] || b: [email protected] || a: [email protected] 

最初的想法是,我必須複製將某些點的像素數據放入Java緩衝區以在JOGL中使用它。所以我寫了getScruct(int i,int j)方法來獲取一個像素的rgba數據並儘可能簡化JNI接口。

現在的問題是,痛飲不知道如何將ILM半數據類型轉換爲Java數據類型。起初我試圖將浮點值存儲在Rgba結構中,因爲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,它是我第一次與痛飲和JNI工作,我是絕對有不知道如何解決這個問題。

因此,沒有人知道如何解決這個問題,所以我可以得到的像素數據到Java數據類型?

回答

0

我發現我工作的解決方案。之後,我加入了預處理宏:

OPENEXR_DLL和 PLATFORM_WINDOWS

在Visual Studio中,我能夠在半值鑄造成浮動和痛飲將它們轉換成正確的Java數據類型。

1

這是因爲half結構不爲SWIG定義。嘗試包括與

%include "half.h" 

頭文件,你應該得到進入式半

+0

感謝您的幫助,但我從這裏得到的是swig無法找到half.h文件的錯誤消息。唯一可行的選擇似乎是在界面文件的標題部分中添加#include (相應地swig doc)。而且我還不確定這是否能解決我的問題,除非swig自動將openExr一半封裝到java浮點數中。 – Scyla

+0

你應該給予swig相同的包含標誌,它給了C編譯器(-I ) –