Skip to main content
Participating Frequently
October 4, 2006
Question

Export to PNG from Illustrator

  • October 4, 2006
  • 26 replies
  • 21118 views
Does anyone have the AIPNGFormatAction.h header file so I can export Illustrator to PNG. I have found the AIPDFFormatAction.h header and got it working but I need the parameters for setting the resolution of the PNG.
This topic has been closed for replies.

26 replies

Participating Frequently
October 22, 2008
Hitesh,

Here is my code for saving as PNG. It might help you to work out how to save as JPEG.

Robin

extern "C" AIImageOptSuite* sImageOptimization;
extern "C" AIDataFilterSuite* sAIDataFilter;
extern "C" AIDocumentSuite* sDocument;
extern "C" AILayerSuite* sLayer;
extern "C" AIArtSuite* sAIArt;
extern "C" AIPathSuite* sAIPath;
extern "C" AIPathStyleSuite* sAIPathStyle;

static AIActionParamValueRef CreateRasteriseFileParams ()
{
AIActionParamValueRef valueParameterBlock = NULL;
ReturnIfError (sAIActionManager->AINewActionParamValue (&valueParameterBlock));
if (valueParameterBlock)
{
string theStr ("Adobe PNG Format");
ReturnIfError (sAIActionManager->AIActionSetString (valueParameterBlock, kAIExportDocumentFormatKey, theStr.c_str ()));
theStr = "png";
ReturnIfError (sAIActionManager->AIActionSetString (valueParameterBlock, kAIExportDocumentExtensionKey, theStr.c_str ()));
}
return valueParameterBlock;
}

static bool gFirstTimePNG = true;
static AIBoolean MyRasterizeProgressProc (long current, long total)
{
return true;
}

static void RasteriseFileToPNG (const ai::UnicodeString& inFilePath, AIActionParamValueRef valueParameterBlock, AIArtHandle art, AIRealRect& bounds)
{
if (sImageOptimization && sAIDataFilter && art)
{
AIDataFilter* dstfilter = NULL;
AIDataFilter* filter;
ai::FilePath file (inFilePath);
AIErr result = sAIDataFilter->NewFileDataFilter (file, "write", 'prvw', 'PNGf', &filter);
if (!result)
{
result = sAIDataFilter->LinkDataFilter (dstfilter, filter);
dstfilter = filter;
}

AIDocumentSetup setup;
if ((bounds.bottom == 0.0) && (bounds.right == 0.0f))
{
if (sDocument->GetDocumentSetup (&setup))
{
setup.width = 0.0f;
setup.height = 0.0f;
}
}
else
{
setup.width = bounds.right - bounds.left;
if (setup.width < 0.0f)
setup.width = -setup.width;
setup.height = bounds.bottom - bounds.top;
if (setup.height < 0.0f)
setup.height = -setup.height;
}

float maxDims = setup.height; // in points
if (maxDims < setup.width)
maxDims = setup.width;
float resolution;
if (maxDims > 0.0f)
{
resolution = 72000.0f / maxDims; // 72 dpi x 1000 pixels = ? dpi X maxDims pixels so ? dpi = 72 dpi x 1000 pixels / maxDims pixels
if (resolution < 5.0f)
resolution = 5.0f;
else
if (resolution > 300.0f)
resolution = 300.0f;
}
else
resolution = 36.0f;

AIImageOptPNGParams2 params;
params.versionOneSuiteParams.interlaced = false;
params.versionOneSuiteParams.numberOfColors = 255;
params.versionOneSuiteParams.transparentIndex = 0;
params.versionOneSuiteParams.resolution = resolution;
params.versionOneSuiteParams.outAlpha = false;
params.versionOneSuiteParams.outWidth = 0;
params.versionOneSuiteParams.outHeight = 0;
params.antialias = true;
/* A cropping box for the art. If empty or degenerate, do not crop. */
params.cropBox = bounds;
params.backgroundIsTransparent = true;
/* When backgroundIsTransparent is false, rasterize against this matte color. */
params.matteColor.red = 1.0f;
params.matteColor.green = 1.0f;
params.matteColor.blue = 1.0f;

AIArtHandle path = NULL;
AILayerHandle newLayer = NULL;
result = sLayer->InsertLayer (NULL, kPlaceAboveAll, &newLayer);
if (newLayer && !result)
{
sLayer->SetLayerVisible (newLayer, true); // show layer
sLayer->SetLayerIsTemplate (newLayer, false); // mark as NOT a template layer so does get exported
sLayer->SetLayerEditable (newLayer, true);

AIPathSegment segments[4];
AIPathStyle pathStyle;
AIPathStyleMap pathStyleMap;
result = sAIArt->NewArt (kPathArt, kPlaceAboveAll, NULL, &path);
if (path && !result)
{
result = sAIPath->SetPathSegmentCount (path, 4);
if (!result)
{
segments[0].p.h = bounds.left;
segments[0].p.v = bounds.top;
segments[0].in = segments[0].out = segments[0].p;
segments[0].corner = true;

segments[1].p.h = bounds.right;
segments[1].p.v = bounds.top;
segments[1].in = segments[1].out = segments[1].p;
segments[1].corner = true;

segments[2].p.h = bounds.right;
segments[2].p.v = bounds.bottom;
segments[2].in = segments[2].out = segments[2].p;
segments[2].corner = true;

segments[3].p.h = bounds.left;
segments[3].p.v = bounds.bottom;
segments[3].in = segments[3].out = segments[3].p;
segments[3].corner = true;

sAIPath->SetPathSegments (path, 0, 4, segments);
sAIPath->SetPathClosed (path, true);

sAIPathStyle->GetCurrentPathStyle (&pathStyle, &pathStyleMap);
pathStyle.fillPaint = false;
pathStyle.fill.color.kind = kGrayColor;
pathStyle.fill.color.c.g.gray = kAIRealZero;

pathStyle.strokePaint = false;
pathStyle.stroke.color.kind = kGrayColor;
pathStyle.stroke.color.c.g.gray = kAIRealZero;
pathStyle.stroke.width = kAIRealZero;
sAIPathStyle->SetPathStyle (path, &pathStyle);
}
}
}

result = sImageOptimization->MakePNG24 (art, dstfilter, params, MyRasterizeProgressProc);
if (dstfilter)
sAIDataFilter->UnlinkDataFilter (dstfilter, &dstfilter);
if (path)
sAIArt->DisposeArt (path);
if (newLayer)
sLayer->DeleteLayer (newLayer);
}
else
if (valueParameterBlock)
{
ReturnIfError (sAIActionManager->AIActionSetStringUS (valueParameterBlock, kAISaveDocumentAsNameKey, inFilePath));
ReturnIfError (sAIActionManager->PlayActionEvent (kAIExportDocumentAction, gFirstTimePNG ? kDialogOn : kDialogOff, valueParameterBlock));
}
gFirstTimePNG = false;
}
November 19, 2012

Hi Robin,

I want to generate PNG files from AI..

but in your above code I am not able to understand the following objets:

ReturnIfError

kAIExportDocumentFormatKey

kAIExportDocumentExtensionKey

kAISaveDocumentAsNameKey

kAIExportDocumentAction

can you please help me..

Thanks

Harsh

Inspiring
October 22, 2008
Hi Robin,

I need to do the same stuff to generate JPEG images.
Can you tell me the parameters for
AIErr result = sAIDataFilter->NewFileDataFilter, what should be used in place of 'prvw', 'PNGf' for JPEG.

Thanks and Regards,
Hitesh
Participating Frequently
June 27, 2008
Adding a new layer, then adding a box with no fill and no frame the size of the page and rendering to PNG worked fine. I then delete the box and the layer when I am done. Problem solved. Thank you everyone for the various pointers.
Participating Frequently
June 27, 2008
I have written the following code which ALMOST works...

extern "C" AIDocumentSuite* sDocument;
extern "C" AIImageOptSuite* sImageOptimization;
extern "C" AIDataFilterSuite* sAIDataFilter;

static AIBoolean MyRasterizeProgressProc (long current, long total)
{
}

static void RasteriseFile (const string& inFilePath, AIArtHandle art)
{
if (sImageOptimization && sAIDataFilter && sDocument && art && inFilePath.length ())
{
AIDataFilter* dstfilter = NULL;
AIDataFilter* filter;
ai::UnicodeString theUnicode (inFilePath, kAIPlatformCharacterEncoding);
ai::FilePath file (theUnicode);
AIErr result = sAIDataFilter->NewFileDataFilter (file, "write", 'prvw', 'PNGf', &filter);
if (!result)
{
result = sAIDataFilter->LinkDataFilter (dstfilter, filter);
dstfilter = filter;
}
float resolution = 36.0f;
AIDocumentSetup setup;
if (!sDocument->GetDocumentSetup (&setup))
{
float maxDims = setup.height; // in points
if (maxDims < setup.width)
maxDims = setup.width;
resolution = 72000.0f / maxDims; // want the PNG to be a max of 1000 pixels
if (resolution < 5.0f)
resolution = 5.0f;
else
if (resolution > 300.0f)
resolution = 300.0f;
}
else
{
setup.width = 0.0f;
setup.height = 0.0f;
}
AIImageOptPNGParams2 params;
params.versionOneSuiteParams.interlaced = false;
params.versionOneSuiteParams.numberOfColors = 255;
params.versionOneSuiteParams.transparentIndex = 0;
params.versionOneSuiteParams.resolution = resolution;
params.versionOneSuiteParams.outAlpha = false;
params.versionOneSuiteParams.outWidth = 0;
params.versionOneSuiteParams.outHeight = 0;
params.antialias = true;
/* A cropping box for the art. If empty or degenerate, do not crop. */
params.cropBox.left = 0.0f;
params.cropBox.top = 0.0f;
params.cropBox.right = setup.width / 72.0f * resolution;
params.cropBox.bottom = setup.height / 72.0f * resolution;
params.backgroundIsTransparent = true;
/* When backgroundIsTransparent is false, rasterize against this matte color. */
params.matteColor.red = 1.0f;
params.matteColor.green = 1.0f;
params.matteColor.blue = 1.0f;

result = sImageOptimization->MakePNG24 (art, dstfilter, params, MyRasterizeProgressProc);
if (dstfilter)
sAIDataFilter->UnlinkDataFilter (dstfilter, &dstfilter);
}
}

It allows me to adjust the resolution but now it seems to optimise the PNG image size to just include the bounds of the art on the layer despite me giving it a clipping rect in the param block. I think my only alternative is to add a rectangle the size of the page with no fill and no frame. I will let you know I I get on.

Robin Landsbert
Participating Frequently
June 26, 2008
I have looked into the code of the Export to PNG plug-in and found the following strings in the code:

ai_plugin_PNGFileFormat
PNG File Format
Adobe PNG Format
AIPNGFileFormatScratchSpaceKey
PNGFileFormat
Resolution
OtherResolution
Background/red
Background/green
Background/blue
AntiAlias
Interlaced

The string "Adobe PNG Format" above is used with:

sAIActionManager->AIActionSetString (valueParameterBlock, kAIExportDocumentFormatKey,"Adobe PNG Format");

and 'ai_plugin_PNGFileFormat' looks like it could be the first parameter for PlayActionEvent although I am actually using 'adobe_exportDocument'

So it looks like there are some parameters that can be passed into the plug-in but I don't know how to do it. Is there some call like:

sAIActionManager->AIActionSetNamedParameter(valueParameterBlock, "OtherResolution", 36));
sAIActionManager->AIActionSetNamedParameter(valueParameterBlock, "AntiAlias", 1));
sAIActionManager->AIActionSetNamedParameter(valueParameterBlock, "Interlaced", 0));
Participating Frequently
June 26, 2008
I have been playing around with the "ai_plugin_rasterize" action and it seems to have nothing to do with exporting to PNG. It invokes the Object->Rasterize menu command which takes the selected graphical objects and rasterizes them to a bitmap which it the uses to replace the selected objects with. I did your trick of using kDialogOn to see what was happening and that is when I discovered that I was invoking the wrong command.

I can still find no way to change the options in the Export to PNG dialog. I tried passing some of the parameters into the valueParameterBlock of the sAIActionManager->PlayActionEvent (kAIExportDocumentAction, kDialogOff, valueParameterBlock); but it made no difference. Back at square 1.
Toto RoToTO
Inspiring
June 25, 2008
Let's try with that. Let me know if it works ? it should...but we never know.


if (valueParameterBlock1)
{

result1 = sAIActionManager->AIActionSetEnumerated(valueParameterBlock1, 'colr', "AIRasterizeType", 5);
result1 = sAIActionManager->AIActionSetInteger(valueParameterBlock1, 'dpi.', 10);
result1 = sAIActionManager->AIActionSetEnumerated(valueParameterBlock1, 'bkgb', "AITransparencyGrid", 0);
//result1 = sAIActionManager->AIActionSetEnumerated(valueParameterBlock1, 'type', ....);
result1 = sAIActionManager->AIActionSetEnumerated(valueParameterBlock1, 'alis', "AIResamplingType", 0);
result1 = sAIActionManager->AIActionSetBoolean(valueParameterBlock1, 'mask', true);
result1 = sAIActionManager->AIActionSetUnitReal(valueParameterBlock1, 'padd', unitDistance, 0.0);

result1 = sAIActionManager->PlayActionEvent("ai_plugin_rasterize", dialogStatus1, valueParameterBlock1);
result1 = sAIActionManager->AIDeleteActionParamValue(valueParameterBlock1);
}

'type' parameter is not set yet. I did not find how to set correctly this parameter but I am still working on that.
Toto RoToTO
Inspiring
June 24, 2008
I found the problem.
dpi value is not a char* but an int, so I have to use:
sAIActionManager->AIActionSetInteger(valueParameterBlock1, 1685088558, 15);

param 1, 3, 4, 5: sAIActionManager->AIActionSetEnumerated(....)
param 6: sAIActionManager->AIActionSetBoolean(......)
param 7: sAIActionManager->AIActionSetUnitReal(.....)

For debugging, I did not hide dialog status, to see if values were modified, and I realized that parameters were not set correctly.
(dpi parameter was always set to 1, whatever value was set.)

sorry for telling you mistakes. :(
hope this will more usefull.
Participating Frequently
June 24, 2008
I have finally got round to testing my code and it seems to make no difference to the resolution. I want to produce a PNG as near to 1000x1000 pixels as possible so I alter the resolution to a value so that docWidth (in inches) X resolution == 1000. I set:

result1 = sAIActionManager->AIActionSetString(valueParameterBlock1, 1685088558, resolutionStr.c_str());

where resolutionStr is the string of the INTEGER that I have calculated and then I call

result = sAIActionManager->PlayActionEvent("adobe_exportDocument", dialogStatus, valueParameterBlock);

But my PNG still comes out in the resolution of the last MANUAL export using the dialog.

I will look at the Rasterize Suite. It looks more promising.
A. Patterson
Inspiring
June 24, 2008
On that note, it's even possible to rasterize the result using AIRasterize & pull out the raw image data. We use that in our product to push the data into the format our GUI needs to display some of results.