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

# PDDocColorConvertPage - Convert color pages to gray

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.

• ###### 1. Re: PDDocColorConvertPage - Convert color pages to gray

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

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

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

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;

}

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 PDDocColorConvertPagevia 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

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:

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

Karl Heinz Kremer

PDF Acrobatics Without a Net

khk@khk.net

http://www.khkonsulting.com

• ###### 6. Re: PDDocColorConvertPage - Convert color pages to gray

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

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

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

Look at the doc.colorConvertPage() API.

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

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

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],[]);

}

}

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

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

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

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")

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

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")

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

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

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.