I am using a C# FreeImage wrapper. I am trying to open a PDF file containing images, and "extract" those images into windows Bitmap objects. I am following the guidelines described in articles on the internet, following loosely the following pattern:
byte[] bytes = GetPdfFile();
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(bytes);
int pageNumber = 0;
for (int i = 0; i <= reader.XrefSize - 1; i++)
{
pdfObj = reader.GetPdfObject(i);
if ((pdfObj != null) && pdfObj.IsStream())
{
pdfStream = (iTextSharp.text.pdf.PdfStream)pdfObj;
iTextSharp.text.pdf.PdfObject subtype = pdfStream.Get(iTextSharp.text.pdf.PdfName.SUBTYPE);
if ((subtype != null) && subtype.ToString().Equals(iTextSharp.text.pdf.PdfName.IMAGE.ToString()))
{
pageNumber++;
byte[] imgBytes = iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw((iTextSharp.text.pdf.PRStream)pdfStream);
if ((imgBytes != null))
{
// in my case images are in TIF Group 4 format
using (MemoryStream ms = new MemoryStream(imgBytes))
{
FreeImageAPI.FIBITMAP bmp = FreeImageAPI.FreeImage.LoadFromStream(ms);
// in my case bmp with IsNull = true is returned
if (!bmp.IsNull)
{
using (MemoryStream msOut = new MemoryStream())
{
FreeImageAPI.FreeImage.SaveToStream(bmp, msOut, ... ); // etc.
}
}
}
}
}
}
}
Does anybody have a suggestion on how to troubleshoot this, given that no exception is returned - some kind of GetLastError FreeImage function? Thank you
Although it doesn't appear that the SetOutputMessage function was added to the .NET wrapper library, it is possible to call it directly from the FreeImage library.
That is, adding the function to your code using:
[DllImport("FreeImage", EntryPoint = "FreeImage_SetOutputMessage")]
internal static extern void SetOutputMessage(OutputMessageFunction outputMessageFunction);
The following code shows an Exception being thrown from the Save function, rather than returning false (with the following console output):
Test 1... Success
Test 2...
Unhandled Exception: System.Exception: only 24-bit highcolor or 8-bit greyscale/palette bitmaps can be saved as JPEG
at ConsoleApplication1.Program.OutputMessage(FREE_IMAGE_FORMAT format, String message) ...\ConsoleApplication1\Program.cs:line 35
at FreeImageAPI.FreeImage.Save(FREE_IMAGE_FORMAT fif, FIBITMAP dib, String filename, FREE_IMAGE_SAVE_FLAGS flags)
at ConsoleApplication1.Program.Main(String[] args) in ...\ConsoleApplication1\Program.cs:line 28
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using FreeImageAPI;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{ FIBITMAP bitmap;
bool success;
SetOutputMessage(OutputMessage);
Console.Write("Test 1... ");
bitmap = FreeImage.CreateFromBitmap(new Bitmap(320, 240, PixelFormat.Format24bppRgb));
success = FreeImage.Save(FREE_IMAGE_FORMAT.FIF_JPEG, bitmap, "output.jpg", FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYNORMAL);
FreeImage.Unload(bitmap);
Console.WriteLine("Success");
Console.Write("Test 2... ");
bitmap = FreeImage.CreateFromBitmap(new Bitmap(320, 240));
success = FreeImage.Save(FREE_IMAGE_FORMAT.FIF_JPEG, bitmap, "output.jpg", FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYNORMAL);
FreeImage.Unload(bitmap);
Console.WriteLine("Success");
}
static void OutputMessage(FREE_IMAGE_FORMAT format, string message)
{ throw new Exception(message);
}
[DllImport("FreeImage", EntryPoint = "FreeImage_SetOutputMessage")]
internal static extern void SetOutputMessage(OutputMessageFunction outputMessageFunction);
}
}