我遇到了名为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规范知识的人都可以帮我解决压缩的可能问题吗?
谢谢堆......
答案 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很好)并手动压缩它。这不重要。