C# 如何诊断freeimage loadfromstream错误

C# 如何诊断freeimage loadfromstream错误,c#,pdf,freeimage,C#,Pdf,Freeimage,我使用的是C#FreeImage包装器。 我试图打开一个包含图像的PDF文件,并将这些图像“提取”到windows位图对象中。我遵循互联网文章中描述的指导原则,大致遵循以下模式: byte[] bytes = GetPdfFile(); iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(bytes); int pageNumber = 0; for (int i = 0; i <= read

我使用的是C#FreeImage包装器。 我试图打开一个包含图像的PDF文件,并将这些图像“提取”到windows位图对象中。我遵循互联网文章中描述的指导原则,大致遵循以下模式:

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.
                        }
                    }
                }
            }
        }
    }
}
byte[]bytes=GetPdfFile();
iTextSharp.text.pdf.PdfReader=新的iTextSharp.text.pdf.PdfReader(字节);
int pageNumber=0;

对于(int i=0;i,尽管SetOutputMessage函数似乎没有添加到.NET包装器库中,但可以直接从FreeImage库调用它

也就是说,使用以下方法将函数添加到代码中:

  [DllImport("FreeImage", EntryPoint = "FreeImage_SetOutputMessage")]
  internal static extern void SetOutputMessage(OutputMessageFunction outputMessageFunction);
以下代码显示从Save函数引发的异常,而不是返回false(使用以下控制台输出):

测试1…成功
测试2…
未处理的异常:系统。异常:只能将24位highcolor或8位灰度/调色板位图保存为JPEG
在ConsoleApplication1.Program.OutputMessage(免费图像格式,字符串消息)…\ConsoleApplication1\Program.cs:第35行
在FreeImageAPI.FreeImage.Save(自由图像格式fif、FIBITMAP dib、字符串文件名、自由图像保存标志)
在…\ConsoleApplication1\Program.cs中的ConsoleApplication1.Program.Main(字符串[]args)处:第28行


通过一些搜索,我发现FreeImage有一个SetOutputMessage方法,它映射到FreeImageAPI.FreeImage.OutputMessageProc C#wrapper方法-但我不太清楚如何使用它-因为它似乎不是一个委托/将函数作为参数…这里有另一个与问题相关的链接,似乎存在一个委托方法od FreeImageAPI.FreeImageEngine.Message,它通过+=,以通常的方式接受函数,但在我的例子中,它似乎没有被调用-通过imgBytes(PDF图像对象的原始字节)的直接输出to disk提供了一些连IrfanView都无法识别为imageok的东西,据我所知,freeimage API还将查找图像数据的标题以确定图像格式-因此,它并不比标准系统更好。绘制位图之类的对象。此外,我还必须在原始图像上执行FlateCode字节,如果在筛选器“属性”中指定在pdfStream之后,我求助于将原始图像数据逐行复制到一个新的位图对象,使用Stride等正确对齐。正如下面所指出的,我仍然不知道如何在加载图像时捕获FreeImage给出的异常,这仍然很烦人,但这可能是微不足道的,因为在大多数情况下,FreeImage无法读取图像的标题,即图像数据的格式不正确/或不受支持。。。
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);

   }
}