Manually convert 16-bit grayscale image data to 8-bit grayscale in Borland c++

View: New views
4 Messages — Rating Filter:   Alert me  

Manually convert 16-bit grayscale image data to 8-bit grayscale in Borland c++

by Robert Zermeno :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi everyone,
 
I have been using this website and mail archieve exclusively finding answers to the questions I had recently.  Thanks a bunch for your knowledge.  However, I am stuck with this issue i cannot find and answer to because everyone is using the libtiff library to perform the action. 
 
I am creating an application to manually read in the bits from the file into memory to be displayed in Borland (I have to read certain segment of a file given an offset and extract an (x,y) size sub-image of an image.  What I mean by manually, is I parse through the header and footer myself using fseek() and fread(), and use the stripOffset and StripByteCount to perform a fread() for each strip of image data.
 
How on earth may I be able to convert my 16-bit grayscale image data to 8-bit?  I have been able to take 2 bytes to a short value, then truncate it to a single byte like so:
 
 unsigned short value16 = *TmpBits++;
                       value16 = value16 + (*TmpBits++ << 8)
pBits[curPix++] = (value16/257. + .5)  //convert value to double and round up.
 
where pBits is my BYTE array to hold image data and TmpBits is another BYTE array of size StripByteCount.
 
When I dislpay my data in Borland through a TImage object, I will recieve my image (meaning, you can make out my object I am looking at, but the gray values for each pixel is way off.  Sometimes too much white and some pixels are correct for black)  but the gray coloration is way off.  I have to do this because in Borland, to create my HBITMAP from a bmp object it must be in 1,4,8 or 24 bpp image.  I then pass this created HBITMAP to an TBitmap object and associate this Bitmap to an TImage for display purposes.
 
It works well with 8-bit images, but I cannot get the 16-bit data to work.  Here is my tag information to help out what my issue is:
 

NewSubfileType                   254        LONG          1         0
ImageWidth                        256        LONG          1         14592
ImageLength                       257        LONG          1         6940
BitsPerSample                    258        SHORT         1         16
Compression                      259        SHORT         1         1
PhotometricInterpretation     262        SHORT         1         1
ImageDescription                270        ASCII         13        Space Imaging
StripOffsets                        273        LONG          6940      56040 85224 114408 143592...
SamplesPerPixel                277        SHORT         1         1
RowsPerStrip                      278        SHORT         1         1
StripByteCounts                 279        LONG          6940      29184 29184 29184 29184...
MinSampleValue                280        SHORT         1         0
MaxSampleValue               281        SHORT         1         2047
XResolution                        282        RATIONAL      1         1/1
YRresolution                      283        RATIONAL      1         1/1
ResolutionUnit                    296        SHORT         1         1
DateTime                           306        ASCII         20        2001:01:11 18:50:28
Copyright                          33432      ASCII         24        (c) Space Imaging LLC |
 
It is a geotiff image, but that is irrelevent.  Please help me understand this issue.
Thanks in advance.
Robert 
 


_______________________________________________
Tiff mailing list: Tiff@...
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/

Re: Manually convert 16-bit grayscale image data to 8-bit grayscale in Borland c++

by Evgenia Gurova :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

For converting 16-bit TIFF images to 8-bit I successfully use
ImageMagic:    convert -depth 8 ifile ofile.
The only option - ImageMagic "kills" geo-tag, so if you have geo-tiff,
you need first  write geo-tag to a txt file (with "listgeo") and after
processing with ImageMagic - write it back (with "geotifcp").
I do it on Ubuntu Linux, works perfect!


Robert Zermeno wrote:

> Hi everyone,
>  
> I have been using this website and mail archieve exclusively finding
> answers to the questions I had recently.  Thanks a bunch for your
> knowledge.  However, I am stuck with this issue i cannot find and
> answer to because everyone is using the libtiff library to perform the
> action.
>  
> I am creating an application to manually read in the bits from the
> file into memory to be displayed in Borland (I have to read certain
> segment of a file given an offset and extract an (x,y) size sub-image
> of an image.  What I mean by manually, is I parse through the header
> and footer myself using fseek() and fread(), and use the stripOffset
> and StripByteCount to perform a fread() for each strip of image data.
>  
> How on earth may I be able to convert my 16-bit grayscale image data
> to 8-bit?  I have been able to take 2 bytes to a short value, then
> truncate it to a single byte like so:
>  
>  unsigned short value16 = *TmpBits++;
>                        value16 = value16 + (*TmpBits++ << 8)
> pBits[curPix++] = (value16/257. + .5)  //convert value to double and
> round up.
>  
> where pBits is my BYTE array to hold image data and TmpBits is another
> BYTE array of size StripByteCount.
>  
> When I dislpay my data in Borland through a TImage object, I will
> recieve my image (meaning, you can make out my object I am looking at,
> but the gray values for each pixel is way off.  Sometimes too much
> white and some pixels are correct for black)  but the gray coloration
> is way off.  I have to do this because in Borland, to create my
> HBITMAP from a bmp object it must be in 1,4,8 or 24 bpp image.  I then
> pass this created HBITMAP to an TBitmap object and associate this
> Bitmap to an TImage for display purposes.
>  
> It works well with 8-bit images, but I cannot get the 16-bit data to
> work.  Here is my tag information to help out what my issue is:
>  
>
> NewSubfileType                   254        LONG          1         0
> ImageWidth                        256        LONG          1         14592
> ImageLength                       257        LONG          1         6940
> BitsPerSample                    258        SHORT         1         16
> Compression                      259        SHORT         1         1
> PhotometricInterpretation     262        SHORT         1         1
> ImageDescription                270        ASCII         13        
> Space Imaging
> StripOffsets                        273        LONG          6940      
> 56040 85224 114408 143592...
> SamplesPerPixel                277        SHORT         1         1
> RowsPerStrip                      278        SHORT         1         1
> StripByteCounts                 279        LONG          6940      
> 29184 29184 29184 29184...
> MinSampleValue                280        SHORT         1         0
> MaxSampleValue               281        SHORT         1         2047
> XResolution                        282        RATIONAL      1         1/1
> YRresolution                      283        RATIONAL      1         1/1
> ResolutionUnit                    296        SHORT         1         1
> DateTime                           306        ASCII         20        
> 2001:01:11 18:50:28
> Copyright                          33432      ASCII         24        
> (c) Space Imaging LLC |
>  
> It is a geotiff image, but that is irrelevent.  Please help me
> understand this issue.
> Thanks in advance.
> Robert
>  
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Tiff mailing list: Tiff@...
> http://lists.maptools.org/mailman/listinfo/tiff
> http://www.remotesensing.org/libtiff/

--
****************************
Institute of Aerial Geodesy
Applied Research Center
Pramones pr.13, LT-51327
Kaunas, Lithuania
tlf. +370 377 55226
fax. +370 374 51497
mob. +370 680 88688
 


_______________________________________________
Tiff mailing list: Tiff@...
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/

Re: Manually convert 16-bit grayscale image data to 8-bit grayscale in Borland c++

by Bob Friesenhahn :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 10 Sep 2009, Robert Zermeno wrote:

> How on earth may I be able to convert my 16-bit grayscale image data
> to 8-bit?  I have been able to take 2 bytes to a short value, then
> truncate it to a single byte like so:  

>  unsigned short value16 = *TmpBits++;
>                        value16 = value16 + (*TmpBits++ << 8)

Be sure to consider endian order since TIFF can be big or little
endian.

> When I dislpay my data in Borland through a TImage object, I will
> recieve my image (meaning, you can make out my object I am looking
> at, but the gray values for each pixel is way off.  Sometimes too
> much white and some pixels are correct for black)  but the gray
> coloration is way off.  I have to do this because in Borland, to

Someone else here mentioned ImageMagick, but I will instead
(naturally!) suggest installing a "Q16" build of GraphicsMagick from
http://www.GraphicsMagick.org/ and you can use that to see if the
results look the same as with your Borland results.  If results look
similar, then add the -normalize option when converting the file and
see if there is now a recognizable image.

It is important to realize that Geotiff data may use the full range
and resolution of the 16 bits.  A simple conversion to 8 bit would
loose all of the data if it happened to only use the range of 0 to
255. Some sensors may only produce a range of 0-4095 but the values
are still stored in 16-bits.  It could be a particularly dark or
bright day. Due to this, software which deals with such images often
reads the data twice.  The first read is used to estimate the scaling
parameters to be applied during the second read.  User interaction may
be necessary to fine-tune the results.

Bob
--
Bob Friesenhahn
bfriesen@..., http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
Tiff mailing list: Tiff@...
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/

Re: Manually convert 16-bit grayscale image data to 8-bit grayscale in Borland c++

by Robert Zermeno :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>It could be a particularly dark or bright day. Due to this, software which deals with such >images often reads the data twice.  The first read is used to estimate the scaling >parameters to be applied during the second read.  User interaction may be necessary to >fine-tune the results
 
Can you elaborate a little more on the idea behind 2 reads ("used to estimate the scaling parameters?")
I have to provide my own tiff reader/writer because the type of handheld device the software will be placed on cannot use libtiff.  For some reason, it cannot compile and work on the handheld (as claimed by my team lead).  So, I am forced to re-invent the wheel, but with a different purpose.
 
I have all the different types of tiff images my firm will deal with written out to read them except for 16-bit grayscale images.  I am aware of Little/Big endian byte ordering and I account for this as well.


--- On Thu, 9/10/09, Bob Friesenhahn <bfriesen@...> wrote:

From: Bob Friesenhahn <bfriesen@...>
Subject: Re: [Tiff] Manually convert 16-bit grayscale image data to 8-bit grayscale in Borland c++
To: "Robert Zermeno" <refriguy68@...>
Cc: tiff@...
Date: Thursday, September 10, 2009, 8:52 AM

On Thu, 10 Sep 2009, Robert Zermeno wrote:

> How on earth may I be able to convert my 16-bit grayscale image data to 8-bit?  I have been able to take 2 bytes to a short value, then truncate it to a single byte like so:  

>  unsigned short value16 = *TmpBits++;
>                        value16 = value16 + (*TmpBits++ << 8)

Be sure to consider endian order since TIFF can be big or little endian.

> When I dislpay my data in Borland through a TImage object, I will recieve my image (meaning, you can make out my object I am looking at, but the gray values for each pixel is way off.  Sometimes too much white and some pixels are correct for black)  but the gray coloration is way off.  I have to do this because in Borland, to

Someone else here mentioned ImageMagick, but I will instead (naturally!) suggest installing a "Q16" build of GraphicsMagick from http://www.GraphicsMagick.org/ and you can use that to see if the results look the same as with your Borland results.  If results look similar, then add the -normalize option when converting the file and see if there is now a recognizable image.

It is important to realize that Geotiff data may use the full range and resolution of the 16 bits.  A simple conversion to 8 bit would loose all of the data if it happened to only use the range of 0 to 255. Some sensors may only produce a range of 0-4095 but the values are still stored in 16-bits.  It could be a particularly dark or bright day. Due to this, software which deals with such images often reads the data twice.  The first read is used to estimate the scaling parameters to be applied during the second read.  User interaction may be necessary to fine-tune the results.

Bob
--
Bob Friesenhahn
bfriesen@..., http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/


_______________________________________________
Tiff mailing list: Tiff@...
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/