SetActiveFrame() on tif throwing exception (whole source incl.)

Tech-Archive recommends: Fix windows errors by optimizing your registry



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


.



Relevant Pages

  • Re: SetActiveFrame() on tif throwing exception (whole source incl.)
    ... will need to display multi pages tiff. ... int numPages = image.GetFrameCount; ... Console.WriteLine("Changed to frame without ... public static byteReadWholeStream(Stream stream) ...
    (microsoft.public.dotnet.framework.drawing)
  • Re: SetActiveFrame() on tif throwing exception (whole source incl.)
    ... The Tiff that is produced from my application appears to be ... int numPages = image.GetFrameCount; ... Console.WriteLine("Changed to frame without ... public static byteReadWholeStream(Stream stream) ...
    (microsoft.public.dotnet.framework.drawing)
  • Re: SetActiveFrame() on tif throwing exception (whole source incl.)
    ... A multi frame tiff needs access to it's source stream. ... Find great Windows Forms articles in Windows Forms Tips and Tricks ... Answer those GDI+ questions with the GDI+ FAQ ...
    (microsoft.public.dotnet.framework.drawing)
  • Re: DVD to WMV -- Success...
    ... direct stream copy is selected, should be since that is the default. ... The higher the frame rate the better. ... maintain the quality, it will create them. ... > My source DVD have only the Video and Audio: ...
    (microsoft.public.windowsmedia.encoder)
  • Re: Reading sections of MP3/WMA files
    ... is the boundary of an audio frame. ... type will tell you the block align of the stream and a block ... You may want to take a look at my sample MP3 parser to know ... a decode to memory takes. ...
    (microsoft.public.windowsmedia.sdk)