GDI+ and multi-page tiff files

112 views
Skip to first unread message

David H.

unread,
Mar 15, 2002, 11:50:38 AM3/15/02
to
Are the new GDI+ system tools capable of opening and
manipulating individual pages of a multi-page tiff file
(such as created by a scanning software package)?

John Hornick [MS]

unread,
Mar 15, 2002, 3:55:38 PM3/15/02
to
Hi,

> Are the new GDI+ system tools capable of opening and
> manipulating individual pages of a multi-page tiff file
> (such as created by a scanning software package)?


I don't know what you mean by "GDI+ system tools".

For programmers, GDI+ is capable of reading multi-page TIFFs.
See Image.SelectActiveFrame().


Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.

David H.

unread,
Mar 15, 2002, 4:51:22 PM3/15/02
to
Thanks John,

What I'm trying to do is return the pages of a tiff from
an .aspx page coded in VB.

I've successfully loaded it from a directory on the web
server using:

dim myImage as System.Drawing.Image =
System.Drawing.Image.FromFile(path)

And sent it in the page stream using (of course, this
returns just the first page):

myImage.save(response.outputstream,
system.drawing.imaging.ImageFormat.Gif)

It doesn't look like image.SelectActiveFrame() is happy
with just the page number as a parameter. Do you have any
examples of the right syntax?

I also will need to retrieve the total number of pages in
the document if that is possible?

This is my first attempt at GDI+ programming in ASP.NET
pages, but so far I'm very impressed with what I see!

Robert Smith

unread,
Mar 17, 2002, 7:35:33 AM3/17/02
to
I've got a class tht does all those tif things (including getting rid
of the scrunching that occurs because fax compression sets different
horizontal and vertical resolutions ... I've got an article coming to
smithvoice.com/vbfun.htm about all the ins and outs of tif files.
Should be up in a week or so)

But first off,try this. I'm doing it from memory but it should get you
going:

dim myimg as System.Drawing.Image
myimg = Image.FromFile([FilePath])

Dim oFDimension As System.Drawing.Imaging.FrameDimension
oFDimension = New System.Drawing.Imaging.FrameDimension _
(myimg.FrameDimensionsList(0))

'framecount is one based
msgbox("PageCount: " & myimg.GetFrameCount(oFDimension))

'frame/pages are zero based
dim iCount as integer = 0
for iCount to myimg.GetFrameCount(oFDimension))-1
myimg.SelectActiveFrame(oFDimension,iCount)
'do what you want with the "image" object,
'if you pass the myimg object out at this point in the loop
' (like to a picturebox or response.outputstream)
'you will get the "image" for that page
'example
myimg.save(Response.Outputstream,
System.Drawing.Imaging.ImageFormat.JPEG)
'the above will render all the pages to a browser
next


The one thing I have seen with this in asp.net is that if the file is
on a unc share then IIS/ASP.net will lock it even after you are done
with it and your object has gone out of scope (so you can't go to that
machine and delete or move the file!). But that is not a tif issue,
it seems to happen with all image files opened with FromFile.

Robert Smith
Kirkland, WA
www.smithvoice.com/vbfun.htm
www.doitin.net

David H.

unread,
Mar 18, 2002, 9:39:27 AM3/18/02
to
Very nice! Thanks!

>.
>

Robert Smith

unread,
Mar 19, 2002, 12:15:43 AM3/19/02
to
"David H." <david....@acs-inc.com> wrote in message news:<404601c1ce8a$b49e5a90$35ef2ecf@TKMSFTNGXA11>...
> Very nice! Thanks!
>

Hope it helped... here's a bit of added info you might need. I have
gotten around the issue of FromFile locking files, I stopped using
FromFile and use a Stream and, in an ASP.net app, an additional step
of a Byte array. It seems like overkill to go Stream to array back to
a Stream but without that my apps would not work. Here's a first
draft to the "tip"... (I'd love someone to explain the reaons for all
this, btw)


###
A System.Drawing.Image object has a tempting FromFile method that
allows you to pass in a full path to fill the object. There is a
significant downside to this simple method: It locks the image file a
lot longer than you'd ever want, prohibiting you to delete or modify
the source file out side of your app after you opened it (any such
attempts raise a "There has been a sharing violation. The source or
destination file may be in use" error).

Using the FromFile in a WinForm app will lock the file for the
lifetime of the application, even if you let the Image fall out of
scope and, worse still, in ASP.net passing a UNC to FromFile to open
an image located remotely will lock the file indefinitely (even hours
beyond the run of the WebApp, that can't be the Garbage Collector!).

I don't know exactly why this is, but I can tell you a workaround:
Don't use Image.FromFile. Instead, use a Stream object open the file,
pass it to the Image's FromStream method and close the stream when the
Image object is filled.

Dim objStream As System.IO.Stream = System.IO.File.Open([Path To
File], System.IO.FileMode.Open)
Dim MyImage as System.Drawing.Image
MyImage.FromStream(objStream)
objStream.Close()

Oddly, this has not fully helped the lockups when the Image object is
encapsulated in a custom wrapper class being used from an ASP.net
application. In that case the only way to have the file display *and*
leave it modifiable outside of the app is to load it into a Stream,
convert the Stream to a Byte array, pass the Byte array to the dll
then have the dll reconstitute the array to a new stream and load that
into the Image.FromStream method. Strange but true.

Client Code:

Dim objStream As System.IO.Stream = System.IO.File.Open([Path To
File], System.IO.FileMode.Open)
Dim buffer(objStream.Length) As Byte
objStream.Read(buffer, 0, objStream.Length)
MYImageWrapperClass.Open(buffer)
objStream.Close()

Dll Code:
...
Public Sub Open(ByVal btByte As Byte())
'module level iamge variable declared elsewhere as: private m_Image
= System.Drawing.Image

Dim strm As New System.IO.MemoryStream()
strm.Write(btByte, 0, btByte.Length)
m_image = Image.FromStream(strm)
End Sub

I hope this helps.
Robert Smith
Kirkland, WA

### Any takers on why all this happens?

David H.

unread,
Mar 19, 2002, 6:10:59 PM3/19/02
to
Here's another approach I've used to open an image file
via URL (as stored in a variable named "path"):

dim myimg as System.Drawing.Image
Dim wc As New System.Net.WebClient()
myimg = myimg.FromStream(wc.OpenRead(path))

So far, I'm not having any problems with it. I'm
basically using this approach to return a selected page of
the .tif and the 3 surrounding pages as thumbnails to
a "viewer" page that contains 4 <img
src=myimagestream.aspx> tags. In other words, I'm making
4 back-to-back calls that opens and returns one page of
the same .tif -- no problem!

>....


>Public Sub Open(ByVal btByte As Byte())
> 'module level iamge variable declared elsewhere as:
private m_Image
>= System.Drawing.Image
>
> Dim strm As New System.IO.MemoryStream()
> strm.Write(btByte, 0, btByte.Length)
> m_image = Image.FromStream(strm)
>End Sub
>
>I hope this helps.
>Robert Smith

>KirklÍ{ wÀ t Ìζ1ô«0`ì£- °ìx and, WA


>
>### Any takers on why all this happens?

>.
>

Ųyvind Sannerhaugen

unread,
Mar 22, 2002, 6:27:00 AM3/22/02
to
Interesting question. I am trying to write a program which is capable of
creating multi-page tiff files, but I have not succeeded (yet). This is due
to my lack of experience with GDI, as well as poor documentation.

However, I found an interesting article on MSDN;

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/gdip
_cpp_classes_02a_2z6n.asp

So far I have not managed to port this code to C# yet, but I am working on
it. My problem is that I am not quite sure of how I am supposed to use the
EncoderParameters object in .NET. I have seached the internet trying to find
a .NET example, but to no avail. Anobody with more experience on this?


Regards,

Ųyvind Sannerhaugen

"David H." <david....@acs-inc.com> wrote in message

news:3e8c01c1cc41$889d3830$9be62ecf@tkmsftngxa03...

Reply all
Reply to author
Forward
0 new messages