我試圖用iTextSharp壓縮PDF文件。有很多彩色圖像存儲爲JPEG(DCTDECODE)的頁面...所以我將它們轉換爲黑白PNG並在文檔中替換它們(PNG比黑白格式的JPG小得多)PDF轉換爲黑白PNG
我有以下幾種方法:
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;
}
我試過品種的色彩空間和BITSPERCOMPONENTs的,但總是得到「沒有足夠的數據圖像」,「內存不足」或「錯誤存在於這個頁面「試圖打開生成的PDF文件...所以我一定是做錯了。我很確定FLATEDECODE是正確的使用方式。
任何援助將不勝感激。
你在用什麼FLATEDECODE?這是ZIP壓縮,你不是在尋找DCTDECODE(它指的是JPEG壓縮)嗎? – 2014-10-27 13:33:49
在問題中 - 正如我所提到的,我試圖嵌入PNG格式 – Jeff 2014-10-27 14:13:31
PNG無法像嵌入PDF一樣嵌入。請使用適當的iTextSharp圖像類。 – mkl 2014-10-31 09:50:09