Luv*_*Luv 19 c# pdf pdf-generation
我一直在谷歌上搜索如何压缩现有pdf
(大小).我的问题是
我不能使用任何应用程序,因为它需要由C#程序完成.
我不能使用任何付费图书馆,因为我的客户不想退出预算.因此,PAID库肯定是NO
我做了最近2天的家庭工作,并使用iTextSharp,BitMiracle找到了一个解决方案但无济于事,因为前者只减少了1%的文件而后来的一个是付费的.
我也遇到了PDFcompressNET和pdftk,但我找不到他们的.dll.
实际上,pdf是保险单,有2-3张图像(黑白),大约70页,大小为5 MB.
我只需要pdf的输出(不能是任何其他格式)
pli*_*nth 14
这是一种方法(这应该工作而不考虑您使用的工具包):
如果您有24位rgb或32位cmyk映像,请执行以下操作:
也就是说,如果你能以无人监督的方式完成所有这些工作,那么你就拥有了自己的商业产品.
我会说你可以用Atalasoft dotImage完成大部分工作(免责声明:它不是免费的;我在那里工作;我写过几乎所有的PDF工具;我曾经在Acrobat上工作).
使用dotImage的一个特殊方法是拉出所有只有图像的页面,重新压缩它们并将它们保存到新的PDF中,然后通过获取原始文档中的所有页面并将它们替换为重新压缩的页面来构建新的PDF,然后再次保存.这并不难.
List<int> pagesToReplace = new List<int>();
PdfImageCollection pagesToEncode = new PdfImageCollection();
using (Document doc = new Document(sourceStream, password)) {
for (int i=0; i < doc.Pages.Count; i++) {
Page page = doc.Pages[i];
if (page.SingleImageOnly) {
pagesToReplace.Add(i);
// a PDF image encapsulates an image an compression parameters
PdfImage image = ProcessImage(sourceStream, doc, page, i);
pagesToEncode.Add(i);
}
}
PdfEncoder encoder = new PdfEncoder();
encoder.Save(tempOutStream, pagesToEncode, null); // re-encoded pages
tempOutStream.Seek(0, SeekOrigin.Begin);
sourceStream.Seek(0, SeekOrigin.Begin);
PdfDocument finalDoc = new PdfDocument(sourceStream, password);
PdfDocument replacementPages = new PdfDocument(tempOutStream);
for (int i=0; i < pagesToReplace.Count; i++) {
finalDoc.Pages[pagesToReplace[i]] = replacementPages.Pages[i];
}
finalDoc.Save(finalOutputStream);
Run Code Online (Sandbox Code Playgroud)
这里缺少的是ProcessImage().ProcessImage将栅格化页面(您不需要了解图像可能已缩放到PDF上)或提取图像(并跟踪图像上的变换矩阵),并完成上面列出的步骤.这是非常重要的,但它是可行的.
我想你可能想让你的客户知道你提到的任何库都不是完全免费的:
鉴于以上所有,我认为我可以放弃免费软件的要求.
Docotic.Pdf可以在不引入任何破坏性更改的情况下将压缩和未压缩PDF的大小减小到不同程度.
增益取决于PDF的大小和结构:对于大多数扫描图像的小文件或文件,缩小可能不是那么好,因此您应该尝试使用文件库并亲自查看.
如果您最关心尺寸并且文件中有许多图像,并且您可以放弃这些图像的某些质量,那么您可以使用Docotic.Pdf轻松地重新压缩现有图像.
以下代码使所有图像通过传真压缩进行双层和压缩:
static void RecompressExistingImages(string fileName, string outputName)
{
using (PdfDocument doc = new PdfDocument(fileName))
{
foreach (PdfImage image in doc.Images)
image.RecompressWithGroup4Fax();
doc.Save(outputName);
}
}
Run Code Online (Sandbox Code Playgroud)
还有RecompressWithFlate
,RecompressWithGroup3Fax
和RecompressWithJpeg
方法.
如果需要,库将把彩色图像转换为双层图像.您可以指定deflate压缩级别,JPEG质量等.
Docotic.Pdf还可以在PDF中调整大图像(并同时重新压缩它们).如果文档中的图像实际上比需要的更大或图像质量不那么重要,这可能很有用.
下面是一个代码,可以对所有宽度或高度大于或等于256的图像进行缩放.然后使用JPEG压缩对缩放后的图像进行编码.
public static void RecompressToJpeg(string path, string outputPath)
{
using (PdfDocument doc = new PdfDocument(path))
{
foreach (PdfImage image in doc.Images)
{
// image that is used as mask or image with attached mask are
// not good candidates for recompression
if (!image.IsMask && image.Mask == null && (image.Width >= 256 || image.Height >= 256))
image.Scale(0.5, PdfImageCompression.Jpeg, 65);
}
doc.Save(outputPath);
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用其中一种ResizeTo
方法将图像调整为指定的宽度和高度.请注意,该ResizeTo
方法不会尝试保留图像的宽高比.你应该自己计算适当的宽度和高度.
免责声明:我为Bit Miracle工作.
使用PdfSharp
public static void CompressPdf(string targetPath)
{
using (var stream = new MemoryStream(File.ReadAllBytes(targetPath)) {Position = 0})
using (var source = PdfReader.Open(stream, PdfDocumentOpenMode.Import))
using (var document = new PdfDocument())
{
var options = document.Options;
options.FlateEncodeMode = PdfFlateEncodeMode.BestCompression;
options.UseFlateDecoderForJpegImages = PdfUseFlateDecoderForJpegImages.Automatic;
options.CompressContentStreams = true;
options.NoCompression = false;
foreach (var page in source.Pages)
{
document.AddPage(page);
}
document.Save(targetPath);
}
}
Run Code Online (Sandbox Code Playgroud)