• OpenEXR的读取机制


    这还是一篇学习笔记,知识重点还是领会完再敲一遍比较好。

    OpenEXR通过RgbaInputFile这个接口读取RGBA ONLY图像文件信息,该接口通过dataWindow()方法获取图像边界坐标信息,通过该边界坐标信息即可计算出图像的heigth及width。

    此时的图像文件的数据还未以OpenEXR标准的方式存储,OpenEXR是如何将这些数据标准化的呢?首先定义一个Array2D<Rgba>的模板&pixels,pixels是一个数组的引用,然后通过pixels.resizeErase(height,width)将该数组与图像数据统一,设定该数组的宽高格式,pixels.resizeErase(height,width)就等于是在内存上为该数组分配了一个额定大小的空间,该数组的宽高与图像的宽高一致。

    下一步就是将pixels的每一个元素与图像中的每一个像素建立映射关系了。通过file.setFrameBuffer(pixels,1,width),可以为每一个图像像素建立一个指针,该指针存储于pixels数组中,并且这些地址是连续的。当我们想访问图像数据某一部分时,我们就可以通过访问这个数组中的指针来完成了。例如:pixels[x][y]就可以获得一个坐标为(x,y)的像素的指针地址。这样做既保护了图像数据的原始性,又提高了访问的灵活性。OpenEXR的设计确实到位。当然这种设计跟OpenGL也是如出一辙的~

    接下来就是通过对file.readPixels(dw.min.y,dw.max.y)来调用并将高度在dw.min.y和dw.max.y之间的像素拷贝到buffer中了。由于数组中记录的地址是连续的,这样的设计更适合cpu的多级缓冲特质,这也是图像能够被高效处理的一个保证。

    以上是OpenEXR的RgbaInputFile接口的最简单的使用。在实际工作中,我们只想观看图像的某一部分,这时候就需要利用OpenEXR成族访问的特点了。

    在Reading an RGBA Image File in Chunks这个单元中给出了这样的例子:

    void
    readRgba2 (const char fileName[])
    {
        RgbaInputFile file (fileName);
        Box2i dw = file.dataWindow();
        int width = dw.max.x - dw.min.x + 1;
        int height = dw.max.y - dw.min.y + 1;
        Array2D<Rgba> pixels (10, width);
        while (dw.min.y <= dw.max.y)
        {
            file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y * width,1, width);
            file.readPixels (dw.min.y, min (dw.min.y + 9, dw.max.y));// processPixels (pixels)
            dw.min.y += 10;
        }
    }

    下面分析这段代码:

    首先声明一个RgbaInputFile函数,函数结构体中首先定义一个名为file的RgbaInputFile类用于读取图像信息。

    然后定义一个名为dw的Box2i对象,该对象通过dataWindow()方法获取图像的边界信息。

    通过边界信息进而计算得出图像的宽高。

    用Array2D<>模板定义了一个应用于Rgba结构体的数组。该数组名为pixels。同时我们注意到,该数组的高度范围只有10,也就是说该数组只存储十行图像数据。这与之前建立一个储存全部行的数组不一样。现在建立的数组明显占用更小的储存空间,存入到buffer中更具灵活性。也就是说cpu缓存机制并不是那么强大的电脑依然可以很轻松的使用RgbaInputFile接口。
    之后一段代码引入了一个非常精妙的while循环,这个循环很有意思。dw.min.y这个值是可以修改的,在循环句尾有这样一句:dw.min.y+=10,更新一下while语句中的判断条件,同时也可以保证pixels在每一次循环中递归的为图像中的十行像素分配地址,不得不感叹ILM的工程师功力深厚。

    以上。

  • 相关阅读:
    WPF获取分辨率2
    怎样将UNIX Shell作为Concurrent Program来运行
    转 FRM40654 Record has been updated Requery block to see change
    各模组相关interface
    EBS 表后缀的含义
    Oracle Form開發Form消息提示
    EBS多组织(OU
    EBS 开发基础知识
    FORM:在不同窗口中传递参数
    AR 金额计算
  • 原文地址:https://www.cnblogs.com/hksac/p/4998251.html
Copyright © 2020-2023  润新知