दिलचस्प पोस्ट
जावास्क्रिप्ट पर ब्राउजर आँकड़े निष्क्रिय पता लगाएँ कि मूल्य MySQL में नंबर है क्या LINQ क्वेरी में ToList () या ToArray () को कॉल करना बेहतर है? अजगर खोल में मौजूदा निर्देशिका को कैसे जानना / बदलना है? स्ट्रटोक विभाजन की गलती PHP सेटलोकाले का कोई प्रभाव नहीं है जावा – पढ़ना, जोड़ना और WAV फ़ाइलों को लिखना मैं ज्येथोन में विभिन्न पायथन लाइब्रेरी कैसे स्थापित कर सकता हूं? Filezilla और SFTP का उपयोग करते हुए अमेज़ॅन EC2 फ़ाइल निर्देशिका से कनेक्ट करें शुद्ध PHP में HTTP पुनर्निर्देशन के बाद अंतिम URL कैसे प्राप्त करें? स्विफ्ट के लिए UITableView उदाहरण आर .5 में से ऊपर कैनवास छवि क्रॉसप्लेफ़ेट असुरक्षित त्रुटि JFrame आइकन कैसे परिवर्तित करें जावा – छवि से पिक्सेल सरणी प्राप्त करें

मर्ज पर व्हाइसेस्पेस को कैसे निकालें

मेरे पास कुछ कोड है जो 3 अलग पीडीएफ बाइट सरणियों को लेता है और उन्हें विलय कर लेता है। यह कोड महान काम करता है मुद्दा (कुछ लोग) है कि प्रत्येक पीडीएफ एक पूर्ण पृष्ठ माना जाता है (यदि मुद्रित किया गया है) भले ही उस पर सामग्री के 4 इंच ही कहें, इस प्रकार इसने 7 इंच के सफेद अंतरिक्ष को खड़ी छोड़ दिया। फिर मध्य दस्तावेज़ में डाल दिया जाता है और इसके अंत में ऊर्ध्वाधर सफेद स्थान नहीं हो सकता है या नहीं। फिर पाद लेख को अपने स्वयं के पृष्ठ पर भी डाल दिया जाता है

यहां कोड है:

byte[] Bytes = rv.LocalReport.Render("PDF", null, out MimeType, out Encoding, out Extension, out StreamIDs, out Warnings); List<byte[]> MergeSets = // This is filled prior to this code // Append any other pages to this primary letter if (MergeSets.Count > 0) { MemoryStream ms = new MemoryStream(); Document document = new Document(); PdfCopy copy = new PdfCopy(document, ms); document.Open(); PdfImportedPage page; PdfReader reader = new PdfReader(Bytes); // read the generated primary Letter int pages = reader.NumberOfPages; for (int i = 0; i < pages; ) { page = copy.GetImportedPage(reader, ++i); copy.AddPage(page); } // foreach of the pages in the Cover Letter // Now append the merge sets foreach (byte[] ba in MergeSets) { reader = new PdfReader(ba); pages = reader.NumberOfPages; for (int i = 0; i < pages; ) { page = copy.GetImportedPage(reader, ++i); copy.AddPage(page); } // foreach of the pages in the current merge set } // foreach of the sets of data document.Close(); ServerSaved = SaveGeneratedLetter(ms.GetBuffer(), DateTime.Now.Year, hl.LetterName, SaveName); } // if there is anything to merge 

क्या कोई तरीका है जब मैं प्रत्येक पृष्ठ को प्रत्येक पीडीएफ के अंत में ऊर्ध्वाधर सफेद स्थान को क्लिप / निकालने / मिटाने के लिए मर्ज कर रहा हूं, तो यह एक निर्बाध दस्तावेज़ के रूप में प्रकट होता है?

अद्यतनः यहां कुछ नमूना। पीडीएफ फाइलें हैं I मर्ज करने की कोशिश कर रहा हूं I

शीर्षलेख , शरीर , पादलेख

2 अद्यतन: उत्तर का उपयोग करना:

मैंने @ एमकेएल का कोड C # पर बदल दिया है और यहां यह है।

उपकरण वर्ग:

 public class PdfVeryDenseMergeTool { private Rectangle PageSize; private float TopMargin; private float BottomMargin; private float Gap; private Document Document = null; private PdfWriter Writer = null; private float YPosition = 0; public PdfVeryDenseMergeTool(Rectangle size, float top, float bottom, float gap) { this.PageSize = size; this.TopMargin = top; this.BottomMargin = bottom; this.Gap = gap; } // PdfVeryDenseMergeTool public void Merge(MemoryStream outputStream, List<PdfReader> inputs) { try { this.OpenDocument(outputStream); foreach (PdfReader reader in inputs) { this.Merge(reader); } // foreach of the PDF files to merge } finally { this.CloseDocument(); } // try-catch-finally } // Merge public void OpenDocument(MemoryStream outputStream) { this.Document = new Document(PageSize, 36, 36, this.TopMargin, this.BottomMargin); this.Writer = PdfWriter.GetInstance(Document, outputStream); this.Document.Open(); this.NewPage(); } // OpenDocument public void CloseDocument() { try { this.Document.Close(); } finally { this.Document = null; this.Writer = null; this.YPosition = 0; } // try-finally } // CloseDocument public void NewPage() { this.Document.NewPage(); this.YPosition = PageSize.GetTop(this.TopMargin); } // Merge public void Merge(PdfReader reader) { PdfReaderContentParser parser = new PdfReaderContentParser(reader); for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++) { this.Merge(reader, parser, pageIndex); } // foreach of the pages of the current PDF } // Merge public void Merge(PdfReader reader, PdfReaderContentParser parser, int pageIndex) { PdfImportedPage importedPage = Writer.GetImportedPage(reader, pageIndex); PdfContentByte directContent = Writer.DirectContent; PageVerticalAnalyzer finder = parser.ProcessContent(pageIndex, new PageVerticalAnalyzer()); if (finder.VerticalFlips.Count < 2) return; Rectangle pageSizeToImport = reader.GetPageSize(pageIndex); int startFlip = finder.VerticalFlips.Count - 1; bool first = true; while (startFlip > 0) { if (!first) this.NewPage(); float freeSpace = this.YPosition - PageSize.GetBottom(BottomMargin); int endFlip = startFlip + 1; while ((endFlip > 1) && (finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip - 2] < freeSpace)) endFlip -= 2; if (endFlip < startFlip) { float height = finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip]; directContent.SaveState(); directContent.Rectangle(0, this.YPosition - height, pageSizeToImport.Width, height); directContent.Clip(); directContent.NewPath(); this.Writer.DirectContent.AddTemplate(importedPage, 0, this.YPosition - (finder.VerticalFlips[startFlip] - pageSizeToImport.Bottom)); directContent.RestoreState(); this.YPosition -= height + this.Gap; startFlip = endFlip - 1; } else if (!first) { throw new ArgumentException(string.Format("Page {0} content too large", pageIndex)); } // if first = false; } // while } // Merge } // PdfVeryDenseMergeTool 

RenderListener वर्ग:
3 अद्यतन: कोड की एक लाइन तय की गई और यह काम करता है: कोड में टिप्पणी देखें

 public class PageVerticalAnalyzer : IRenderListener { public PageVerticalAnalyzer() { } public List<float> VerticalFlips = new List<float>(); public void AddVerticalUseSection(float from, float to) { if (to < from) { float temp = to; to = from; from = temp; } int i = 0; int j = 0; for (i = 0; i < VerticalFlips.Count; i++) { float flip = VerticalFlips[i]; if (flip < from) continue; for (j = i; j < VerticalFlips.Count; j++) { flip = VerticalFlips[j]; if (flip < to) continue; break; } break; } // foreach of the vertical flips bool fromOutsideInterval = i % 2 == 0; bool toOutsideInterval = j % 2 == 0; while (j-- > i) VerticalFlips.RemoveAt(j); // This was the problem line with just .Remove(j) if (toOutsideInterval) VerticalFlips.Insert(i, to); if (fromOutsideInterval) VerticalFlips.Insert(i, from); } // AddVerticalUseSection public void BeginTextBlock() { /* Do nothing */ } public void EndTextBlock() { /* Do nothing */ } public void RenderImage(ImageRenderInfo renderInfo) { Matrix ctm = renderInfo.GetImageCTM(); List<float> YCoords = new List<float>(4) { 0, 0, 0, 0 }; for (int x = 0; x < 2; x++) { for (int y = 0; y < 2; y++) { Vector corner = new Vector(x, y, 1).Cross(ctm); YCoords[2 * x + y] = corner[Vector.I2]; } } YCoords.Sort(); AddVerticalUseSection(YCoords[0], YCoords[3]); } // RenderImage public void RenderText(TextRenderInfo renderInfo) { LineSegment ascentLine = renderInfo.GetAscentLine(); LineSegment descentLine = renderInfo.GetDescentLine(); List<float> YCoords = new List<float>(4) { ascentLine.GetStartPoint()[Vector.I2], ascentLine.GetEndPoint()[Vector.I2], descentLine.GetStartPoint()[Vector.I2], descentLine.GetEndPoint()[Vector.I2], }; YCoords.Sort(); AddVerticalUseSection(YCoords[0], YCoords[3]); } // RenderText } // PageVericalAnalyzer 

कोड इकट्ठा करने और उपकरण चलाने के लिए कोड:

 public void TestMergeDocuments() { PdfVeryDenseMergeTool tool = new PdfVeryDenseMergeTool(iTextSharp.text.PageSize.A4, 18, 18, 10); List<byte[]> Files = new List<byte[]>(); // Code to load each of the 3 files I need into this byte array list using (MemoryStream ms = new MemoryStream()) { List<PdfReader> files = new List<PdfReader>(); foreach (byte[] ba in Files) { files.Add(new PdfReader(ba)); } // foreach of the sets of data tool.Merge(ms, files); // Save the file using: ms.GetBuffer() } // using the memory stream } // TestMergeDocuments 

वेब के समाधान से एकत्रित समाधान "मर्ज पर व्हाइसेस्पेस को कैसे निकालें"

निम्नलिखित नमूना उपकरण को इस उत्तर से उपकरण PdfDenseMergeTool के विचारों के साथ लागू किया गया है जिसमें ओ.पी. ने टिप्पणी की है ताकि वह [उस] की आवश्यकता के करीब हो जैसे PdfDenseMergeTool यह उपकरण यहां जावा / PdfDenseMergeTool में कार्यान्वित किया जाता है जो मैं सी # / iTextSharp से अधिक घर पर हूं। जैसा कि ओपी ने पहले से ही PdfDenseMergeTool को सी # / iTextSharp में अनुवाद किया है, यहां इस उपकरण का अनुवाद भी बहुत बड़ी समस्या नहीं होनी चाहिए।

PdfVeryDenseMergeTool

इसी तरह PdfDenseMergeTool लिए यह उपकरण कई PdfReader इंस्टेंसेस से पृष्ठों की पेज की सामग्री लेता है और उन्हें घनी तरह से मर्ज करने की कोशिश करता है, यानी एक ही पेज पर कई स्रोत पृष्ठों की सामग्री डालने पर ऐसा करने के लिए पर्याप्त जगह नहीं है। उस पहले के उपकरण के विपरीत, यह टूल स्रोत पेज की सामग्री को भी एक भी घनीभूत मर्ज के लिए अनुमति देता है।

बस उस अन्य उपकरण की तरह PdfVeryDenseMergeTool खाते में वेक्टर ग्राफिक्स नहीं लेती क्योंकि PdfVeryDenseMergeTool (Sharp) पार्सिंग एपीआई केवल पाठ और बिटमैप छवियों को आगे PdfVeryDenseMergeTool है

PdfVeryDenseMergeTool स्रोत पृष्ठों को विभाजित करता है जो एक क्षैतिज रेखा पर लक्ष्य पृष्ठ पर पूरी तरह से फिट नहीं होते हैं, जो टेक्स्ट ग्लिफ़ या बिटमैप ग्राफ़िक्स के बाउंडिंग बॉक्स द्वारा प्रतिच्छेदन नहीं करता है।

उपकरण वर्ग:

 public class PdfVeryDenseMergeTool { public PdfVeryDenseMergeTool(Rectangle size, float top, float bottom, float gap) { this.pageSize = size; this.topMargin = top; this.bottomMargin = bottom; this.gap = gap; } public void merge(OutputStream outputStream, Iterable<PdfReader> inputs) throws DocumentException, IOException { try { openDocument(outputStream); for (PdfReader reader: inputs) { merge(reader); } } finally { closeDocument(); } } void openDocument(OutputStream outputStream) throws DocumentException { final Document document = new Document(pageSize, 36, 36, topMargin, bottomMargin); final PdfWriter writer = PdfWriter.getInstance(document, outputStream); document.open(); this.document = document; this.writer = writer; newPage(); } void closeDocument() { try { document.close(); } finally { this.document = null; this.writer = null; this.yPosition = 0; } } void newPage() { document.newPage(); yPosition = pageSize.getTop(topMargin); } void merge(PdfReader reader) throws IOException { PdfReaderContentParser parser = new PdfReaderContentParser(reader); for (int page = 1; page <= reader.getNumberOfPages(); page++) { merge(reader, parser, page); } } void merge(PdfReader reader, PdfReaderContentParser parser, int page) throws IOException { PdfImportedPage importedPage = writer.getImportedPage(reader, page); PdfContentByte directContent = writer.getDirectContent(); PageVerticalAnalyzer finder = parser.processContent(page, new PageVerticalAnalyzer()); if (finder.verticalFlips.size() < 2) return; Rectangle pageSizeToImport = reader.getPageSize(page); int startFlip = finder.verticalFlips.size() - 1; boolean first = true; while (startFlip > 0) { if (!first) newPage(); float freeSpace = yPosition - pageSize.getBottom(bottomMargin); int endFlip = startFlip + 1; while ((endFlip > 1) && (finder.verticalFlips.get(startFlip) - finder.verticalFlips.get(endFlip - 2) < freeSpace)) endFlip -=2; if (endFlip < startFlip) { float height = finder.verticalFlips.get(startFlip) - finder.verticalFlips.get(endFlip); directContent.saveState(); directContent.rectangle(0, yPosition - height, pageSizeToImport.getWidth(), height); directContent.clip(); directContent.newPath(); writer.getDirectContent().addTemplate(importedPage, 0, yPosition - (finder.verticalFlips.get(startFlip) - pageSizeToImport.getBottom())); directContent.restoreState(); yPosition -= height + gap; startFlip = endFlip - 1; } else if (!first) throw new IllegalArgumentException(String.format("Page %s content sections too large.", page)); first = false; } } Document document = null; PdfWriter writer = null; float yPosition = 0; final Rectangle pageSize; final float topMargin; final float bottomMargin; final float gap; } 

( पीडीएफविरडेन्स मेर्जटूल.जावा )

यह टूल iText पार्सर एपीआई के उपयोग के लिए कस्टम RenderListener का उपयोग करता है:

 public class PageVerticalAnalyzer implements RenderListener { @Override public void beginTextBlock() { } @Override public void endTextBlock() { } /* * @see RenderListener#renderText(TextRenderInfo) */ @Override public void renderText(TextRenderInfo renderInfo) { LineSegment ascentLine = renderInfo.getAscentLine(); LineSegment descentLine = renderInfo.getDescentLine(); float[] yCoords = new float[]{ ascentLine.getStartPoint().get(Vector.I2), ascentLine.getEndPoint().get(Vector.I2), descentLine.getStartPoint().get(Vector.I2), descentLine.getEndPoint().get(Vector.I2) }; Arrays.sort(yCoords); addVerticalUseSection(yCoords[0], yCoords[3]); } /* * @see RenderListener#renderImage(ImageRenderInfo) */ @Override public void renderImage(ImageRenderInfo renderInfo) { Matrix ctm = renderInfo.getImageCTM(); float[] yCoords = new float[4]; for (int x=0; x < 2; x++) for (int y=0; y < 2; y++) { Vector corner = new Vector(x, y, 1).cross(ctm); yCoords[2*x+y] = corner.get(Vector.I2); } Arrays.sort(yCoords); addVerticalUseSection(yCoords[0], yCoords[3]); } /** * This method marks the given interval as used. */ void addVerticalUseSection(float from, float to) { if (to < from) { float temp = to; to = from; from = temp; } int i=0, j=0; for (; i<verticalFlips.size(); i++) { float flip = verticalFlips.get(i); if (flip < from) continue; for (j=i; j<verticalFlips.size(); j++) { flip = verticalFlips.get(j); if (flip < to) continue; break; } break; } boolean fromOutsideInterval = i%2==0; boolean toOutsideInterval = j%2==0; while (j-- > i) verticalFlips.remove(j); if (toOutsideInterval) verticalFlips.add(i, to); if (fromOutsideInterval) verticalFlips.add(i, from); } final List<Float> verticalFlips = new ArrayList<Float>(); } 

( पृष्ठवैशिष्टिक विश्लेषक.जावा )

इसका उपयोग इस प्रकार किया जाता है:

 PdfVeryDenseMergeTool tool = new PdfVeryDenseMergeTool(PageSize.A4, 18, 18, 5); tool.merge(output, inputs); 

(बहुत डाटा मैर्जिंग.जावा )

ओपी नमूना दस्तावेजों के लिए लागू

Header.pdf

हेडर पीडीएफ पृष्ठ

Body.pdf

Body.pdf पृष्ठ

Footer.pdf

Footer.pdf पृष्ठ

यह उत्पन्न करता है

ए 4 बहुत घने मर्ज परिणाम

यदि कोई लक्ष्य दस्तावेज़ पृष्ठ आकार ए 5 लैंडस्केप के रूप में परिभाषित करता है:

 PdfVeryDenseMergeTool tool = new PdfVeryDenseMergeTool(new RectangleReadOnly(595,421), 18, 18, 5); tool.merge(output, inputs); 

(बहुत डाटा मैर्जिंग.जावा )

यह यह उत्पन्न करता है:

ए 5 बहुत घना मर्ज परिणाम

सावधान रहें! यह केवल अवधारणा का प्रमाण है और यह सभी संभावनाओं पर विचार नहीं करता है। उदाहरण के लिए स्रोत या लक्ष्य पृष्ठों के मामले में एक गैर तुच्छ rotate मान के साथ ठीक से संभाला नहीं है। इस प्रकार, यह अभी तक उत्पादन का उपयोग करने के लिए तैयार नहीं है।


वर्तमान में सुधार (5.5.6 SNAPSHOT) iText संस्करण

वर्तमान आईटेक्स्ट विकास संस्करण 5.5.6 की तरफ वेक्टर ग्राफिक्स को भी संकेत देने के लिए पारसर की कार्यक्षमता को बढ़ाता है। इस प्रकार, मैंने इस का उपयोग करने के लिए PageVerticalAnalyzer को बढ़ा दिया है:

 public class PageVerticalAnalyzer implements ExtRenderListener { @Override public void beginTextBlock() { } @Override public void endTextBlock() { } @Override public void clipPath(int rule) { } ... static class SubPathSection { public SubPathSection(float x, float y, Matrix m) { float effectiveY = getTransformedY(x, y, m); pathFromY = effectiveY; pathToY = effectiveY; } void extendTo(float x, float y, Matrix m) { float effectiveY = getTransformedY(x, y, m); if (effectiveY < pathFromY) pathFromY = effectiveY; else if (effectiveY > pathToY) pathToY = effectiveY; } float getTransformedY(float x, float y, Matrix m) { return new Vector(x, y, 1).cross(m).get(Vector.I2); } float getFromY() { return pathFromY; } float getToY() { return pathToY; } private float pathFromY; private float pathToY; } /* * Beware: The implementation is not correct as it includes the control points of curves * which may be far outside the actual curve. * * @see ExtRenderListener#modifyPath(PathConstructionRenderInfo) */ @Override public void modifyPath(PathConstructionRenderInfo renderInfo) { Matrix ctm = renderInfo.getCtm(); List<Float> segmentData = renderInfo.getSegmentData(); switch (renderInfo.getOperation()) { case PathConstructionRenderInfo.MOVETO: subPath = null; case PathConstructionRenderInfo.LINETO: case PathConstructionRenderInfo.CURVE_123: case PathConstructionRenderInfo.CURVE_13: case PathConstructionRenderInfo.CURVE_23: for (int i = 0; i < segmentData.size()-1; i+=2) { if (subPath == null) { subPath = new SubPathSection(segmentData.get(i), segmentData.get(i+1), ctm); path.add(subPath); } else subPath.extendTo(segmentData.get(i), segmentData.get(i+1), ctm); } break; case PathConstructionRenderInfo.RECT: float x = segmentData.get(0); float y = segmentData.get(1); float w = segmentData.get(2); float h = segmentData.get(3); SubPathSection section = new SubPathSection(x, y, ctm); section.extendTo(x+w, y, ctm); section.extendTo(x, y+h, ctm); section.extendTo(x+w, y+h, ctm); path.add(section); case PathConstructionRenderInfo.CLOSE: subPath = null; break; default: } } /* * @see ExtRenderListener#renderPath(PathPaintingRenderInfo) */ @Override public Path renderPath(PathPaintingRenderInfo renderInfo) { if (renderInfo.getOperation() != PathPaintingRenderInfo.NO_OP) { for (SubPathSection section : path) addVerticalUseSection(section.getFromY(), section.getToY()); } path.clear(); subPath = null; return null; } List<SubPathSection> path = new ArrayList<SubPathSection>(); SubPathSection subPath = null; ... } 

( पृष्ठवैशिष्टिक विश्लेषक.जावा )

एक साधारण परीक्षण (बहुत डाटा मैर्जिंग.जावा विधि testMergeOnlyGraphics ) इन फ़ाइलों में विलीन हो जाती है

circlesOnlyA.pdf

circlesOnlyB.pdf

circlesOnlyC.pdf

circlesOnlyD.pdf

इस मामले में:

circlesOnlyMerge-veryDense.pdf

लेकिन एक बार फिर से सावधान रहें: यह अवधारणा का एकमात्र प्रमाण है विशेष रूप से modifyPath() को modifyPath() आवश्यकता है, कार्यान्वयन सही नहीं है क्योंकि इसमें modifyPath() के नियंत्रण बिंदु भी शामिल हैं जो वास्तविक वक्र से बाहर हो सकते हैं।