क्या पाइथन लाइब्रेरी का उपयोग करके पीडीएफ फाइल को उसके ग्रेस्केल समकक्ष में परिवर्तित करना संभव है? मैंने घोस्टस्क्रिप्ट मॉड्यूल को आजमाया है:

import locale
from io import BytesIO
import ghostscript as gs

ENCO = locale.getpreferredencoding()
STDOUT = BytesIO()
STDERR = BytesIO()

with open('adob_in.pdf', 'r') as infile:
    ARGS = f"""DUMMY -sOutputFile=adob_out.pdf -sDEVICE=pdfwrite
     -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray
     -dNOPAUSE -dBATCH {infile.name}"""

    ARGSB = [arg.encode(ENCO) for arg in ARGS.split()]

    gs.Ghostscript(*ARGSB, stdout=STDOUT, stderr=STDERR)

print(STDOUT.getvalue().decode(ENCO))
print(STDERR.getvalue().decode(ENCO))

मानक आउट और त्रुटि स्ट्रीम हैं:

GPL Ghostscript 9.52 (2020-03-19)
Copyright (C) 2020 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 1.
Page 1

दुर्भाग्य से, ग्रेस्केल पीडीएफ दूषित है। दरअसल, घोस्टस्क्रिप्ट के साथ डिबगिंग निम्न त्रुटि दिखाता है:

GPL Ghostscript 9.52 (2020-03-19)
Copyright (C) 2020 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
   **** Error: Cannot find a 'startxref' anywhere in the file.
               Output may be incorrect.
   **** Error:  An error occurred while reading an XREF table.
   **** The file has been damaged.  This may have been caused
   **** by a problem while converting or transfering the file.
   **** Ghostscript will attempt to recover the data.
   **** However, the output may be incorrect.
   **** Error:  Trailer dictionary not found.
                Output may be incorrect.
   No pages will be processed (FirstPage > LastPage).

   **** This file had errors that were repaired or ignored.
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.

   **** The rendered output from this file may be incorrect.
GS>

ध्यान दें कि स्ट्रिंग ARGS में वैध घोस्टस्क्रिप्ट कोड है (Linux कमांड लाइन में परीक्षण किया गया है, GPL Ghostscript 9.52 के साथ) और ARGSB स्ट्रिंग्स का संबंधित बाइनरी प्रतिनिधित्व है:

print(ARGSB)
[b'DUMMY', b'-sOutputFile=adob_out.pdf', b'-sDEVICE=pdfwrite', b'-sColorConversionStrategy=Gray', b'-dProcessColorModel=/DeviceGray', b'-dNOPAUSE', b'-dBATCH', b'adob_in.pdf']

यह कार्य ठीक से कैसे किया जा सकता था? मेरा उदाहरण इनपुट और आउटपुट फ़ाइलें यहां मिल सकती हैं। पहले से ही बहुत - बहुत धन्यवाद।

0
panadestein 22 जून 2020, 00:38
ईमानदार होने के लिए यह वास्तव में एक घोस्टस्क्रिप्ट प्रश्न नहीं है, क्योंकि आप कहते हैं कि यह कमांड खोल से सही तरीके से काम करता है। यदि यह आपके द्वारा उपयोग किए जा रहे तरीके से काम नहीं करता है, तो आपके द्वारा उपयोग किए जा रहे रैपर में समस्या होने की संभावना है। हालांकि यह पिछले चैनल के सभी को घोस्टस्क्रिप्ट से देखने में मदद करेगा, न कि केवल आपके द्वारा दिखाए गए बिट को।
 – 
KenS
22 जून 2020, 10:24
1
मुझे डर है कि मैं पाइथन लाइब्रेरी के बारे में तुरंत टिप्पणी नहीं कर सकता, क्योंकि मुझे पाइथन के बारे में बिल्कुल कुछ नहीं पता है। घोस्टस्क्रिप्ट स्पष्ट रूप से a फ़ाइल खोल रहा है, लेकिन मुझे आश्चर्य है कि क्या यह वास्तव में सही फ़ाइल खोल रहा है। त्रुटि संदेश बहुत स्पष्ट है कि यह पीडीएफ फाइल नहीं है। वास्तव में ऐसा लगता है कि यह आउटपुट फ़ाइल को इनपुट फ़ाइल के रूप में खोलने की कोशिश कर रहा है। क्या आपको आउटपुट फ़ाइल बिल्कुल मिलती है (0 बाइट्स से अधिक)? यदि ऐसा है तो क्या आप इसे कहीं सार्वजनिक कर सकते हैं? क्या आप प्रिंट कर सकते हैं कि वास्तव में *ARGSB में क्या निहित है?
 – 
KenS
22 जून 2020, 14:11
1
आह, मैंने आपकी मूल पोस्ट को गलत तरीके से पढ़ा! मैंने माना कि बैक चैनल आउटपुट पायथन रन से था, आउटपुट पीडीएफ फाइल को फिर से खोलने से नहीं .... हां आउटपुट फाइल आंशिक रूप से सही है, इसमें पेज कंटेंट स्ट्रीम है, लेकिन इसमें बहुत सी अन्य चीजें गायब हैं, इसकी वैध पीडीएफ फाइल नहीं है, ऐसा लगता है कि इसे छोटा कर दिया गया है। मुझे लगता है कि यह पायथन कोड चलाते समय कुछ त्रुटि के कारण है। क्या पाइथन रूपांतरण के दौरान stdout और stderr का आउटपुट प्राप्त करने का कोई तरीका है? मुझे ऐसा प्रतीत होता है कि वहां कुछ विफल हो रहा है जिससे पीडीएफ फाइल का केवल एक हिस्सा ही लिखा जा रहा है।
 – 
KenS
22 जून 2020, 15:32
1
ऐसा प्रतीत होता है, हाँ। मुझे डर है कि उस समय मैं और कुछ नहीं कर सकता जो मैं योगदान कर सकता हूं। चूंकि प्रक्रिया सामान्य रूप से कमांड लाइन से काम करती है, केवल एक ही संभावना है जिसके बारे में मैं सोच सकता हूं कि किसी तरह प्रक्रिया को पूरा होने से पहले समाप्त किया जा रहा है। लेकिन मैं वहां क्या हो रहा है, इस पर कोई अंतर्दृष्टि नहीं दे पा रहा हूं, मुझे अजगर के बारे में कुछ नहीं पता है।
 – 
KenS
23 जून 2020, 10:07
1
मैं देखता हूं कि आप बाइंडिंग का उपयोग करने के बजाय पायथन का उपयोग करके एक प्रक्रिया को जन्म दे सकते हैं, आप इसे आज़माना चाहेंगे और देखें कि क्या होता है। जो कोड मैं देख रहा हूं वह इस तरह दिखता है: os.system("gs -sOutputFile=adob_out.pdf -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dNOPAUSE -dBATCH adob_in.pdf") जाहिर है आप इससे बेहतर जान पाएंगे मुझे इसे उचित रूप से कैसे संशोधित किया जाए।
 – 
KenS
23 जून 2020, 11:07

1 उत्तर

सबसे बढ़िया उत्तर

मुझे नहीं पता कि इसे घोस्टस्क्रिप्ट के माध्यम से कैसे करना है, लेकिन निम्न कोड pdf2image और img2pdf इस उद्देश्य को पूरा करता है:

from os.path import join
from tempfile import TemporaryDirectory
from pdf2image import convert_from_path # https://pypi.org/project/pdf2image/
from img2pdf import convert # https://pypi.org/project/img2pdf/

with TemporaryDirectory() as temp_dir: # Saves images temporarily in disk rather than RAM to speed up parsing
    # Converting pages to images
    print("Parsing pages to grayscale images. This may take a while")
    images = convert_from_path(
        "your_pdf_path.pdf",
        output_folder=temp_dir,
        grayscale=True,
        fmt="jpeg",
        thread_count=4
    )

    image_list = list()
    for page_number in range(1, len(images) + 1):
        path = join(temp_dir, "page_" + str(page_number) + ".jpeg")
        image_list.append(path)
        images[page_number-1].save(path, "JPEG") # (page_number - 1) because index starts from 0

    with open("Gray_PDF.pdf", "bw") as gray_pdf:
        gray_pdf.write(convert(image_list))

    print("The new page is saved as Gray_PDF.pdf in the current directory.")

ग्रेस्केल छवि वाली पीडीएफ फाइल को उसी निर्देशिका में ग्रे_पीडीएफ.पीडीएफ के रूप में सहेजा जाएगा।

व्याख्या: निम्नलिखित कोड:

with TemporaryDirectory() as temp_dir: # Saves images temporarily in disk rather than RAM. This speeds up parsing
    # Converting pages to images
    print("Parsing pages to grayscale images. This may take a while")
    images = convert_from_path(
        "your_pdf_path.pdf",
        output_folder=temp_dir,
        grayscale=True,
        fmt="jpeg",
        thread_count=4
    )

निम्नलिखित कार्य करता है:

  1. PDF पृष्ठों को ग्रेस्केल छवियों में परिवर्तित करता है।
  2. इसे अस्थायी रूप से एक निर्देशिका में संग्रहीत करता है।
  3. एक सूची बनाता है images जनहित याचिका छवि वस्तुओं

अब निम्नलिखित कोड:

    image_list = list()
    for page_number in range(1, len(images) + 1):
        path = join(temp_dir, "page_" + str(page_number) + ".jpeg")
        image_list.append(path)
        images[page_number-1].save(path, "JPEG") # (page_number - 1) because index starts from 0

छवियों को फिर से उसी निर्देशिका में page_1.jpeg, page_2.jpeg आदि के रूप में सहेजता है। यह इन नई छवियों के पथों की एक सूची भी बनाता है।

अंत में, निम्नलिखित कोड:

    with open("Gray_PDF.pdf", "bw") as gray_pdf:
        gray_pdf.write(convert(image_list))

पहले बनाई गई ग्रेस्केल छवियों से ग्रे_पीडीएफ नामक एक पीडीएफ बनाता है और इसे कार्यशील निर्देशिका में सहेजता है।

अतिरिक्त युक्ति: यदि आप OpenCV का उपयोग करके अधिक छवि संसाधन संचालन करना चाहते हैं तो यह विधि आपको बहुत अधिक लचीलापन देती है क्योंकि सभी पृष्ठ अब छवियों के रूप में हैं। बस सुनिश्चित करें कि सभी ऑपरेशन पहले with स्टेटमेंट के अंदर हैं, यानी निम्नलिखित:

with TemporaryDirectory() as temp_dir: # Saves images temporarily in disk rather than RAM. This speeds up parsing
1
Gulshan Mishra 17 जिंदा 2021, 02:49