zippy1978 / ghost4j

Java wrapper for Ghostscript C API + PS/PDF document handling API
http://www.ghost4j.org
GNU Lesser General Public License v3.0
64 stars 38 forks source link

Bounding Box error when converting PDF to PDF-A/1 #70

Open jstaerk opened 4 years ago

jstaerk commented 4 years ago

Hi, With the code below I get (with GS 9.52 on Mac) a

Ghotscript error output: %%BoundingBox: 0 0 599 845
%%HiResBoundingBox: 0,000000 0,000000 598,805982 844,091974

I had installed ghostscript I think using brew and of course downloaded an appropriate .ICC file, placed it as absolute filename in the PDFA_def.ps which I had moved to /usr/local/Cellar/ghostscript/9.52/share/ghostscript/9.52/Resource/ and made the .dylib available using export LD_LIBRARY_PATH=/usr/local/Cellar/ghostscript/9.52/lib/.

-> It actually works from command line like /usr/local/Cellar/ghostscript/9.52/bin/gs -P -dPDFA=1 -sGenericResourceDir=/usr/local/Cellar/ghostscript/9.52/share/ghostscript/9.52/Resource/ -sColorConversionStrategy=RGB -sDEVICE=pdfwrite -o/Users/jstaerk/temp/out.pdf -dPDFACompatibilityPolicy=1 /usr/local/Cellar/ghostscript/9.52/share/ghostscript/9.52/Resource/PDFA_def.ps /Users/jstaerk/temp/in.pdf

My java code is

 public void pdf2pdfa(InputStream fileInputStream) {
        try {
            Ghostscript gs = Ghostscript.getInstance();
            DiskStore diskStore = DiskStore.getInstance();
            String diskStoreKey = diskStore.generateUniqueKey();
            synchronized (gs) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ByteArrayOutputStream err = new ByteArrayOutputStream();
                gs.setStdOut(out);
                gs.setStdErr(err);

                String inputFilename = "/Users/jstaerk/temp/in.pdf";
                File tempInputFile = new File(inputFilename);
                String outputFilename = "/Users/jstaerk/temp/out.pdf";
                java.nio.file.Files.copy(
                        fileInputStream,
                        tempInputFile.toPath(),
                        StandardCopyOption.REPLACE_EXISTING);

                String[] gsArgs = {"-q", "-P", "-dPDFA=1", "-sGenericResourceDir=/usr/local/Cellar/ghostscript/9.52/share/ghostscript/9.52/Resource/", "-sColorConversionStrategy=RGB",
                        "-o" + diskStore.addFile(diskStoreKey).getAbsolutePath(), "-dPDFACompatibilityPolicy=1",
                        "/usr/local/Cellar/ghostscript/9.52/share/ghostscript/9.52/Resource/PDFA_def.ps", tempInputFile.getPath()};
                try {
                    File outputFile = diskStore.getFile(diskStoreKey);
                    gs.initialize(gsArgs);
                    if (outputFile == null) {
                        throw new ConverterException("Cannot retrieve file with key "
                                + diskStoreKey + " from disk store");
                    }
                    outputFile.renameTo(new File(outputFilename));
                    gs.exit();
                    Ghostscript.deleteInstance();
                    diskStore.removeFile(diskStoreKey);
                } catch (GhostscriptException e) {
                    System.out.println("ERROR: " + e.getMessage());
                }

                System.out.println("Ghostscript outout: " + out);
                System.out.println("Ghotscript error output: " + err);
                System.out.println("2pdfa from " + tempInputFile.getPath() + " to " + outputFilename);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

and the PDFA_def.ps file is, as mentioned

%!
% This is a sample prefix file for creating a PDF/A document.
% Feel free to modify entries marked with "Customize".
% This assumes an ICC profile to reside in the file (ISO Coated sb.icc),
% unless the user modifies the corresponding line below.

% Define entries in the document Info dictionary :
/ICCProfile (/usr/local/Cellar/ghostscript/9.52/share/ghostscript/9.52/Resource/AdobeRGB1998.icc) % Customise
def

[ /Title (Title)       % Customise
  /DOCINFO pdfmark

% Define an ICC profile :

[/_objdef {icc_PDFA} /type /stream /OBJ pdfmark
[{icc_PDFA}
<<
  /N currentpagedevice /ProcessColorModel known {
    currentpagedevice /ProcessColorModel get dup /DeviceGray eq
    {pop 1} {
      /DeviceRGB eq
      {3}{4} ifelse
    } ifelse
  } {
    (ERROR, unable to determine ProcessColorModel) == flush
  } ifelse
>> /PUT pdfmark
[{icc_PDFA} ICCProfile (r) file /PUT pdfmark

% Define the output intent dictionary :

[/_objdef {OutputIntent_PDFA} /type /dict /OBJ pdfmark
[{OutputIntent_PDFA} <<
  /Type /OutputIntent             % Must be so (the standard requires).
  /S /GTS_PDFA1                   % Must be so (the standard requires).
  /DestOutputProfile {icc_PDFA}            % Must be so (see above).
  /OutputConditionIdentifier (sRGB)      % Customize
>> /PUT pdfmark
[{Catalog} <</OutputIntents [ {OutputIntent_PDFA} ]>> /PUT pdfmark

Any idea anyone?

billy9222 commented 1 year ago

Hi, I am stuck exactly at this point in my implementation. Did you find the solution already or is it a dead end?