SharpPDF - 帮助提高图像质量 - pdf 规范

发布于 2024-10-03 12:31:44 字数 1401 浏览 1 评论 0原文

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

当我将结果与通过 iTextSharp 创建的 pdf 进行比较时,结果被严重压缩(不幸的是,这对我们来说是不行的,不要问我为什么)。

我注意到,在源代码中,有类似以下内容的内容:

//PDF's Images

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++;
    }

which in the runtime isn't like this

> 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 规范知识的人都可以帮助我找出压缩中可能出现的问题这里?

谢谢堆...

I'm having troubles with the (slightly outdated) .net library called sharpPDF. We are generating a few images from our gis web application and need to reference the images within this library. The only issue seems to be the compression that the library is using (or not using). The images are PNG32.

The outcome is quite heavily compressed when I compare the results with pdf created via iTextSharp (which is unfortunately a no go for us, don't ask me why).

I've noticed, that in the source code, there is something like the following:

//PDF's Images

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++;
    }

which in the runtime looks like this

> 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

can anyone, who has some pdf specification knowledge, help me out to figure out possible issues with the compression here?

thanks heaps...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮萍、无处依 2024-10-10 12:31:44

您看到的是为使用 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,您将必须收集逐行图像数据并使用扁平压缩( Ionic 的 zlib 很好)并手动压缩它。这一点很重要。

What you're seeing is a stream that is generated for a particular image that is being compressed with JPEG compression (DCTDecode = Discrete Cosine Transform = JPEG). I'm surprised that the PDF generator doesn't have options to select the codec for the image and configure it (for JPEG you should at least be able to set the image quality).

If you're compressing a color/grayscale image that you want to be lossless, you should use flate. If you are compressing a 1-bit image that you want to be lossless, you should be using CCITT.

If you want a lossy compression (more compression + artifacts) you should use JPEG or JPEG2000 on color/gray and JBIG2 on black and white.

From reading your comment, this is what you should do:

if you're content with JPEG, then you want to use the flavor of Image.Save that includes more codec information, like so:

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

For anything Flate, you will have to collect the image data row by row and use a flate compression (Ionic's zlib is good) and hand compress it. This is non-trivial.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文