0

Java で OpenExr イメージを読み取り、JOGL でテクスチャのピクセル データを使用できるようにするソリューションを作成しようとしています。Javaには無料のOpenExrライブラリがないため(機能しているものは何も見つかりませんでした)、ILM OpenExrライブラリを利用して小さなc ++プログラムを作成し、Swigでラップして、JNIを使​​用してdllをロードして使用できるようにすることを考えましたジャバ。

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 インターフェイス ファイル:

/* 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) メソッドを作成して、1 ピクセルの rgba データを取得し、JNI インターフェイスをできるだけシンプルに保ちました。

問題は、Swig が ILM ハーフ データ型を Java データ型に変換する方法を認識していないことです。Swig は float 値を変換する方法を知っているので、最初は float 値を Rgba-struct に格納しようとしました。したがって、半分をフロートに変換する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" (?_toFloat@half@@0QBTuif@1@B)

私が思いついた他の解決策は、Swig typemap を使用し、ラッパーに ILM の半分を Java float に変換するように指示することでしたが、これが可能かどうかはわかりません。

私は C++ と VS についてほとんど知らず、Swig と JNI を扱うのは初めてなので、これを解決する方法がまったくわかりません。

それで、ピクセルデータをJavaデータ型に変換できるように、これを解決する方法を知っている人はいますか?

4

2 に答える 2

1

これは、halfSWIG の構造が定義されていないためです。ヘッダーファイルをインクルードしてみてください

%include "half.h"

タイプハーフにアクセスする必要があります

于 2012-05-25T15:04:25.467 に答える
0

自分に合った解決策を見つけました。プリプロセッサ マクロを追加した後:

OPENEXR_DLL と PLATFORM_WINDOWS

Visual Studio では、半分の値を float にキャストすることができ、swig はそれらを正しい Java データ型に変換します。

于 2012-05-31T16:50:15.037 に答える