Anyone out there has code to read a 48 bit (16 bits per colour channel) tiff file?
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
As far as I understand a Tiff is not really an image format itself rather a way of containing one or more files of different formats as one file. The image contained could be a Ping, Jpeg, Bitmap or raw data (a bitmap without a header).
If this image is in Jpeg2000 format then I don't know how to extract it from the Tiff. If it's in a raw or bitmap format it should be fairly straight forward, assuming it's a RGB format rather than a CYMK (printer) format. Once the pixel data has been found it's a case of copying every other byte (the hi order byte) to a new image. A 48bit image cannot be displayed without losing information.
How huge are the files in question? I think you still have my email, if you do you could send it to me and I'll be better placed to tell you how to extract the image.
As far as I understand a Tiff is not really an image format itself rather a way of containing one or more files of different formats as one file. The image contained could be a Ping, Jpeg, Bitmap or raw data (a bitmap without a header).
Well, I have no idea about its structure.
Originally Posted by Milk
If this image is in Jpeg2000 format then I don't know how to extract it from the Tiff. If it's in a raw or bitmap format it should be fairly straight forward, assuming it's a RGB format rather than a CYMK (printer) format. Once the pixel data has been found it's a case of copying every other byte (the hi order byte) to a new image. A 48bit image cannot be displayed without losing information.
Actually I want to separate the 3 channels, R G & B and plot one of them as grayscale.
Originally Posted by Milk
How huge are the files in question? I think you still have my email, if you do you could send it to me and I'll be better placed to tell you how to extract the image.
Just about 2 or 3 Mb. But I've cropped an image which is now about 100 kb to e-mail it to you.
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
Cheers for that...
Right it's a Big Endian tiff which is a pain to read with VB which likes Little Endian numbers. The program I have written is not yet capable of reading Big Endian Tiffs but this is something I've been meaning to address for some time, this sounds like just the excuse I need. In the meantime there might be some some Tiff parser you can find at PSC or somesuch that will do the job.
The size of the file compared to the size of the image within does suggest that it's stored in a raw or Bitmap format of 6 bytes per pixel, making it easy to extract once the Tiff directories can be navigated.
The information that is needed are the image dimensions and the offset of the pixel data.
...In the meantime there might be some some Tiff parser you can find at PSC or somesuch that will do the job.
Well, I'm using a third party program, ImageJ ( http://rsbweb.nih.gov/ij/ ) which allows me to load the tiff and then save it as an array of tab separated text values, which is easy to handle with vb. But I want to skip this step and that's why I'd like to handle the tiff with vb.
Originally Posted by Milk
...
The information that is needed are the image dimensions and the offset of the pixel data.
Image size is 181 x 106 pixels. I'm going to e-mail you the ImageJ converted file.
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
Forgot to mention: in case it's any use to you, in the ImageJ web site the Java source code -including the tiff decoding part- is available, but I don't know Java.
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
Set Tiff = Nothing 'not required, just a good habit
End Sub
The function that receives the 48bit (6 byte/pixel) byte data must choose one of the three high order bytes for the greyscale image. The High order bytes will be the odd indexes for Little-Endian data (even for Big-En...) . It is possible with DibSection Api to work with GreyScale Bitmaps, copy the right bytes to one of those and you're laughing.
I think that Java code you have converts to BigEndian, the scanner TIFFs you sent are Intel friendly.
This looks incredible let me just take a deep breath and start playing around with it.
Originally Posted by Milk
...
I think that Java code you have converts to BigEndian, the scanner TIFFs you sent are Intel friendly...
Maybe this ImageJ thing was first developed for Unix, I once wrote code for parsing files ftp'd from a Unix system and I seem to recall they were big endian.
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
I'm really happy with your code. For now I've just managed to extract the channels,
VB Code:
Dim redch() As Long, greench() As Long, bluech() As Long
Private Sub ExtractChannels(pix, redch, greench, bluech)
Dim pch As Long, i As Long, j As Long
pch = (1 + UBound(pix)) \ 6 - 1
ReDim redch(pch), greench(pch), bluech(pch)
For i = 0 To pch
j = 6 * i
redch(i) = 256 * pix(j + 1) + pix(j)
greench(i) = 256 * pix(j + 3) + pix(j + 2)
bluech(i) = 256 * pix(j + 5) + pix(j + 4)
Next
End Sub
I assume you have to switch the bytes for big endian, for example,
redch(i) = 256 * pix(j) + pix(j + 1)
Edit: this is only because I want to keep the full information per channel that I need for some further processing. Thereafter, when it comes to plot the image then I can keep only the high order byte, odd for little endian as you've pointed out.
Last edited by krtxmrtz; Aug 31st, 2008 at 10:56 AM.
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
and now it can be called for plotting from within your code above:
VB Code:
'...
Dim mybm() As Long
'...
If UBound(Pix) + 1 = Wdth * Hght * 6
Call Create2DBitmap(pix, Wdth, Hght, mybm)
Picture1.Width = Wdth + 2 * bWdt 'Account for
'the border width of the picturebox
Picture1.Height = Hght + 2 * bWdt
Call DrawData(Picture1.hdc, mybm)
Else
Debug.Print "Not a 48bit image"
End If
'...
where DrawData is the function you sent me some time ago based on SetDIBitsToDevice.
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)
I thought it might be useful to transcribe here your DrawData function:
VB Code:
'(In a module)
Option Explicit
Private Type RGBQUAD
blue As Byte
green As Byte
red As Byte
alpha As Byte
End Type
Private Type BITMAPINFOHEADER
bmSize As Long
bmWidth As Long
bmHeight As Long
bmPlanes As Integer
bmBitCount As Integer
bmCompression As Long
bmSizeImage As Long
bmXPelsPerMeter As Long
bmYPelsPerMeter As Long
bmClrUsed As Long
bmClrImportant As Long
End Type
Private Type BITMAPINFO
bmHeader As BITMAPINFOHEADER
bmColors(0 To 255) As RGBQUAD
End Type
Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, _
ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, _
ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, _
ByVal wUsage As Long) As Long
Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Public Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal hStretchMode As Long) As Long
Public Const STRETCHMODE = vbPaletteModeNone
Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
Public Const SRCCOPY = &HCC0020
'...
'...
Public Sub DrawData(handledc As Long, lngImageData2D() As Long)
Lottery is a tax on people who are bad at maths
If only mosquitoes sucked fat instead of blood...
To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)