How do I display Multipage tiff image
How do I display Multipage tiff image
Hi,
I am trying to find a way to display Multipage Tiff images in PB.
If I use the Tiff decoder it only displays the first page, is there a way to display them with PB or do I have to use a library to display them. I would be happy with the pages to be joined at the bottom of the previous page.
Does anyone have any ideas or clues.
Thanks
I am trying to find a way to display Multipage Tiff images in PB.
If I use the Tiff decoder it only displays the first page, is there a way to display them with PB or do I have to use a library to display them. I would be happy with the pages to be joined at the bottom of the previous page.
Does anyone have any ideas or clues.
Thanks
Regards
Leo
Leo
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: How do I display Multipage tiff image
Your best bet would probably be the FreeImage library. Gdiplus is capable as well but with more effort required from the coder. You could always write your own decoder like Wilbert and I both did for Gif over the last 2 months of 2013 but that would be overkill unless you really love tiffs.
BERESHEIT
Re: How do I display Multipage tiff image
I always liked multipage tiffs for document storage although I now scan and OCR documents into PDF so they are searchable so I stopped using TIFF. Would be handy to have a native PB reader.
Re: How do I display Multipage tiff image
Hi,
I got this far but can't display the other pages.
Does anyone have an example of multipage display.
Regards
I got this far but can't display the other pages.
Code: Select all
; Modified from ************************************
;==================================================
; Program: GDIPlus Rotation Demo
; Author: netmaestro
; Date: November 12, 2006
;==================================================
;****************************************************
CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugCallback
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
CompilerEndIf
Prototype GdiplusStartup( *token, *input, mode )
Prototype GdipCreateBitmapFromFile( Filename, *image )
Prototype GdipGetImageWidth( *image, *Width )
Prototype GdipGetImageHeight( *image, *Height )
Prototype GdipCreateFromHDC( hdc, *gfx)
Prototype GdipDrawImageRectI( *gfx, *image, x, y, Width, Height )
Prototype GdipDeleteGraphics( *gfx )
Prototype GdipDisposeImage( *image )
Prototype GdiplusShutdown( *token )
OpenLibrary(0, "gdiplus.dll")
Global Startup.GdiplusStartup = GetFunction( 0, "GdiplusStartup" )
Global CreateBitmapFromFile.GdipCreateBitmapFromFile = GetFunction( 0, "GdipCreateBitmapFromFile" )
Global GetImageWidth.GdipGetImageWidth = GetFunction( 0, "GdipGetImageWidth" )
Global GetImageHeight.GdipGetImageHeight = GetFunction( 0, "GdipGetImageHeight" )
Global CreateFromHDC.GdipCreateFromHDC = GetFunction( 0, "GdipCreateFromHDC" )
Global DrawImageRectI.GdipDrawImageRectI = GetFunction( 0, "GdipDrawImageRectI" )
Global DeleteGraphics.GdipDeleteGraphics = GetFunction( 0, "GdipDeleteGraphics" )
Global DisposeImage.GdipDisposeImage = GetFunction( 0, "GdipDisposeImage" )
Global Shutdown.GdiplusShutdown = GetFunction( 0, "GdiplusShutdown" )
;
;-----------------------------------------------------------------------------
; End GDIPlus Initialization Section
;-----------------------------------------------------------------------------
Procedure StringToBStr (string$) ; By Zapman Inspired by Fr34k
Protected Unicode$ = Space(Len(string$)* 2 + 2)
Protected bstr_string.l
PokeS(@Unicode$, string$, -1, #PB_Unicode)
bstr_string = SysAllocString_(@Unicode$)
ProcedureReturn bstr_string
EndProcedure
input.GdiplusStartupInput
input\GdiPlusVersion = 1
Startup( @*token, @input, #Null)
FileName.s = "C:\AS-13-0731-RS-1.tif"
Imagenumber = 0
CreateBitmapFromFile( StringToBStr(Filename), @*image)
GetImageWidth( *image, @Width.l )
GetImageHeight( *image, @Height.l )
Retval = CreateImage(ImageNumber, width, Height, 24)
hdc = StartDrawing(ImageOutput(ImageNumber))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, width, height, 0)
CreateFromHDC( hdc, @*gfx )
DrawImageRectI( *gfx, *image, 0, 0, Width, Height)
StopDrawing()
DeleteGraphics( *gfx )
DisposeImage( *image )
Shutdown( *token )
CreateImage(1, width, height, 24)
StartDrawing(ImageOutput(1))
Box(0, 0, width, Height, GetSysColor_(#COLOR_3DFACE))
DrawAlphaImage(ImageID(0), 0, 0)
StopDrawing()
CloseLibrary(0)
OpenWindow(0,0,0,600,800,"")
ScrollAreaGadget(99,0,0,600,800,1700,2200)
ImageGadget(0,0,0,Width,Height,ImageID(1))
CloseGadgetList()
Repeat
Until WaitWindowEvent() = #WM_CLOSE
ShutDownGDIPlus(*token)
Regards
Regards
Leo
Leo
Re: How do I display Multipage tiff image
Hi,
look at
http://www.purebasic.fr/english/viewtop ... hilit=tiff
at the bottom of the first page.
Bernd
look at
http://www.purebasic.fr/english/viewtop ... hilit=tiff
at the bottom of the first page.
Bernd
Re: How do I display Multipage tiff image
I think it should be possible with the decoder that comes with PureBasic.
If you load the tiff file into memory, you should be able to change the offset of the image data to the next page, catch the image and move on to the next one.
If you load the tiff file into memory, you should be able to change the offset of the image data to the next page, catch the image and move on to the next one.
Last edited by wilbert on Fri Mar 28, 2014 11:38 am, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: How do I display Multipage tiff image
I found some test files and can confirm it's easy to create a simple cross platform solution.
If you specify a negative page number, the procedure returns the amount of pages.

Code: Select all
UseTIFFImageDecoder()
Procedure.w SwapBytesW(v.w)
!movzx eax, word [p.v_v]
!xchg al, ah
ProcedureReturn
EndProcedure
Procedure.l SwapBytesL(v.l)
!mov eax, [p.v_v]
!bswap eax
ProcedureReturn
EndProcedure
Procedure.i CatchTIFFPage(Image, *MemoryAddress.Word, Page = 0)
Protected.i Result, Count, *Entries.Word
Protected *IFD0.Long = *MemoryAddress + 4
Protected *IFD.Long = *IFD0
While *IFD\l
If Count = Page
Swap *IFD0\l, *IFD\l
Result = CatchImage(Image, *MemoryAddress)
Swap *IFD0\l, *IFD\l
Break
EndIf
Count + 1
If *MemoryAddress\w = $4D4D
; big endian
*Entries = *MemoryAddress + SwapBytesL(*IFD\l)
*IFD = *Entries + 2 + SwapBytesW(*Entries\w) * 12
Else
; little endian
*Entries = *MemoryAddress + *IFD\l
*IFD = *Entries + 2 + *Entries\w * 12
EndIf
Wend
If Page >= 0
ProcedureReturn Result
Else
ProcedureReturn Count
EndIf
EndProcedure
Code: Select all
CatchTIFFPage(0, *TIFFData, 1); Catches the second page (page number starts at 0)
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: How do I display Multipage tiff image
Hi Wilbert,
I have had a look at your code and I think I understand what you are saying, but I can not get it to work, I've not done much with images.
When you say load the Tiff file into memory, how do I load it into memory as Image 0 ?
In the statement CatchTiffPage is *TIFFData the pointer to image was loaded ? I think I tried just about everything I could think of.
I am most probably doing something really silly, but I have no idea.
Could you push me in the right direction.
Thanks
I have had a look at your code and I think I understand what you are saying, but I can not get it to work, I've not done much with images.
When you say load the Tiff file into memory, how do I load it into memory as Image 0 ?
In the statement CatchTiffPage is *TIFFData the pointer to image was loaded ? I think I tried just about everything I could think of.
I am most probably doing something really silly, but I have no idea.
Code: Select all
OpenWindow(0,0,0,800,700,"",#PB_Window_ScreenCentered)
CreateImage(0,800,600,24)
LoadImage(0,FileName.s)
ImageGadget(0,0,0,800,600,ImageID(0))
Delay(1000)
For t = 1 To 9
CatchTIFFPage(0, *TIFFData, t); Catches the t page (10 pages in Image)
SetGadgetState(0,ImageID(0))
Next t
Repeat
Until WaitWindowEvent() = #WM_CLOSE
Thanks
Regards
Leo
Leo
Re: How do I display Multipage tiff image
Here's a more complete example.leodh wrote:When you say load the Tiff file into memory, how do I load it into memory as Image 0 ?
Hopefully this helps.
Code: Select all
UseTIFFImageDecoder()
Procedure.w SwapBytesW(v.w)
!movzx eax, word [p.v_v]
!xchg al, ah
ProcedureReturn
EndProcedure
Procedure.l SwapBytesL(v.l)
!mov eax, [p.v_v]
!bswap eax
ProcedureReturn
EndProcedure
Procedure.i CatchTIFFPage(Image, *MemoryAddress.Word, Page = 0)
Protected.i Result, Count, *Entries.Word
Protected *IFD0.Long = *MemoryAddress + 4
Protected *IFD.Long = *IFD0
While *IFD\l
If Count = Page
Swap *IFD0\l, *IFD\l
Result = CatchImage(Image, *MemoryAddress)
Swap *IFD0\l, *IFD\l
Break
EndIf
Count + 1
If *MemoryAddress\w = $4D4D
; big endian
*Entries = *MemoryAddress + SwapBytesL(*IFD\l)
*IFD = *Entries + 2 + SwapBytesW(*Entries\w) * 12
Else
; little endian
*Entries = *MemoryAddress + *IFD\l
*IFD = *Entries + 2 + *Entries\w * 12
EndIf
Wend
If Page >= 0
ProcedureReturn Result
Else
ProcedureReturn Count
EndIf
EndProcedure
Procedure.i LoadFile(FileName.s)
Protected.i File, Length, *Memory
File = ReadFile(#PB_Any, FileName)
If File
Length = Lof(File)
*Memory = AllocateMemory(Length)
If *Memory
ReadData(File, *Memory, Length)
EndIf
CloseFile(File)
EndIf
ProcedureReturn *Memory
EndProcedure
; *** Test code ***
Define.i Event, Page, PageCount, *TIFFData
OpenWindow(0, 0, 0, 800, 700, "", #PB_Window_ScreenCentered)
*TIFFData = LoadFile("MyTiffFile.tiff")
If *TIFFData
PageCount = CatchTIFFPage(0, *TIFFData, -1)
For Page = 0 To PageCount - 1
CatchTIFFPage(Page, *TIFFData, Page)
Next
FreeMemory(*TIFFData)
ImageGadget(0, 0, 0, 800, 600, ImageID(0))
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget And EventType() = #PB_EventType_LeftClick
Page = (Page + 1) % PageCount
SetGadgetState(0, ImageID(Page))
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
After that you can catch the images you want.
When the tiff data is no longer needed, FreeMemory needs to be used to free the memory it occupies.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: How do I display Multipage tiff image
Hi Wilbert,
Thank you, I was close but I could not figure out the memory allocation stuff.
Once again the PB community helps a battler.
Thanks again.
Thank you, I was close but I could not figure out the memory allocation stuff.
Once again the PB community helps a battler.
Thanks again.
Regards
Leo
Leo