首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenExr、Swig和Java

OpenExr、Swig和Java
EN

Stack Overflow用户
提问于 2012-05-25 14:34:10
回答 2查看 853关注 0票数 0

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

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

H文件:

代码语言:javascript
复制
#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文件:

代码语言:javascript
复制
#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结构:

代码语言:javascript
复制
#include <half.h>

#ifndef RGBASTRUCT_H
#define RGBASTRUCT_H

struct Rgba{

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

#endif

Swig接口文件:

代码语言:javascript
复制
/* 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测试程序:

代码语言:javascript
复制
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();
        }
    }
  }
}

就像我说的,这是有效的,但我得到的不是像素数据,而是每个像素的数据:

代码语言:javascript
复制
r: SWIGTYPE_p_half@6b8741 || g: SWIGTYPE_p_half@17cfa2a || b: SWIGTYPE_p_half@c0a52 || a: SWIGTYPE_p_half@79c3e2

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

现在的问题是,Swig不知道如何将ILM half数据类型转换为Java数据类型。首先,我尝试将浮点值存储在Rgba-struct中,因为Swig知道如何转换这些浮点值。因此,根据OpenExr文档,将half转换为float应该没有问题,但每次我尝试这样做:

代码语言:javascript
复制
half a = newPixels[i][j].r;
float b = a;

我从VS收到一条错误消息,上面写着:

代码语言:javascript
复制
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数据类型?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-01 00:50:15

我找到了一个适合我的解决方案。在我添加了预处理器宏之后:

OPENEXR_DLL和PLATFORM_WINDOWS

在Visual Studio中,我能够将半个值转换为浮点数,然后swig将它们转换为正确的java数据类型。

票数 0
EN

Stack Overflow用户

发布于 2012-05-25 23:04:25

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

代码语言:javascript
复制
%include "half.h"

并且您应该可以访问类型half

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10749608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档