2014-12-04 66 views
0

我正在使用C#FreeImage包装。 我试图打开一个包含图像的PDF文件,并将这些图像“提取”到窗口位图对象中。我下面在互联网上的文章中描述的指导方针,遵循松散以下模式:如何诊断freeimage loadfromstream错误

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. 
         } 
        } 
       } 
      } 
     } 
    } 
} 

有谁知道如何解决这个建议,因为返回也不例外 - 某种GetLastError函数FreeImage的功能? 谢谢

+0

一些搜索我发现的FreeImage具有映射到一个FreeImageAPI.FreeImage方法SetOutputMessage .OutputMessageProc C#wrapper方法 - 但我不太清楚如何使用它 - 因为它看起来不是一个委托/将一个函数当作参数...这里是另一个触及问题的链接http://sourceforge.net/p/freeimage/discussion/36111/thread/8ccaebf8/ – 2014-12-04 16:42:13

+0

似乎存在一个委托方法FreeImageAPI.FreeImageEngine.Message,它接受通常的函数通过+ =的方式,但它似乎并没有在我的情况下被称为 - 通过imgBytes(这是PDF图像对象的原始字节)直接输出到磁盘给出的东西,即使IrfanView不承认作为图片 – 2014-12-05 12:57:45

+0

好吧,据我了解,freeimage API也会查找图像数据的头部以确定图像格式 - 因此,与标准的System.Drawing对象(比如位图)相比,它并不比我想要做的更好。此外,如果在pdfStream的Filter“属性”中指定了原始字节,我必须对原始字节执行FlateDecode--之后,我要求将原始图像数据逐行复制到新的Bitmap对象,使用Stride等进行正确对齐。正如下面指出的 – 2014-12-10 10:59:37

回答

0

尽管看起来SetOutputMessage函数没有添加到.NET包装库中,但可以直接从FreeImage库调用它。

也就是说,使用添加的功能代码:

[DllImport("FreeImage", EntryPoint = "FreeImage_SetOutputMessage")] 
    internal static extern void SetOutputMessage(OutputMessageFunction outputMessageFunction); 

下面的代码显示了保存功能被抛出,而不是返回假的异常(含以下控制台输出):

试验1 ...成功
试验2 ...
未处理的异常:System.Exception的:只有24位增强色或8位灰度/调色板的位图可以被保存为JPEG
在ConsoleApplication1.Program.OutputMessage(FREE_IMAGE_FORMAT格式,字符串消息)... \ ConsoleApplication1 \的Program.cs:行35
在FreeImageAPI.FreeImage.Save(FREE_IMAGE_FORMAT FIF,FIBITMAP DIB,字符串文件名,FREE_IMAGE_SAVE_FLAGS标志)
在ConsoleApplication1.Program.Main(字串[] args)在... \ ConsoleApplication1 \的Program.cs:行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); 

    } 
}