I have been exploring adding Tiff and Png files to an image processing program that I have developed. I am particularly interested in 16 bpp grayscale and 48 bpp color versions. I decided to try GDI+ despite Jose Roca's caution that GDI+ did not handle these versions properly. I hoped that I might be able to just use GDI+ to load the file, and then grab the bytes in memory without doing any further processing in GDI+. What I found is that this approach worked fine for 8 bpp images, but not at all for 16 bpp grayscale or 48 bpp color. In the latter cases the image bytes seem to get rescaled to use only about 6 of the available 256 levels. The code follows, and what I would like to know is whether someone could suggest an alternative approach or work-around that might preserve the high dynamic range images?
Ken German
'The above code is actually the VB6 prototype and would be modified appropriatly before proceeding to the PB DLL
Ken German
Code:
'##################### [FONT=MS Mincho][FONT=Courier New]Public Function Open_Tif_Png(imageData As String, Index As Integer) As Boolean[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim I As Long, J As Long, K As Long 'index variables[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim statusNow As GpStatus[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim gdipBeginInfo As GdiplusStartupInput[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim gdipToken As Long 'created at GDI+ start, used to close GDI+[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim bmpData As BitmapData 'data structure from GDI+ lock[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim ptrBmp As Long 'pointer from GDI+ file read[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim nuRect As RECTL 'rectangular picture structure of locked data[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim xWidth As Single 'image width in pixels[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim yHeight As Single 'image height in pixels[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim ptrBitmapData As Long 'pointer RECTL data[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim xStride As Long 'width*bytesperpixel padded/4 [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim pixFormat As Long 'return from GetPixelImageFormat[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim bytePerPixel As Long 'name says it all[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim byteArray() As Byte 'memory block for image data[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]Dim datalength As Long 'ubound of byteArray[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]'######################[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]gdipBeginInfo.DebugEventCallback = 0[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]gdipBeginInfo.GdiplusVersion = 1[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]gdipBeginInfo.SuppressBackgroundThread = 0[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]gdipBeginInfo.SuppressExternalCodecs = 0[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'Start GDI+[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdiplusStartup(gdipToken, gdipBeginInfo)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'Load file[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipCreateBitmapFromFile(StrPtr(imageData), ptrBmp)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'Get width and height of image[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipGetImageDimension(ptrBmp, xWidth, yHeight)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'Set size of image data to be opened for read[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] nuRect.Height = yHeight[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] nuRect.left = 0[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] nuRect.top = 0[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] nuRect.Width = xWidth[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'get pixel format of opened image[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipGetImagePixelFormat(ptrBmp, pixFormat)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'lock bitmap data for reading[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipBitmapLockBits(ptrBmp, nuRect, ImageLockModeRead, pixFormat, bmpData)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] xStride = Abs(bmpData.Stride) 'negative means inverted [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] ptrBitmapData = bmpData.Scan0Ptr[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Select Case pixFormat[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Case 137224 [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] '%PixelFormat24bppRGB [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] bytePerPixel = 3[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Case 198659 [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] '%PixelFormat8bppIndexed [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] bytePerPixel = 1[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Case 2498570 [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] '%PixelFormat32bppARGB [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] bytePerPixel = 4[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Case 1060876 [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] '%PixelFormat48bppRGB [/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] bytePerPixel = 6[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Case Else[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] 'Quit[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Screen.MousePointer = vbDefault[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] MsgBox "Unrecognized pixel format!", vbOKOnly, "FILE READ ERROR"[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipBitmapUnlockBits(ptrBmp, bmpData)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipDisposeImage(ptrBmp)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] statusNow = GdipDisposeImage(ptrBmp)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] Exit Function[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] End Select[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] datalength = xStride * yHeight - 1[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] ReDim byteArray(datalength)[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New] CopyMemory byteArray(0), ptrBitmapData, datalength[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]'following code creates an image from byteArray() and closes GDI+ functions neatly but has no impact on the stated problem[/FONT][/FONT] [FONT=MS Mincho][FONT=Courier New]'##########################################[/FONT][/FONT]
Comment