Search code examples
python-3.xcomtypescoreldraw

CorelDRAW and Python Integration


I am trying to create an application in Python to modify CorelDRAW files. These cdr files are basically templates that I've added artwork to. I'm trying to create proof email files and a different layout print file. These files have to be JPEG as that is what my RIPing software uses to print.

I've got the layout part correct for the email files and I do not need help with laying out the print files either. What's not working correctly is exporting the JPEG files. The problem I'm having is that, no matter what I've tried, the program says that it's executing correctly but it is not exporting the JPEG file. It rearranges the items in the template correctly and makes the layout that should be exported but it never does the exporting. My code is below. Please help

import comtypes.client
import os

# Create a new instance of the CorelDRAW application
cdr = comtypes.client.CreateObject('CorelDRAW.Application')

# Open an existing document
fpath = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop\Corel Testing\\4 Panels.cdr')
doc = cdr.OpenDocument(fpath)
filename = fpath.split("\\")[-1].split(".")[0]

# Select the active page
page = doc.ActivePage
doc.Unit = 3
layer = page.ActiveLayer

# get the page width and height
width = page.SizeWidth
height = page.SizeHeight


def createSaveLayout():
    global layer
    # get the amount of shapes on the current layer
    shape_count = layer.Shapes.Count

    #set initial rotation
    rotation = 0

    # case
    if shape_count == 1:
        # first clone the panel 3 times.
        layer.Shapes.Item(1).Duplicate()
        layer.Shapes.Item(1).Duplicate()
        layer.Shapes.Item(1).Duplicate()

    elif shape_count == 2:
        page_rect = layer.CreateRectangle2(0, 0, width, height)
        page_rect.Name = "PageRect"
        for i in range(shape_count + 1):
            if layer.Shapes.Item(i + 1).Name != "PageRect":
                # fix rotation
                layer.Shapes.Item(i + 1).RotationAngle = rotation
                # fix position
                layer.Shapes.Item(i + 1).AlignToShape(Type=3, Shape=page_rect)
                layer.Shapes.Item(i + 1).AlignToShape(Type=12, Shape=page_rect)
        layer.Shapes.Item(2).Duplicate()
        layer.Shapes.Item(4).Duplicate()
        layer.Shapes.Item(1).Delete()
        layer.Shapes.Item(3).OrderForwardOne()

    elif shape_count == 4:
        page_rect = layer.CreateRectangle2(0, 0, width, height)
        page_rect.Name = "PageRect"
        for i in range(shape_count + 1):
            if layer.Shapes.Item(i + 1).Name != "PageRect":
                # fix rotation
                layer.Shapes.Item(i + 1).RotationAngle = rotation
                # fix position
                layer.Shapes.Item(i + 1).AlignToShape(Type=3, Shape=page_rect)
                layer.Shapes.Item(i + 1).AlignToShape(Type=12, Shape=page_rect)
        layer.Shapes.Item(1).Delete()

    shape_count = layer.Shapes.Count

    # Movement code
    for i in range(shape_count):
        shape = layer.Shapes.Item(i + 1)
        if i % 2 == 0:
            shape.PositionX += shape.SizeWidth

        if i == 0 or i == 1:
            shape.PositionY += shape.SizeHeight + 50
            shape.RotationAngle = 180

    layer.Shapes.Item(1).AddToSelection()
    layer.Shapes.Item(3).AddToSelection()

    # Add the selected shapes to a group
    cdr.ActiveDocument.BeginCommandGroup("Group Selection")
    cdr.ActiveSelection.Group()
    cdr.ActiveDocument.EndCommandGroup()

    layer.Shapes.Item(1).RotationAngle = 90
    layer.Shapes.Item(1).AlignToShape(Type=3, Shape=layer.Shapes.Item(2))

    layer.Shapes.Item(1).Ungroup()
    layer.Shapes.Item(2).OrderBackOne()

    for i in range(shape_count):
        layer.Shapes.Item(i + 1).RemoveFromSelection()
    # doc.Save()


def createEmailFile():
    global filename, cdr, filename, page, width, height
    page.Autofit()

    export_dir = os.path.join(os.path.dirname(fpath), 'exports')  # create an "exports" directory
    if not os.path.exists(export_dir):  # if the directory doesn't exist, create it
        os.makedirs(export_dir)

    print(fpath)

    file_name = os.path.join(export_dir, f"{filename}.jpg")  # use os.path.join() to combine the directory and file name

    export_result = cdr.ActiveDocument.ExportBitmap(FileName=file_name,
                                                    Filter=774,
                                                    ResolutionX=72,
                                                    ResolutionY=72,
                                                    ImageType=5,
                                                    Width=1000,
                                                    Height=1000,
                                                    AntiAliasingType=1,
                                                    Dithered=False,
                                                    Transparent=False,
                                                    UseColorProfile=False,
                                                    MaintainLayers=False,
                                                    Compression=8)

    if export_result:
        print(f"Export succeeded! Result: {export_result}")
    else:
        print("Export failed.")
    page.SizeWidth = width
    page.SizeHeight = height
    createSaveLayout()


# Save the changes and close the document
# doc.Save()
# doc.Close()
createSaveLayout()
createEmailFile()

Solution

  • After experimenting with the Corel API for almost a year using C# I came back to the python version of my code as I'm trying to create something wholly different but using the same principles. I thought I'd post the solution to this so that anyone else trying to experiment and automate will be able to do so.

    In the code above I had done this, thinking that this is what was required.

    export_result = cdr.ActiveDocument.ExportBitmap(FileName=file_name,
                                                    Filter=774,
                                                    ResolutionX=72,
                                                    ResolutionY=72,
                                                    ImageType=5,
                                                    Width=1000,
                                                    Height=1000,
                                                    AntiAliasingType=1,
                                                    Dithered=False,
                                                    Transparent=False,
                                                    UseColorProfile=False,
                                                    MaintainLayers=False,
                                                    Compression=8)
    

    That is not what is required. This is:

    struct_palette_options = cdr.CreateStructPaletteOptions()
    rect = cdr.CreateRect()
    rect.Height = page.SizeHeight
    rect.Width = page.SizeWidth
    rect.x = 0
    rect.y = 0
    cdr.ActiveDocument.ExportBitmap(file_name, 774, 72, 72, 5, 1000, 1000, 1, False, False, False, False, 8, struct_palette_options, rect)
    

    But there's a much easier way of exporting a jpeg and it gives you control over what you're adding to the StructExportOptions() and you'll know exactly what you're doing.

    export_options = app.CreateStructExportOptions() # cdr.CreateStructExportOptions in the original.
    export_options.ResolutionX = 300
    export_options.ResolutionY = 300
    export_options.AntiAliasingType = 1
    export_options.Transparent = False
    export_options.MaintainAspect = True
    export_options.Compression = 80
    export_options.ImageType = 5
    
    palette_options = app.CreateStructPaletteOptions()
    
    app.ActiveDocument.Export(f_name, 774, 1, export_options, palette_options)
    

    If you want more control, the options on this link within the API tells you exactly what you can set. The same is also true for StructPaletteOptions()