openexr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Openexr-devel] Writing OpenEXR file, one scanline at a time


From: Nicholas Yue
Subject: [Openexr-devel] Writing OpenEXR file, one scanline at a time
Date: Tue, 23 Jun 2015 16:21:23 -0700

Hi,

  I have having difficult working out the correct stride logic to write one scanline at a time to an OpenEXR file.

  The example code shows write the entire array in memory but I only have access to a single scanline at a time.

  I want to minimize the memory usage by not storing the entire image before writing.

  Here is the code.

  Thanks in advance.

#include <stdio.h>
#include <string>
#include <OpenEXR/ImfOutputFile.h>
#include <OpenEXR/ImfArray.h>
#include <OpenEXR/ImfCompression.h>
#include <OpenEXR/ImfChannelList.h>
#include <OpenEXR/ImfRgba.h>

// This is currently NOT working but would be a useful example to have

void writeIncrementalScanline (const std::string& fileName,
  int width,
  int height)
{
float pixelAspectRatio = 1;
const Imath::V2f screenWindowCenter = Imath::V2f (0, 0);
float screenWindowWidth = 1;
Imf::LineOrder lineOrder = Imf::INCREASING_Y;
Imf::Compression compression = Imf::ZIPS_COMPRESSION;
Imf::Header header(width, height,
  pixelAspectRatio,
  screenWindowCenter,
  screenWindowWidth,
  lineOrder,
  compression);

header.channels().insert("rgba.R",Imf::Channel(Imf::HALF));
header.channels().insert("rgba.G",Imf::Channel(Imf::HALF));
header.channels().insert("rgba.B",Imf::Channel(Imf::HALF));
header.channels().insert("rgba.A",Imf::Channel(Imf::HALF));
Imf::OutputFile file (fileName.c_str(), header);
Imf::FrameBuffer framebuffer;

Imf::Array2D<half> redBuffer(width,1);
Imf::Array2D<half> greenBuffer(width,1);
Imf::Array2D<half> blueBuffer(width,1);
Imf::Array2D<half> alphaBuffer(width,1);
half colorChannelGreyScaleDelta = 1.0f/float(height-1);
std::cout << "colorChannelGreyScaleDelta = " << colorChannelGreyScaleDelta << std::endl;
std::cout << "height * colorChannelGreyScaleDelta = " << height * colorChannelGreyScaleDelta << std::endl;


size_t xStride = sizeof(half) * 1;
size_t yStride = width;

const half *redPixels   = &redBuffer[0][0];
const half *greenPixels = &greenBuffer[0][0];
const half *bluePixels  = &blueBuffer[0][0];
const half *alphaPixels = &alphaBuffer[0][0];

framebuffer.insert("rgba.R",
  Imf::Slice(Imf::HALF,
 (char *)redPixels,
 xStride,
 yStride));
framebuffer.insert("rgba.G",
  Imf::Slice(Imf::HALF,
 (char *)greenPixels,
 xStride,
 yStride));
framebuffer.insert("rgba.B",
  Imf::Slice(Imf::HALF,
 (char *)bluePixels,
 xStride,
 yStride));
framebuffer.insert("rgba.A",
  Imf::Slice(Imf::HALF,
 (char *)alphaPixels,
 xStride,
 yStride));


for (int h=0;h<height;h++)
{
half grey_scale_value = colorChannelGreyScaleDelta * h;
for (int w=0;w<width;w++)
{
redBuffer[w][0]   = 1.;//grey_scale_value;
greenBuffer[w][0] = 1.;//grey_scale_value;
blueBuffer[w][0]  = 1.;//grey_scale_value;
alphaBuffer[w][0] = 1.;
}

file.setFrameBuffer(framebuffer);
file.writePixels();

}
}

int main()
{
    const std::string fileName("IncrementalScanline.exr");

    const int width = 256;
    const int height = 512;
    writeIncrementalScanline (fileName, width, height);

    return 0;
}

Cheers
--
Nicholas Yue


reply via email to

[Prev in Thread] Current Thread [Next in Thread]