Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
Hi, To resize scanned PDF you may try to use the following code. Please note This is example only and it will not work with all PDF files, it just illustrates the idea. But this example should work for all PDF documents created with OCR using the Tesseract.Net SDK. Also please note, the images does not resized actually, so they size (in bytes) is same as original images I have checked this code on the following file Source document: multipage.pdfresized document:  multipage_resized.pdf (1,017kb) downloaded 17 time(s).Code:
using Patagames.Pdf;
using Patagames.Pdf.Enums;
using Patagames.Pdf.Net;
using Patagames.Pdf.Net.BasicTypes;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication15
{
class Program
{
//The example will not work with all PDF files, it just illustrates the idea.
//But this example should work for all PDF documents created with recognition using the Tesseract.Net SDK.
static void Main(string[] args)
{
PdfCommon.Initialize();
float scaleFactor = 0.2f;
var doc = PdfDocument.Load(@"d:\1\multipage.pdf");
foreach(var page in doc.Pages)
{
//Get page's content
string content = page.Dictionary["Contents"].As<PdfTypeStream>().DecodedText;
//Set the size of the page. The size stored as MediaBox rectangle. It is an array of four numbers [0 0 width height]
var array = page.Dictionary["MediaBox"].As<PdfTypeArray>();
array[2].As<PdfTypeNumber>().FloatValue *= scaleFactor;
array[3].As<PdfTypeNumber>().FloatValue *= scaleFactor;
//Gets the images matrices
var cmMatrices = ExtractMatrices(content, "cm");
//Gets the matrices of the text objects
var tmMatrices = ExtractMatrices(content, "Tm");
//Multiply the matrix by the scaling factor. The resulting matrices are inserted back to the content line.
//For image's matrices
foreach (var matrix in cmMatrices)
{
matrix.Value.Scale(scaleFactor, scaleFactor);
content = ReplaceMatrix(content, matrix.Value, matrix.Key, "cm");
}
//For text's matrices
foreach (var matrix in tmMatrices)
{
matrix.Value.Scale(scaleFactor, scaleFactor);
content = ReplaceMatrix(content, matrix.Value, matrix.Key, "Tm");
}
//Create new content stream
var contentStream = CreateStream(doc, page);
//Store modified content to content stream
InitStream(Encoding.GetEncoding(1251).GetBytes(content), contentStream);
//Page dispose
page.Dispose();
}
//Save copy of the document
doc.Save(@"d:\1\multipage_resized.pdf", SaveFlags.NoIncremental);
}
private static string ReplaceMatrix(string content, FS_MATRIX matrix, string key, string suffix)
{
return content.Replace(key, string.Format("{0} {1} {2} {3} {4} {5} {6}", matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f, suffix));
}
private static Dictionary<string, FS_MATRIX> ExtractMatrices(string content, string suffix)
{
Regex r = new Regex(@"(\d{1,5}\s|\d{1,5}\.\d{1,5}\s){6}"+suffix);
var matches = r.Matches(content);
var ret = new Dictionary<string, FS_MATRIX>();
foreach (Match m in matches)
{
var key = m.Value;
var matrix = BuildMatrix(key);
ret.Add(key, matrix);
}
return ret;
}
private static FS_MATRIX BuildMatrix(string key)
{
char[] ch = { ' ' };
var arr = key.Split(ch, StringSplitOptions.RemoveEmptyEntries);
return new FS_MATRIX()
{
a = float.Parse(arr[0]),
b = float.Parse(arr[1]),
c = float.Parse(arr[2]),
d = float.Parse(arr[3]),
e = float.Parse(arr[4]),
f = float.Parse(arr[5]),
};
}
private static PdfTypeStream CreateStream(PdfDocument doc, PdfPage page)
{
//Set new content stream
var list = PdfIndirectList.FromPdfDocument(doc);
var contentStream = PdfTypeStream.Create();
int objNum = list.Add(contentStream);
var indirect = PdfTypeIndirect.Create(list, objNum);
page.Dictionary["Contents"] = indirect;
return contentStream;
}
private static void InitStream(byte[] data, PdfTypeStream contentStream)
{
var streamDict = PdfTypeDictionary.Create();
streamDict.Add("Length", PdfTypeNumber.Create(data.Length));
contentStream.Init(data, streamDict);
}
}
static class Helpers
{
/// <summary>
/// Converts the current instance to specified type.
/// </summary>
/// <typeparam name="T">The type the instance should be converted for.</typeparam>
/// <returns>Returns instance of type of T or throw an exception if type of this istance is not T.</returns>
/// <remarks>This instance may be a direct or inderect object of type T</remarks>
public static T As<T>(this PdfTypeBase item) where T : PdfTypeBase
{
if (item is T)
return item as T;
if (item is PdfTypeIndirect)
{
var direct = (item as PdfTypeIndirect).Direct;
if (direct is T)
return direct as T;
}
throw new Exception(string.Format("Unexpected type of object. Expected: {0}; Actual: {1}", typeof(T), item.GetType()));
}
}
}
Edited by user Monday, December 4, 2017 5:36:39 AM(UTC)
| Reason: Not specified
|