【发布时间】:2014-12-22 05:44:19
【问题描述】:
我正在尝试使用 iTextSharp 压缩 PDF。有很多页面将彩色图像存储为 JPEG(DCTDECODE)......所以我将它们转换为黑白 PNG 并在文档中替换它们(PNG 比黑白格式的 JPG 小得多)
我有以下方法:
private static bool TryCompressPdfImages(PdfReader reader)
{
try
{
int n = reader.XrefSize;
for (int i = 0; i < n; i++)
{
PdfObject obj = reader.GetPdfObject(i);
if (obj == null || !obj.IsStream())
{
continue;
}
var dict = (PdfDictionary)PdfReader.GetPdfObject(obj);
var subType = (PdfName)PdfReader.GetPdfObject(dict.Get(PdfName.SUBTYPE));
if (!PdfName.IMAGE.Equals(subType))
{
continue;
}
var stream = (PRStream)obj;
try
{
var image = new PdfImageObject(stream);
Image img = image.GetDrawingImage();
if (img == null) continue;
using (img)
{
int width = img.Width;
int height = img.Height;
using (var msImg = new MemoryStream())
using (var bw = img.ToBlackAndWhite())
{
bw.Save(msImg, ImageFormat.Png);
msImg.Position = 0;
stream.SetData(msImg.ToArray(), false, PdfStream.NO_COMPRESSION);
stream.Put(PdfName.TYPE, PdfName.XOBJECT);
stream.Put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.Put(PdfName.FILTER, PdfName.FLATEDECODE);
stream.Put(PdfName.WIDTH, new PdfNumber(width));
stream.Put(PdfName.HEIGHT, new PdfNumber(height));
stream.Put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
stream.Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
stream.Put(PdfName.LENGTH, new PdfNumber(msImg.Length));
}
}
}
catch (Exception ex)
{
Trace.TraceError(ex.ToString());
}
finally
{
// may or may not help
reader.RemoveUnusedObjects();
}
}
return true;
}
catch (Exception ex)
{
Trace.TraceError(ex.ToString());
return false;
}
}
public static Image ToBlackAndWhite(this Image image)
{
image = new Bitmap(image);
using (Graphics gr = Graphics.FromImage(image))
{
var grayMatrix = new[]
{
new[] {0.299f, 0.299f, 0.299f, 0, 0},
new[] {0.587f, 0.587f, 0.587f, 0, 0},
new[] {0.114f, 0.114f, 0.114f, 0, 0},
new [] {0f, 0, 0, 1, 0},
new [] {0f, 0, 0, 0, 1}
};
var ia = new ImageAttributes();
ia.SetColorMatrix(new ColorMatrix(grayMatrix));
ia.SetThreshold((float)0.8); // Change this threshold as needed
var rc = new Rectangle(0, 0, image.Width, image.Height);
gr.DrawImage(image, rc, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, ia);
}
return image;
}
我尝试了各种 COLORSPACE 和 BITSPERCOMPONENT,但在尝试打开生成的 PDF 时总是得到“图像数据不足”、“内存不足”或“此页面存在错误”...所以我一定做错了。我很确定 FLATEDECODE 是正确的选择。
任何帮助将不胜感激。
【问题讨论】:
-
你在用什么FLATEDECODE?那是ZIP压缩,你不是在找DCTDECODE(指的是JPEG压缩)吗?
-
在问题中 - 正如我所提到的,我正在尝试嵌入 PNG 格式
-
PNG 不能像 PDF 一样嵌入。请使用适当的 iTextSharp 图像类。
-
是的,他们可以。如果我使用新文档和提到的图像类,它们可以正常工作。我只想插入现有的
-
敌意、令人讨厌的回应不受欢迎。
标签: .net pdf itextsharp system.drawing