sharpPDF - 图像质量的帮助 - pdf规范

时间:2010-11-19 11:44:13

标签: pdf pdf-generation

我遇到了名为sharpPDF的(稍微过时的).net库的麻烦。我们正在从我们的gis Web应用程序生成一些图像,并需要引用此库中的图像。唯一的问题似乎是库正在使用(或不使用)的压缩。图像是PNG32。

当我将结果与通过iTextSharp创建的pdf进行比较时,结果得到了极大的压缩(不幸的是,我们没有这样做,不要问我为什么)。

我注意到,在源代码中,有如下内容:

// PDF的图片

foreach (pdfImageReference image in _images.Values)
    {
     _trailer.addObject(_bufferLength.ToString());
     _bufferLength += writeToBuffer(_myBuffer, image.getText());
     _bufferLength += writeToBuffer(_myBuffer, "stream" + Convert.ToChar(13) + Convert.ToChar(10));
     _bufferLength += writeToBuffer(_myBuffer, image.content);
     _bufferLength += writeToBuffer(_myBuffer, Convert.ToChar(13).ToString());
     _bufferLength += writeToBuffer(_myBuffer, Convert.ToChar(10).ToString());
     _bufferLength += writeToBuffer(_myBuffer, "endstream" + Convert.ToChar(13) + Convert.ToChar(10));
     _bufferLength += writeToBuffer(_myBuffer, "endobj" + Convert.ToChar(13) + Convert.ToChar(10));
                    currentStep++;
    }

在运行时中看起来像这样

> 60517 0 obj << /Type /XObject /Subtype
> /Image /Name /I60517 /Filter
> /DCTDecode /Width 830 /Height 1300
> /BitsPerComponent 8 /ColorSpace
> /DeviceRGB /Length 77076
> >> stream
> -here goes some bytes- endstream endobj

任何具有一些pdf规范知识的人都可以帮我解决压缩的可能问题吗?

谢谢堆......

1 个答案:

答案 0 :(得分:0)

您所看到的是为使用JPEG压缩压缩的特定图像生成的流(DCTDecode =离散余弦变换= JPEG)。我很惊讶PDF生成器没有选择图像编解码器和配置它的选项(对于JPEG,你至少应该能够设置图像质量)。

如果要压缩想要无损的彩色/灰度图像,则应使用flate。如果要压缩想要无损的1位图像,则应使用CCITT。

如果你想要有损压缩(更多压缩+工件),你应该在彩色/灰色上使用JPEG或JPEG2000,在黑白上使用JBIG2。

通过阅读您的评论,您应该这样做:

如果您对JPEG感兴趣,那么您希望使用包含更多编解码器信息的Image.Save风格,如下所示:

private static ImageCodecInfo GetEncoderInfo(String mimeType)
{    
    int j;
    ImageCodecInfo[] encoders;
    encoders = ImageCodecInfo.GetImageEncoders();
    for(j = 0; j < encoders.Length; ++j)
    {
        if(encoders[j].MimeType == mimeType)
            return encoders[j];
    }
    return null;
}

Stream GetImageStream(Image image, int compression)
{
    EncoderParameters eps = new EncoderParameters(1);
    eps.Param[0] = new EncoderParameter( Encoder.Quality, (long)compression);
    ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
    if (codecInfo == null) throw new Exception("No jpeg codec - WTF?"); // use better message
    MemoryStream stream = new MemoryStream();
    image.Save(stream, codecInfo, eps);
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
}

对于任何Flate,你必须逐行收集图像数据并使用flate压缩(Ionic's zlib很好)并手动压缩它。这不重要。