SetActiveFrame() on tif throwing exception (whole source incl.)
- From: "Steve K." <noway@xxxxxxxxxxx>
- Date: Mon, 7 Jan 2008 23:16:27 -0800
Hi,
1.5 days of trying to solve this and I can't.... I now ask the pros for help
:0)
I'm working on an image viewing module for our office application. We will
need to display multi pages tiff (faxes). I've created a sample application
to familiarize myself with working with tiffs. Things were going OK until I
tried to change to a different page and I got the dreaded "Generic GDI+
Error" exception.
You will see some methods in the below code that might not "smell right" -
things like ImageFromBytes and BytesFromImage, etc. These are all helper
methods I've been using for years to work with DB blob data. I suspect very
much the problem is somewhere in those methods, but I don't see it.
Since there is no error to really run with, I hoped I could paste the whole
application (Console app, very small) in the hopes that someone with
experience could give it a run. It doesn't require any files or anything,
the TIF is created by the application for testing. It does save the tiff it
creates to the drive, but deletes it after it's done in a try/finally
This is just a test app, it's a bit ugly I know.
<code>
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Text;
namespace AccessTiffPageProblem
{
class Program
{
static void Main(string[] args)
{
// Create a multi page TIFF, save to disk (I think we have to)
// then read the saved tiff as a byte[], then convert to Image
object
// Finally pull the page count and activate different frames.
//
// A good chunk of this code was pulled from Bob Powell's FAQ.
// I've proceeded to massacre it to my usual standards ;0)
try
{
byte[] multiPageTiffData = CreateMultiPageDummyTiffFile(7);
Image image = ImageFromBytes(multiPageTiffData);
// Get the page count
int numPages = image.GetFrameCount(FrameDimension.Page);
Console.WriteLine("Tiff image has {0} pages (frames)",
numPages);
// activate the frames
for (int i = 0; i < numPages; i++)
{
image.SelectActiveFrame(FrameDimension.Page, i);
Console.WriteLine("Changed to frame {0} without
trouble", i);
}
}
catch(Exception e)
{
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("--------------------------------------------------------");
Console.WriteLine(e.ToString());
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
private static byte[] CreateMultiPageDummyTiffFile(int pageCount)
{
// Make sure that no more than 10 pages are created!
pageCount = Math.Max(10, pageCount);
string rootPath =
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string path = rootPath + @"\" + Guid.NewGuid().ToString() +
".tif";
try
{
//get the codec for tiff files
ImageCodecInfo info = null;
foreach (ImageCodecInfo ice in
ImageCodecInfo.GetImageEncoders())
if (ice.MimeType == "image/tiff")
info = ice;
//use the save encoder
System.Drawing.Imaging.Encoder enc =
System.Drawing.Imaging.Encoder.SaveFlag;
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(enc,
(long)EncoderValue.MultiFrame);
Bitmap pages = null;
int frame = 0;
for (int i = 0; i < pageCount; i++)
{
if (frame == 0)
{
pages = (Bitmap)CreateDummyTifPage(i + 1);
//save the first frame
pages.Save(path, info, ep);
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc,
(long)EncoderValue.FrameDimensionPage);
Bitmap bm = (Bitmap)CreateDummyTifPage(i + 1);
pages.SaveAdd(bm, ep);
}
if (frame == (pageCount - 1))
{
//flush and close.
ep.Param[0] = new EncoderParameter(enc,
(long)EncoderValue.Flush);
pages.SaveAdd(ep);
}
frame++;
}
// Load up the saved tiff file, convert to byte[] and
delete the temp file
byte[] data = ReadWholeFileBytes(path);
// If you comment out the above line and uncomment
// this line things fail in a different way - it reports
// only one frame in the loaded tif
//
//byte[] data = BytesFromImage(pages, ImageFormat.Tiff);
System.IO.File.Delete(path);
return data;
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
if (System.IO.File.Exists(path))
System.IO.File.Delete(path);
}
return null;
}
private static Image CreateDummyTifPage(int randomNumber)
{
// Create an 8.5" x 11" B&W tif image
// assume 96 dpi
const int dpi = 96;
int width = (int)(dpi * 8.5 );
int height = (int)(dpi * 11.0);
Bitmap image = new Bitmap(width, height);
Graphics g = Graphics.FromImage(image);
string msg = string.Format("This is a dummy tif fax created at
runtime.\n" +
"It's random seed is {0}", randomNumber);
Font font = new Font(FontFamily.GenericSerif, 20F);
SizeF msgSize = g.MeasureString(msg, font);
g.FillRectangle(Brushes.White, 0, 0, image.Width, image.Height);
g.DrawString(msg, font, Brushes.Black, (width / 2) -
(msgSize.Width / 2), 100);
return image;
}
public static byte[] ReadWholeStream(Stream stream)
{
byte[] buffer = new byte[stream.Length];
int offset = 0;
int remaining = (int)stream.Length;
while (remaining > 0)
{
int read = stream.Read(buffer, offset, remaining);
if (read <= 0)
{
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes
left to read", remaining));
}
remaining -= read;
offset += read;
}
return buffer;
}
public static byte[] ReadWholeFileBytes(string filename)
{
using (Stream stream = new FileStream(filename, FileMode.Open))
{
return ReadWholeStream(stream);
}
}
public static Image ImageFromBytes(byte[] data)
{
using (MemoryStream ms = new MemoryStream(data, 0, data.Length))
{
ms.Write(data, 0, data.Length);
return Image.FromStream(ms, true);
}
}
public static byte[] BytesFromImage(Image image, ImageFormat format)
{
byte[] Ret;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, format);
Ret = ms.ToArray();
}
return Ret;
}
}
}
</code>
I will REALLY appreciate if anyone can point out the error... I can't find
it without a better error message from GDI.
Thanks,
Steve
.
- Follow-Ups:
- Re: SetActiveFrame() on tif throwing exception (whole source incl.)
- From: Bob Powell [MVP]
- Re: SetActiveFrame() on tif throwing exception (whole source incl.)
- Prev by Date: Re: memory device context and DIB
- Next by Date: Re: SetActiveFrame() on tif throwing exception (whole source incl.)
- Previous by thread: Re: memory device context and DIB
- Next by thread: Re: SetActiveFrame() on tif throwing exception (whole source incl.)
- Index(es):
Relevant Pages
|