Discussion:
[Openexr-user] Change Channel names
Aaron Carlisle
2015-12-11 19:02:53 UTC
Permalink
In the ChannelList::Iterator and ChannelList::ConsIterator name() is being
defined as a const char * name () const, which means I can't change the
name. Is there anyway around this? I just want to be able to change the
channel name. I tried converting name into a string then back into a const
char * which works, but I have significant data loss and the pixels no
longer show up in the image.
Peter Hillman
2015-12-14 01:15:46 UTC
Permalink
You cannot modify a channel name because the ChannelList object keeps
them sorted. If you wish to rename a channel within a list, you must
delete it and reinsert it with the new name, or else assemble a
completely new ChannelList containing the channels the way you want.

You may find the source of the multiview utility instructive:
https://github.com/openexr/openexr/blob/master/OpenEXR/exrmultiview/makeMultiView.cpp
That reads in channels from the input(s) and writes them out with
different names.
You could drop a channel from the output file by making these two lines
conditional:
header.channels().insert(outChanName, inChannel);
and
outFb.insert(outChanName,image.channel(outChanName).slice());
Post by Aaron Carlisle
In the ChannelList::Iterator and ChannelList::ConsIterator name() is
being defined as a const char * name () const, which means I can't
change the name. Is there anyway around this? I just want to be able
to change the channel name. I tried converting name into a string then
back into a const char * which works, but I have significant data loss
and the pixels no longer show up in the image.
_______________________________________________
Openexr-user mailing list
https://lists.nongnu.org/mailman/listinfo/openexr-user
Aaron Carlisle
2015-12-14 10:47:45 UTC
Permalink
You're awesome! Ill work with this today, and see where I get.

In addition to changing the channel names I also wanted to be able to combine the channel data from the rgb channels from each layer into one. In python I just created a dictionary, grouped the rgb channels and used array to convert them. So (customlayer.red, customlayer.blue, customlayer.green) became (newlayername.customchannelname(combined pixel data from red, green, blue)). In C++ it doesn't seem seem as simple. Do you have any suggestions for doing the same in C++?

Thanks again!!
Post by Peter Hillman
You cannot modify a channel name because the ChannelList object keeps
them sorted. If you wish to rename a channel within a list, you must
delete it and reinsert it with the new name, or else assemble a
completely new ChannelList containing the channels the way you want.
https://github.com/openexr/openexr/blob/master/OpenEXR/exrmultiview/makeMultiView.cpp
That reads in channels from the input(s) and writes them out with
different names.
You could drop a channel from the output file by making these two lines
header.channels().insert(outChanName, inChannel);
and
outFb.insert(outChanName,image.channel(outChanName).slice());
Post by Aaron Carlisle
In the ChannelList::Iterator and ChannelList::ConsIterator name() is
being defined as a const char * name () const, which means I can't
change the name. Is there anyway around this? I just want to be able
to change the channel name. I tried converting name into a string
then
Post by Aaron Carlisle
back into a const char * which works, but I have significant data
loss
Post by Aaron Carlisle
and the pixels no longer show up in the image.
_______________________________________________
Openexr-user mailing list
https://lists.nongnu.org/mailman/listinfo/openexr-user
------------------------------------------------------------------------
_______________________________________________
Openexr-user mailing list
https://lists.nongnu.org/mailman/listinfo/openexr-user
Peter Hillman
2015-12-15 07:03:39 UTC
Permalink
You could maybe extend the Image class using something like this pseudocode.
The ImageChannel class returns aslice() object that stores the image
layout: you can use that to access the pixels.
And by pseudocode I mean "untested C++":

template <classT>
void
TypedImageChannel<T>::operator+=(const TypedImageChannel<T> &other)
{

assert(image() == other.image());

IMF::Slice outSlice = slice();
IMF::Slice inSlice = other.slice();

assert(outSlice.xSampling == 1);
assert(outSlice.ySampling == 1);
assert(inSlice.xSampling == 1);
assert(inSlice.ySampling == 1);

for ( int y = image().dataWindow().min.y ; y <=
image().dataWindow().max.y ; ++y)
{
for( int x = image().dataWindow().min.x ; x <=
image().dataWindow().max.x; ++x)
{
* (T*) (outSlice.base + y*outSlice.yStride +
x*outSlice.xStride) += * (T*) (inSlice.base + y*inSlice.yStride +
x*inSlice.xStride);
}
}
}

You should then be able to merge channels by doing
image.typedChannel<half>(outChanName)+=image.typedChannel<half>(inChanName);
for each channel inChanName you want to add into outChanName before you
write out the image again, and assuming your channels are stored as half
floats.
I'm not sure if that's exactly what you need, but the nested 'for' loops
should give you an idea how to iterate over the pixels.

If you expect the tool to get more complex than this it may be worth
using a generic image processing library which supports OpenEXR instead.
Post by Aaron Carlisle
You're awesome! Ill work with this today, and see where I get.
In addition to changing the channel names I also wanted to be able to
combine the channel data from the rgb channels from each layer into
one. In python I just created a dictionary, grouped the rgb channels
and used array to convert them. So (customlayer.red
<http://customlayer.red>, customlayer.blue <http://customlayer.blue>,
customlayer.green <http://customlayer.green>) became
(newlayername.customchannelname(combined pixel data from red, green,
blue)). In C++ it doesn't seem seem as simple. Do you have any
suggestions for doing the same in C++?
Thanks again!!
You cannot modify a channel name because the ChannelList object
keeps them sorted. If you wish to rename a channel within a list,
you must delete it and reinsert it with the new name, or else
assemble a completely new ChannelList containing the channels the
way you want.
https://github.com/openexr/openexr/blob/master/OpenEXR/exrmultiview/makeMultiView.cpp
That reads in channels from the input(s) and writes them out with
different names.
You could drop a channel from the output file by making these two
header. channels (). insert (outChanName, inChannel);
and
outFb. insert (outChanName,image. channel (outChanName). slice ());
Post by Aaron Carlisle
In the ChannelList::Iterator and ChannelList::ConsIterator name()
is being defined as a const char * name () const, which means I
can't change the name. Is there anyway around this? I just want
to be able to change the channel name. I tried converting name
into a string then back into a const char * which works, but I
have significant data loss and the pixels no longer show up in
the image.
_______________________________________________
Openexr-user mailing list
https://lists.nongnu.org/mailman/listinfo/openexr-user
------------------------------------------------------------------------
Openexr-user mailing list
https://lists.nongnu.org/mailman/listinfo/openexr-user
Loading...