2014-12-04 4 views
0

Я использую C# FreeImage-обертку. Я пытаюсь открыть PDF-файл, содержащий изображения, и «извлечь» эти изображения в объекты Windows Bitmap. Я следуя инструкции, описанные в статьях в Интернете, следуя свободно следующую схему:Как диагностировать ошибки 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 имеет метод SetOutputMessage, который отображается FreeImageAPI.FreeImage .OutputMessageProc C# метод оболочки - но мне не очень понятно, как его использовать, поскольку он не является делегатом/принимает функцию как параметр ... вот еще одна ссылка, которая затрагивает проблему http://sourceforge.net/p/freeimage/discussion/36111/thread/8ccaebf8/ –

+0

, похоже, существует метод делегата FreeImageAPI.FreeImageEngine.Message, который принимает функции в обычном режиме путь через + =, но он, кажется, не вызван в моем случае - кстати, прямой вывод imgBytes (которые являются необработанными байтами объекта PDF-изображения) на диск дает то, что даже IrfanView не распознает как image –

+0

ok, насколько я понял, API freeimage также будет искать заголовок данных изображения для определения формата изображения - поэтому это не совсем лучше для того, что я хочу сделать, чем стандартные объекты System.Drawing, такие как Bitmap. кроме того, мне пришлось делать FlateDecode на необработанных байтах, если он указан в атрибуте Filter «pdfStream», после чего я прибегал к копированию по строкам данных необработанного изображения в новый объект Bitmap, правильно выравнивая с помощью Stride и т. д. как указано ниже –

ответ

0

Хотя, как представляется, функция SetOutputMessage не была добавлена ​​в библиотеку оболочки .NET, ее можно вызвать непосредственно из библиотеки FreeImage.

То есть, добавление функции в код с помощью:

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

Следующий код показывает выбросу исключения из функции Save, а не возвращать ложь (со следующим выходом консоли):

Test 1 ... Успех
Test 2 ...
Необработанное исключение: System.Exception: только 24-битный HighColor или 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 (String [] арг) в ... \ 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); 

    } 
} 
Смежные вопросы