How to write 10 bit RGB to files

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
Nicola

How to write 10 bit RGB to files

Post by Nicola »

Hello again!

I'm using ImageMagick-6.5.3-3-Q16 with VC++ and want to write 10 bit RGB to files (actually DPX but even BMP does not work).
What I'm doing is:
1. reading an 8 bit BMP
2. extracting the image data to a char array
3. storing the char values in a short array
4. initializing an Magick::Image with the short array
5. writing the image
6. getting black images only :-(

The following code describes what I'm doing - resulting in BLACK IMAGES!

Code: Select all

          // Initialize ImageMagick install location for Windows
          Magick::InitializeMagick( argv[0] );

          Magick::Image cImageIn( "test.bmp" );
          // write image data to external char array => seems to work fine
          cImageIn.write( 0, 0, pcBmpBuffer->getWidth(), pcBmpBuffer->getHeight(), "BGR", MagickCore::CharPixel, pcBmpBuffer->getImage() );
          // write image data to BMP => works fine
          cImageIn.write( "test_IM.bmp" );
          // write image data to DPX => works fine
          cImageIn.write( "test_IM.dpx" );

          // convert char data to short data
          const int iRgbArraySize =  pcBmpBuffer->getImageBufferSize();
          short* psRgbImage = new short[ iRgbArraySize ];
          for( int iRow = 0; iRow < cDvsBuffer.getRows(); ++iRow )
          {
            for( int iCol = 0; iCol < cDvsBuffer.getCols(); ++iCol )
            {
              short* psDestPix = &psRgbImage[ iRow * 3 * cDvsBuffer.getCols() + iCol * 3 ];
              UChar* pucSrcPix = &pcBmpBuffer->getImage()[ iRow * 3 * cDvsBuffer.getCols() + iCol * 3 ];

              // char => short
              psDestPix1[ 0 ] = pucSrcPix[ 2 ]; // R
              psDestPix1[ 1 ] = pucSrcPix[ 1 ]; // G
              psDestPix1[ 2 ] = pucSrcPix[ 0 ]; // B
            }
          }

//          Magick::Blob cImageBlob( psRgbImage, iRgbArraySize * sizeof( short ) );
//          Magick::Image cMagickImage( cImageBlob, Magick::Geometry( cDvsBuffer.getCols(), cDvsBuffer.getRows() )/*, 10*/, "RGB" );
          Magick::Image cMagickImage(
            pcBmpBuffer->getWidth(),
            pcBmpBuffer->getHeight(),
            "RGB",
            Magick::ShortPixel,
            psRgbImage );

          // this returns exactly the pixel value I expect
          const MagickCore::PixelPacket* pcPP = cMagickImage.getConstPixels( 1000, 1000, 1920, 1080 );

          // write the image => result in a black image
          cMagickImage.write( "testOut.dpx" );

          // FOR TESTING: write also a BMP => result in a black image
          cMagickImage.write( "testOut.bmp" );
Any help to get the real images is appreciated :-)

Thanks in advance,
Nicola

EDIT: this is what identify says about the DPX - actually looking good. Especially, the histogram predicts more than a black image, I think :?
Image: C:\LargeFileConvRes-C\Take_01_Halbzeit1\Take_01_Halbzeit1_cam32_0000171.dpx
Format: DPX (SMPTE 268M-2003 (DPX 2.0))
Class: DirectClass
Geometry: 1920x1080+0+0
Resolution: 72x72
Print size: 26.6667x15
Units: Undefined
Type: TrueColor
Base type: TrueColor
Endianess: MSB
Colorspace: RGB
Depth: 16/14-bit
Channel depth:
red: 14-bit
green: 14-bit
blue: 14-bit
Channel statistics:
red:
min: 32 (0.000488289)
max: 1020 (0.0155642)
mean: 491.907 (0.00750601)
standard deviation: 342.012 (0.00521877)
kurtosis: -1.37131
skewness: 0.534891
green:
min: 32 (0.000488289)
max: 1000 (0.015259)
mean: 486.725 (0.00742695)
standard deviation: 339.865 (0.00518601)
kurtosis: -1.36237
skewness: 0.518388
blue:
min: 24 (0.000366217)
max: 1020 (0.0155642)
mean: 459.711 (0.00701474)
standard deviation: 352.045 (0.00537186)
kurtosis: -1.31709
skewness: 0.657898
Image statistics:
Overall:
min: 24 (0.000366217)
max: 1020 (0.0155642)
mean: 359.586 (0.00548693)
standard deviation: 363.805 (0.00555131)
kurtosis: -0.838053
skewness: 0.815415
Rendering intent: Undefined
Interlace: None
Background color: white
Border color: rgb(223,223,223)
Matte color: grey74
Transparent color: black
Page geometry: 1920x1080+0+0
Dispose: Undefined
Iterations: 0
Compression: Undefined
Orientation: TopLeft
Properties:
create-date: 2009-06-23T13:35:53+02:00
dpx:file.creator: ImageMagick 6.5.3-3 2009-06-04 Q16 http://www.imagemagick.org
dpx:file.ditto.key: 1
dpx:file.timestamp: 2009-06-23T15:36:28+02:
dpx:file.version: V2.0
dpx:film.frame_position: 0
dpx:film.held_count: 0
dpx:film.sequence_extent: 0
dpx:image.orientation: 0
dpx:orientation.aspect_ratio: 0x0
dpx:orientation.border: 0x0+0+0
dpx:orientation.x_offset: 0
dpx:orientation.x_size: 0
dpx:orientation.y_offset: 0
dpx:orientation.y_size: 0
dpx:television.time.code: 00:00:00:00
dpx:television.user.bits: 00:00:00:00
modify-date: 2009-06-23T15:36:28+02:00
signature: 04bdd8dfc52ad1c6321a48fb75948e73a4ba08ac432301a77363b13b2e44bcb4
software: ImageMagick 6.5.3-3 2009-06-04 Q16 http://www.imagemagick.org
Artifacts:
verbose: true
Tainted: False
Filesize: 11.87mb
Number pixels: 1.978mb
Version: ImageMagick 6.5.3-8 2009-06-16 Q16 OpenMP http://www.imagemagick.org
Nicola

Re: How to write 10 bit RGB to files

Post by Nicola »

BTW: here you can find a resulting BLACK DPX: http://www.yourfilehost.com/media.php?c ... 000171.dpx
Nicola

Re: How to write 10 bit RGB to files

Post by Nicola »

I tried other formats for my 10 bit. Doing exactly the same with int's produces black images as well. Doing the same with char's works fine again - but of course char's can't hold 10 bit :-(
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to write 10 bit RGB to files

Post by magick »

Set the image depth to 10 to produce a 10-bit DPX image. In the mean-time try:
  • convert Take_01_Halbzeit1_cam32_0000171.dpx -normalize image.png
    display image.png
Your image is there its just saved with a range of 10-bits in a 16-bit DPX image.
Nicola

Re: How to write 10 bit RGB to files

Post by Nicola »

The conversion/normalization works. but I hope that's not the final solution...

EDIT: Doing the following between Magick::Image init and write doesn't solve the problem:

Code: Select all

cMagickImage.channelDepth( MagickCore::AllChannels, 10 );
AND/OR

Code: Select all

cMagickImage.depth( 10 );
EDIT: It even makes the PNG worse, i.e. reduced in color depth!
Nicola

Re: How to write 10 bit RGB to files

Post by Nicola »

OK, my current work around is to include:
cMagickImage.normalize();
cMagickImage.depth( 10 );
This produces a nice image BUT what is normalize() doing. I'm afraid of losing image quality...
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to write 10 bit RGB to files

Post by magick »

User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to write 10 bit RGB to files

Post by fmw42 »

This produces a nice image BUT what is normalize() doing. I'm afraid of losing image quality...
Normalize may clip data on either end. Perhaps -constrast-stretch 0 would be better as it stretches the data between min and max values to black and white without clipping any at either end.
Nicola

Re: How to write 10 bit RGB to files

Post by Nicola »

I found that level( 0, 1023, 1 ) seems to give better results than normalize() (i.e. preserving more unique colors).
BUT I still would prefer to store the data without any transformation!
Post Reply