Преобразование TIFF в PDF приводит к недостаточному количеству данных для изображения - PullRequest
0 голосов
/ 25 января 2012

У меня есть утилита, которая преобразует пакеты изображений TIFF в PDF-файлы с помощью библиотеки PDFSharp.Следующий код выполняет фактическое преобразование.Когда я открываю полученные PDF-файлы в Acrobat Reader, я получаю сообщение об ошибке, в котором указано «Недостаточно данных для изображения».Другие в порядке.

Что может быть причиной этого?Чего-то не хватает в коде, который мог бы предотвратить это?

Public Shared Function ConvertImageToPDF(ByVal img As Image) As Byte()
    Using ms As New MemoryStream()
        Using pdf As New PdfDocument()
            Dim pageCount = GetPageCount(img)

            For index = 0 To (pageCount - 1)
                Dim page = New PdfPage()

                Using sourceImage = GetPage(img, index)
                    Using pageImage = XImage.FromGdiPlusImage(sourceImage)
                        page.Width = pageImage.PointWidth
                        page.Height = pageImage.PointHeight

                        pdf.Pages.Add(page)

                        Using xgr = XGraphics.FromPdfPage(pdf.Pages(index))
                            xgr.DrawImage(pageImage, 0, 0)
                        End Using
                    End Using
                End Using
            Next

            pdf.Save(ms, False)
            pdf.Close()
        End Using

        Return ms.ToArray()
    End Using
End Function

Public Shared Function GetPageCount(ByVal img As Image) As Integer
    If (img Is Nothing) Then
        Return -1
    End If

    Return img.GetFrameCount(FrameDimension.Page)
End Function

Public Shared Function GetPage(ByVal img As Image, ByVal pageNumber As Integer) As Image
    img.SelectActiveFrame(FrameDimension.Page, pageNumber)

    Dim ms = New MemoryStream()
    img.Save(ms, ImageFormat.Tiff)

    Return Image.FromStream(ms)
End Function

ОБНОВЛЕНИЕ:

Если я запускаю один и тот же код для тех же файлов TIFF, то файлы PDF, которые былиповрежденные ранее - теперь все в порядке, а те, которые были исправлены - теперь повреждены.

ОБНОВЛЕНИЕ 2:

После рассмотрения этой проблемы подключения (https://connect.microsoft.com/VisualStudio/feedback/details/584681/system-drawing-image-flags-has-different-value-in-vista-and-windows-7) и комментариев сообщества к этому MSDNстраница (http://msdn.microsoft.com/en-us/library/system.drawing.image.save.aspx), кажется, что проблема связана с ошибкой уровня операционной системы в Windows 7. Может кто-нибудь подтвердить это или предложить обходной путь?

1 Ответ

0 голосов
/ 01 февраля 2012

Как указано в моем обновлении, после рассмотрения этой проблемы с подключением (https://connect.microsoft.com/VisualStudio/feedback/details/584681/system-drawing-image-flags-has-different-value-in-vista-and-windows-7) и комментариев сообщества на этой странице MSDN (http://msdn.microsoft.com/en-us/library/system.drawing.image.save.aspx),, похоже, проблема связана с ошибкой на уровне операционной системы Windows).7.

Это поддерживается комментарием из PDFsharpTeam.

Кроме того, когда изображения читаются в Windows XP, свойство flags для объекта изображения устанавливается в 77888. В Win7,для него установлено значение 77840. После просмотра документации MSDN для свойства flags (http://msdn.microsoft.com/en-us/library/system.drawing.image.flags.aspx), разница в том, что WinXP пометил изображение как изображение в градациях серого (которое у меня), а Win7 пометил его как изображение RGB.похоже, является признаком проблемы, но я недостаточно знаю о форматах изображений и цветовых пространствах, чтобы говорить об этом авторитетно.

ОБНОВЛЕНИЕ (2014-06-13):

После того, как я продолжил сталкиваться с этой проблемой, я немного углубился в поиск и нашел на форумах PDFSharp сообщение с упоминанием этой проблемы и ссылкой на другое сообщение с исправлением.

http://forum.pdfsharp.net/viewtopic.php?f=2&t=2729

http://forum.pdfsharp.net/viewtopic.php?p=5967#p5967

По сути, в файле PdfImage.FaxEncode.cs есть два метода, которые необходимо обновить.

В обоихCountOneBits() и CountZeroBits(), замените следующий код:

return found + hits;

на

found += hits;
if (found >= bitsLeft)
  return bitsLeft;
return found;
...