Exported image not what I expected

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
crancran
Greenskin
Posts: 138
Joined: Wed May 05, 2010 3:36 pm
x 6

Exported image not what I expected

Post by crancran »

I am attempting to create an Ogre::Image2 instance where I set per-pixel a value in the range [0; 1]. In my test program, I am constructing a very simple 2x2 image and I am attempting to set the top-left pixel to white and leave the other pixels untouched:

Code: Select all

auto width =2u, height = 2u; // 2x2 
auto format = Ogre::PFG_R8_UNORM; // single channel greyscale
auto size = Ogre::PixelFormatGpuUtils::calculateSizeBytes( width, height, 1u, 1u, format, 1u );

// make sure the entire image starts black
auto *data = OGRE_MALLOC_SIMD( size, Ogre::MEMCATEGORY_RESOURCE );
memset( data, 0, size );

Ogre::Image2 image;
image.loadDynamicImage( data, width, height, 1u, Ogre::TextureTypes::Type2D, format, true, 0u );

// Set single pixel color
Ogre::TextureBox box = image.getData( 0u );
box.setColourAt( Ogre::ColourValue::White, 0, 0, 0u, format );

image.save( "heightmap.jpg", 0u, 0u );
Instead the code renders a 2x2 image like as follows, taken from GIMP:

Image

Can anyone spot or explain what I am doing wrong here?
crancran
Greenskin
Posts: 138
Joined: Wed May 05, 2010 3:36 pm
x 6

Re: Exported image not what I expected

Post by crancran »

If I actually explicitly set each of the 4 pixels and export the image as a GIF, then I get the expected outcome, so why doesn't JPEG?

For context, the end goal here is to feed an array of floats that represent a heightfield into a texture to build a heightmap. I want to then use this texture in conjunction with a predefined grid and base position in world space to calculate the vertices on the GPU rather than build a VBO for each tile in the grid since the layout of the vertices are consistent based on LoD. What I expected to see at the end is something like:

Image

I am populating an outter band of 9x9 vertex heights interwoven with a band of 8x8 vertex heights. When at the highest level of detail, both height bands will be used but when at a lower level of detail, only the 9x9 outter heights will be sampled.

I just can't understand then why applying the same algorithm to JPEG I get a slightly different result (notice the pixels to the bottom left are different)

Image
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Exported image not what I expected

Post by dark_sylinc »

Try a row alignment of 4 (last parameter to calculateSizeBytes)

The other possibility is that exporting as jpg is not functioning as expected, because you're passing a greyscale format and JPG tends to use 24-RGB colour format.

It's possible our FreeImageCodec2::encodeBitmap implementation does not properly handle this case where FreeImage's backend (JPG) cannot handle 8-bit precision and needs to be converted to 24-RGB.

Try PNG which natively supports greyscale 8-bit and is lossless.

Also please note that JPG is a lossy format, therefore even if everything is correct, you're not guaranteed to get 100% exact output; sometimes the divergence can be quite large. See DXT compression explained "It is clear the resulting interpolated colours not match the originals at all". This is for DXT aka BCn compression, which works quite different from JPG, however JPG also works on macroblocks and can have these edge cases (not as bad as DXT, but still bad).
Rollinger
Gnoblar
Posts: 1
Joined: Fri Dec 13, 2019 11:17 am

Re: Exported image not what I expected

Post by Rollinger »

I had no idea JPG was notorious for output loss. Should it be avoided?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Exported image not what I expected

Post by dark_sylinc »

Rollinger wrote: Sat Dec 14, 2019 12:01 pmI had no idea JPG was notorious for output loss. Should it be avoided?
Normally yes. Most "lossy" format should be avoided unless that's intended or has been evaluated (e.g. have strict size requirements or you're using it to stream content from GPU to disk or network, e.g. youtube streaming)
Post Reply