16 Replies Latest reply: Jul 10, 2012 12:14 PM by Droptix RSS

    PDDocColorConvertPage - Convert color pages to gray

    Droptix Community Member

      I want to convert a specified color page to gray programmatically using `PDDocColorConvertPage` with Dot Gain 15% as I would do it in Acrobat 9 Pro manually. In the API reference the syntax is explained but I don't understand it, especially `PDColorConvertParams`.

       

      Is there anyone who can post a short example of code?

       

      I'm trying to achieve this via COM-programming and Python. An example in VB, JavaScript or similar is also great.

       

      Thanks in advance!

        • 1. Re: PDDocColorConvertPage - Convert color pages to gray
          lrosenth Adobe Employee

          PDDocColorConvertPage and PDColorConvertParams are C/C++ methods and data structures – you can get to them from COM or Python.

           

          In order to convert the page from COM/Python, you will need to use the JavaScript method for color conversion.  Details in the docs.

           

          FYI: Acrobat can't be used on a server….

          • 2. Re: PDDocColorConvertPage - Convert color pages to gray
            Droptix Community Member

            I'm not the big C/C++ geek and always have difficulties finding the right parts in the docs. So can you post a link where exactly this is described?

             

            Sorry, but I don't understand the mix between COM/Python and JavaScript... isn't it possible to use the `PDDocColorConvertPage` API call directly via COM? Also important for where to find this in the docs.

             

            In the past I wrote some programs using COM to control Acrobat, e.g. to rotate, delete or insert pages. So I know all the basic stuff. I think I'm just looking for about 5-10 lines of code doing the right API call syntax. If somebody can help out with a short example this would really help me to go on. Thanks in advance.

            • 3. Re: PDDocColorConvertPage - Convert color pages to gray
              khkremer CommunityMVP

              The Acrobat SDK consists of different parts:

              - plug-in and PDF library API - these are functions you can call from

              C/C++, but only within a plug-in or an application that uses the PDFL. The

              API function yo are trying to use is part of this interface and not

              available via COM.

              - Inter Application Commuication (IAC) interface - these are e.g. COM

              methods that you can call from your Python program

              - JavaScript - an API to automate Acrobat with JavaScript programs that are

              either embedded in PDF files, or stored on your computer.

               

              In general, you cannot cross API boundaries, but there is a way to execute

              JavaScript in an application that uses the COM interface. Take a look at

              the documentation that is part of the SDK, this is all documented, and

              there are sample programs that come with the SDK. You will however not find

              any Python programs in the SDK - you need to map the use of the COM

              interface from VB to Python.

               

              Here is a link to a blog post I wrote a few years ago about how to use

              JavaScript from within a VB program:

              http://www.khk.net/wordpress/2009/03/11/acrobat-javascript-and-vb-walk-into-a-bar/

               

               

              Karl Heinz Kremer

              PDF Acrobatics Without a Net

               

              khk@khk.net

              http://www.khkonsulting.com

              • 4. Re: PDDocColorConvertPage - Convert color pages to gray
                Droptix Community Member

                Hi Karl Heinz, I tried your scripts but didn't get them working... :-(

                 

                First, I wrote a simple JavaScript as you did and saved it to `C:\Program Files (x86)\Adobe\Acrobat 9.0\Acrobat\Javascripts\GrayConversion.js`:

                function GrayConversion() {

                  var message = "The magic happens here...";

                  console.clear();

                  console.show();

                  console.println(message);

                  return message;

                }

                 

                 

                // add the menu item

                app.addMenuItem({

                     cName: "grayConversion",

                     cUser: "Gray Conversion",

                     cParent: "Document",

                     cExec: "GrayConversion();",

                     cEnable: "event.rc = (event.target != null);"

                });

                 

                When I restart Acrobat there's no new menu item. I also checked the tick box as you described here. As I'm using the German Acrobat, I also tried `cParent: "Dokument",`. Can you figure out what is wrong with it? Is there any name convention for the .js file? Does Acrobat automatically "scan" the Javascripts-folder and "includes" all of them?

                 

                Are you still sure that it's not possible to use the `PDDocColorConvertPage`via COM? I don't understand why some parts work and others won't. Is the API some kind of incomplete?

                 

                The other thing is also interesting that you said: do you think it's possible to call that API by an application using PDFL?

                 

                I did something similar to what you are describing with InDesign some years ago :-) So I appreciate for any tips and hints... I don't see the mistake.

                • 5. Re: PDDocColorConvertPage - Convert color pages to gray
                  khkremer CommunityMVP

                  I don't have a Windows version of Acrobat 9 handy, I was only able to test

                  with Acrobat X, and the menu item does show up (after changing "Document"

                  to "File" because AX does not have a Document menu anymore).

                   

                  The "Document" name is a language independent name, so  you have to use

                  that even with the German version of Acrobat. Are you sure that your path

                  is correct? You can easily test that by running a JavaScript command (take

                  a look at this blog post:

                  http://khkonsulting.com/2010/12/acrobat-javascripts-where-do-they-go/ )

                   

                  Acrobat will automatically load anything that has a .js extension if it's

                  stored in either the user or the application level JavaScript directory.

                   

                  The different APIs are not compatible with each other - you can only call

                  JavaScript methods from within JavaScript (with the exception of using the

                  JS bridge), you can call COM methods only when using COM, and you can call

                  the Acrobat/PDFL functions only when writing an Acrobat plug-in or a PDFL

                  based program.  You could write your own COM server in form of a plug-in,

                  and make other functions available via a COM interface, but the standard

                  IAC API does not provide anything besides what is documented in the SDK IAC

                  documentation.

                   

                  If you have a license for the PDFL, then you can certainly call this

                  function (and any of the other functions that are part of the Acrobat/PDFL

                  API) from your own application.

                   

                  Karl Heinz Kremer

                  PDF Acrobatics Without a Net

                   

                  khk@khk.net

                  http://www.khkonsulting.com

                  • 6. Re: PDDocColorConvertPage - Convert color pages to gray
                    Droptix Community Member

                    Aaah, it was probably a permission problem because of Windows' UAC (user account control), so adding menu items via JavaScript was not allowed. I first tried to set this feature as a non-admin user using the `runas` command. But after logging on as the admin user showed that Adobe still did not allow JavaScript to add menu items...

                     

                    Now, when using `Document` and after opening a PDF file in Acrobat (as admin user) the new command is visible as a menu item and it works.

                     

                    First step done :-) Thanks! Also, app.getPath("app", "javascript"); shows that my JavaScript path is correct.

                     

                    Now I have to find out how to convert a color page to gray using 15% dot gain. I found some code snippets doing color conversion with profiles... not the same but the right direction. I'll give it a try and still appreciate any useful ideas to achieve this :-)

                     

                    This is really hard for me because I'm missing a full explanation/documentation of the `PDDocColorConvertPage` API, especially `PDColorConvertParams`.

                     

                    [Edit:] Huh, my Python 2.6 script tells me this when calling `jso.GrayConversion()`:

                    com_error: (-2147467263, 'Nicht implementiert', None, None)

                    Meaning: "not implemented". Seems like it cannot find the JavaScript function `GrayConversion()`?

                     

                    Everything seems to be fine until `GetJSObject()`. Here's my code:

                    import sys

                    import os

                    import win32com.client

                     

                    def main():

                        App = win32com.client.Dispatch("AcroExch.App")

                        PDDoc = win32com.client.Dispatch("AcroExch.PDDoc")

                        PDDoc.Open("file.pdf")

                        jso = PDDoc.GetJSObject()

                        print jso.GrayConversion()

                     

                    if __name__ == "__main__":

                        main()

                    • 7. Re: PDDocColorConvertPage - Convert color pages to gray
                      Droptix Community Member

                      Sorry, Karl Heinz, but I don't get it... even after 6 days of searching and trying. It's a big strain

                       

                      My status right now is that I'm using VB script because Python's COM binding do something strange... with VB script the COM-JS-connection works fine.

                       

                      I found this link that seems to be very useful and very close to what I need it's about the AcroColor extended API:

                       

                      But I cannot "transform" it into JavaScript...

                       

                      Pleeeeeeaaaaase, are you able to transform this into JavaScript code for me and post it here? I visited your homepage and it seems that you could do it because you have the experience and you understand what's going on in Acrobat. I'd really appreciate!

                       

                      Also: is it possible just to replace `AC_Profile_AppleRGB` with `AC_Profile_DotGain15`? See the reference here.

                      • 8. Re: PDDocColorConvertPage - Convert color pages to gray
                        lrosenth Adobe Employee

                        You are, STILL, trying to use the C++ APIs from JavaScript.

                         

                        You want the JavaScript API at http://livedocs.adobe.com/acrobat_sdk/9.1/Acrobat9_1_HTMLHelp/wwhelp/wwhimpl/js/html/wwhel p.htm?href=JS_API_AcroJS.88.1.html#1515776&accessible=true

                         

                        Look at the doc.colorConvertPage() API.

                        • 9. Re: PDDocColorConvertPage - Convert color pages to gray
                          khkremer CommunityMVP

                          Just because you find a function somewhere in the Acrobat SDK documentation

                          does not mean you can use it in your program: As I said before, you cannot

                          cross API boundaries, if you have a function that is described in the

                          plug-in API, you can only use it in an Acrobat plug-in (or in most cased,

                          in an application that uses the PDFL). You need to stick to the API that

                          your application can use (e.g. as lrosenth pointed out, a function from the

                          JavaScript API when you try to either write a JavaScript program, or if you

                          want to use the JS bridge).

                           

                          This is not a question of the level of experience somebody has, it's just

                          not possible to do that.

                           

                          Karl Heinz Kremer

                          PDF Acrobatics Without a Net

                           

                          khk@khk.net

                          http://www.khkonsulting.com

                          • 10. Re: PDDocColorConvertPage - Convert color pages to gray
                            phibbus

                            I have a situation slightly different but similar enough in nature not to require a new thread.  While I'm using Acrobat X on Win7, I think most everything I'm doing remains consistent in Acrobat 9, and it may help shed some common light.

                             

                            In my case, I am trying to call  "colorConvertPage" (the Javascript API version Iorsenth recommends, above, and not the "PDDocColorConvertPage" exposed by the C++ API) from a VBscript via  the JSObject.  My problem is that I cannot figure out how to correctly configure and pass the two arrays of "colorConvertAction" objects that the JavaScript method requires as its second and third parameters.

                             

                            The purpose of the script is to merge large numbers of TIFFs into multiple PDFs, combining them based on a filename schema.  After each document is created, I want the script to convert all of the page images to sRGB before saving.

                             

                            I have been able to implement Mr. Kremer's method of creating a native Acrobat folder-level JavaScript to perform the color conversion and then calling that from the VBscript.  The Javascript is taken almost verbatim from the example given under the "getColorConvertAction" method in the Acrobat X JavaScript API Reference, only changing the profile to sRGB and then adding the loop through all the pages and a slight modification of Karl's code to add the function as a menu item under Edit:

                             

                            function ConvertAllTosRGB()

                            {

                                // Get a color convert action

                                var toRGB = this.getColorConvertAction();

                                // Set up the action for a conversion to RGB

                                toRGB.matchAttributesAny = -1;

                                toRGB.matchSpaceTypeAny = ~toRGB.constants.spaceFlags.AlternateSpace;

                                toRGB.matchIntent = toRGB.constants.renderingIntents.Any;

                                toRGB.convertProfile = "sRGB IEC61966-2.1";

                                toRGB.convertIntent = toRGB.constants.renderingIntents.Document;

                                toRGB.embed = true;

                                toRGB.preserveBlack = false;

                                toRGB.useBlackPointCompensation = true;

                                toRGB.action = toRGB.constants.actions.Convert;

                                // Convert the first each page of the document

                             

                                for(var i = 0; i < this.numPages; i++) {

                                    var result = this.colorConvertPage(i,[toRGB],[]);

                                }

                            }

                             

                            // add the menu item

                            app.addMenuItem({

                                 cName: "ConvertAllTosRGB",

                                 cUser: "Convert Doc To sRGB",

                                 cParent: "Edit",

                                 cExec: "ConvertAllTosRGB();",

                                 cEnable: "event.rc = (event.target != null);"

                            });

                             

                            Once that .js is dropped into one of Acrobat's script folders, the function can be successfully called from vbs with "jso..ConvertAllTosRGB" (where "jso" is a JSObject successfully created by a call to a PDDoc's .GetJSObject method.)

                             

                            Where I'm running into trouble is in trying to replicate that JavaScript function within the VBscript itself (which would be more convenient than having to distribute two separate scripts.)  I can successfully create a colorConvertAction object, however I can't seem to successfully cast that object as one in an array to pass to colorConvertPage (nor create the empty array to pass as the third parameter.)  The pertinent portions of the scipt are something like...

                             

                            Dim AcroApp

                            Dim AVDoc

                            Dim PDDoc

                            Dim jso

                            Dim toRGB

                            Dim i

                            Dim result

                             

                            Set AcroApp = CreateObject("AcroExch.App")

                            Set AVDoc = CreateObject("AcroExch.AVDoc")

                             

                            If AVDoc.Open("c:\path\some.tif"), "") Then

                                 Set PDDoc = AVDoc.GetPDDoc

                                 Set jso = PDDoc.GetJSObject

                                 Set toRGB = jso.getColorConvertAction

                             

                                 With toRGB

                                      .matchAttributesAny = -1

                                      .matchSpaceTypeAny = Not .constants.spaceFlags.AlternateSpace

                                      .matchIntent = .constants.renderingIntents.Any

                                      .convertProfile = "sRGB IEC61966-2.1"

                                      .convertIntent = .constants.renderingIntents.Document

                                      .embed = True

                                      .preserveBlack = False

                                      .useBlackPointCompensation = True

                                      .action = .constants.actions.Convert

                                 End With

                             

                                 For i = 0 to PDDoc.GetNumPages - 1

                                      result = jso.colorConvertPage(i, ????, ????)

                                      MsgBox(result)

                                 Next

                             

                            End If

                             

                            Everything up to the call to jso.colorConvertPage works fine.  However, as stated, no method that I've tried to pass the toRGB object as an array member (as called for by the second "actions" parameter) has worked.  These include declaring the variable as an array and using the Array function.  Nor have I been able to pass an empty array for the third "inkActions" parameter without throwing an error.

                             

                            Interestingly, passing the toRGB object itself, directly, as both parameters does not raise any errors.  However, the function then returns a null value and no conversion actually takes place.

                            • 11. Re: PDDocColorConvertPage - Convert color pages to gray
                              Droptix Community Member

                              I hope you were posting your answer a few days ago to avoid my headaches because one day before you posted this I found the solutionn for my problem in the right docs.

                               

                              ^^ As I mentioned it's not hard to code this but to find the right place is much more difficult... but now I got it. Thanks to everybody here!

                               

                              phibbus, I think your way is too complicated. Why don't you rename your JS function from `ConvertAllTosRGB()` to `ConvertAll(toProfile)` and submit an additional argument? `toProfile` then would be either "sRGB IEC61966-2.1" or "Apple RGB"... just an example. Of course you could submit any argument to your function. Like this:

                              function ConvertAll(toProfile)

                              {

                                  // ...

                                  toAny.convertProfile = toProfile;

                                  // ...

                              }

                              What exactly are you trying to change in your VB script?

                              • 12. Re: PDDocColorConvertPage - Convert color pages to gray
                                phibbus Community Member

                                Hi Droptix,

                                 

                                I'm glad you got it working.  What method did you wind up using?

                                 

                                Yes, the JavaScript function could certainly be made much more versatile by rewriting it to accept the conversion profile and other of the colorConvertAction's properties as arguments.  I was mainly just doing a quick retool of the SDK documentation example by way of illustration.

                                 

                                The thing I'm trying to ascertain in the VBscript is whether or not it is possible to successfully call colorConvertPage from an external automation script using the JSObject bridge (i.e., accomplish the same thing that the JavaScript example does without having to first install the folder level script.)

                                • 13. Re: PDDocColorConvertPage - Convert color pages to gray
                                  Droptix Community Member

                                  No folder level script is a cool idea and this works for me. Pleast test it and give a short feedback:

                                  Set argv = Wscript.Arguments

                                  inFile = argv(0)
                                  outFile = argv(1)
                                  strPages = argv(2)

                                  Set App = CreateObject("AcroExch.App")
                                  Set PDDoc = CreateObject("AcroExch.PDDoc")

                                  ' open the PDF to get access to the JavaScript object
                                  PDDoc.Open(inFile)

                                  Set jso = PDDoc.GetJSObject

                                  ' now open the file again, but using JSObject
                                  Set doc = jso.app.openDoc(inFile)

                                  ' do color conversion
                                  Set target = doc.getColorConvertAction
                                  target.matchAttributesAny = -1
                                  target.matchSpaceTypeAny = Not target.constants.spaceFlags.AlternateSpace
                                  target.matchIntent = target.constants.renderingIntents.Any
                                  target.convertProfile = "Dot Gain 15%"
                                  target.convertIntent = target.constants.renderingIntents.Document
                                  target.embed = True
                                  target.preserveBlack = False
                                  target.useBlackPointCompensation = True
                                  target.action = target.constants.actions.Convert

                                  ' convert first page (0) to gray
                                  doc.colorConvertPage 0, Array(target), Array()

                                  ' save converted document to `outFile`
                                  doc.saveAs(outFile)

                                  doc.closeDoc(True)

                                  ' close document
                                  PDDoc.Close

                                  ' exit and close Acrobat
                                  App.Exit

                                  ' clean up
                                  Set PDDoc = Nothing
                                  Set App = Nothing

                                  Now here's the batch file I'm using for this one:

                                  :go

                                  cls

                                  cscript.exe /nologo GrayConversion2.vbs "D:\folder\subfolder\in.pdf" "D:\folder\subfolder\out.pdf" 1,3,6,7,8

                                  pause

                                  goto go

                                  What I need to do now is to go through the page numbers and auto-convert the ones specified by the script arguments (1,3,6,7,8). Maybe you got a good idea?

                                  • 14. Re: PDDocColorConvertPage - Convert color pages to gray
                                    phibbus Community Member

                                    Hi Droptix,

                                     

                                    I tested your code, and yes, it did work for me (with the exception noted below.)  I see that my mistake was trying to call colorConvertPage as a method of the JSObject, itself, rather than as a method of a JavaScript Doc opened through the JSObject.

                                     

                                    I'm not quite certain what you're trying to do with the goto loop in your batch file.  Do you have multiple .pdf files that need converting, or is it just that single file with multiple pages?

                                     

                                    In any event, given the single call to GrayConversion2.vbs in the .bat, the following simple modifications to your .vbs should work (but, again, see the exception, afterward.)  Modifications are in red:

                                     

                                    Set argv = Wscript.Arguments

                                    inFile = argv(0)
                                    outFile = argv(1)
                                    arrPages = Split(argv(2), ",")

                                    Set App = CreateObject("AcroExch.App")
                                    Set PDDoc = CreateObject("AcroExch.PDDoc")

                                    ' open the PDF to get access to the JavaScript object
                                    PDDoc.Open(inFile)

                                    Set jso = PDDoc.GetJSObject

                                    ' now open the file again, but using JSObject
                                    Set doc = jso.app.openDoc(inFile)

                                    ' do color conversion
                                    Set target = doc.getColorConvertAction
                                    target.matchAttributesAny = -1
                                    target.matchSpaceTypeAny = Not target.constants.spaceFlags.AlternateSpace
                                    target.matchIntent = target.constants.renderingIntents.Any
                                    target.convertProfile = "Dot Gain 15%"
                                    target.convertIntent = target.constants.renderingIntents.Document
                                    target.embed = True
                                    target.preserveBlack = False
                                    target.useBlackPointCompensation = True
                                    target.action = target.constants.actions.Convert

                                    ' convert array of Pages (adjusting for 0 first page) to gray

                                    For i = 0 to Ubound(arrPages)

                                         doc.colorConvertPage arrPages(i)-1, Array(target), Array()

                                    Next

                                    ' save converted document to `outFile`
                                    doc.saveAs(outFile)

                                    doc.closeDoc(True)

                                    ' close document
                                    PDDoc.Close

                                    ' exit and close Acrobat
                                    App.Exit

                                    ' clean up
                                    Set PDDoc = Nothing
                                    Set App = Nothing

                                     

                                    That works when run from the .bat as you have it, except:  The call to colorConvertPage fails on the fifth call for me each time.  I'm using a test .pdf that I created, and I've tried varying the order and number of the pages to be converted.  It doesn't appear to be anything specific to the content of the .pdf.  After four successful calls (with the conversion visiblly completed,) the method fails on the fifth call and gives a "Server threw an exception" error.  I must then hard-quit Acrobat from the Task Manager to be able to test the script again. 

                                    • 15. Re: PDDocColorConvertPage - Convert color pages to gray
                                      Droptix Community Member

                                      Ah yes my batch file... it's just a loop to re-start the batch after I press Enter... makes testing easier for me :-) Just ignore it and just use the single line instead... but then the CLI window closes and I would have to double-click it again... annoying :-P Sorry, I'm lazy

                                      cscript.exe /nologo GrayConversion2.vbs "D:\folder\subfolder\in.pdf" "D:\folder\subfolder\out.pdf" 1,3,6,7,8

                                      P.S. I've not tested it but I think there's a typo in your script mod:

                                      doc.colorConvertPage arrPages(i)-1, Array(target), Array()

                                      I think `-1` is not needed in the counter and also would cause a runtime error because `colorConvertPage` expects a zero-index and in your case you would start with minus one instead of zero. Also, `arrPages(i)` is a page object and I think you cannot do a math operation like this...

                                       

                                      To get this whole thing working I tested a lot how to get `this` or JSObject's `doc` object from my VB `PDDoc`... finally I found out that the easiest way seems to be opening the file again in JSObject. It took me some hours but at the end you can achieve color conversion without having a JavaScript what I find is really great!

                                      • 16. Re: PDDocColorConvertPage - Convert color pages to gray
                                        Droptix Community Member

                                        Ah yes, I got the same error when converting more than 4 pages:

                                        GrayConversion3.vbs(70, 5) (null): Ausnahmefehler des Servers.

                                        Server exception error... I also have to kill the Acrobat.exe process in task manager :-( OK then we have to use the folder level JavaScript file.