How to convert XCF to PNG using GIMP from the command-line?

后端 未结 5 1860
误落风尘
误落风尘 2021-02-01 03:02

As part of my build process I need to convert a number of XCF (GIMP\'s native format) images into PNG format. I\'m sure this should be possible using GIMP\'s batch mode, but I h

相关标签:
5条回答
  • 2021-02-01 03:27

    Before jsbueno posted his answer I had also tried asking on the #gimp IRC channel. I was directed to this thread on Gimptalk which contains the following code:

    gimp -n -i -b - <<EOF
    (let* ( (file's (cadr (file-glob "*.xcf" 1))) (filename "") (image 0) (layer 0) )
      (while (pair? file's) 
        (set! image (car (gimp-file-load RUN-NONINTERACTIVE (car file's) (car file's))))
        (set! layer (car (gimp-image-merge-visible-layers image CLIP-TO-IMAGE)))
        (set! filename (string-append (substring (car file's) 0 (- (string-length (car file's)) 4)) ".png"))
        (gimp-file-save RUN-NONINTERACTIVE image layer filename filename)
        (gimp-image-delete image)
        (set! file's (cdr file's))
        )
      (gimp-quit 0)
      )
    EOF
    

    This scriptfu globs for xcf files, and then for each file it loads the file, merges the visible layers, saves the result as a PNG, and "unloads" the image. Finally, it quits GIMP. The glob approach is used to avoid starting up GIMP for each image. It also side-steps the issue of getting parameters from the shell into gimp.

    I'm posting this answer just in case someone needs a way to do this without the use of GIMP-Python (perhaps because it isn't installed).

    0 讨论(0)
  • 2021-02-01 03:39

    Here is my solution utilizing GIMP, GIMP's python-fu and bash. Note that GIMP's python-fu can only be run under a gimp process, not under plain python.

    #!/bin/bash
    set -e
    
    while getopts df: OPTION "$@"; do
        case $OPTION in
        d)
            set -x
            ;;
        f)
            XCFFILE=${OPTARG}
            ;;
        esac
    done
    
    if [[ -z "$XCFFILE" ]]; then
        echo "usage: `basename $0` [-d] -f <xcfFile>"
        exit 1
    fi
    
    # Start gimp with python-fu batch-interpreter
    gimp -i --batch-interpreter=python-fu-eval -b - << EOF
    import gimpfu
    
    def convert(filename):
        img = pdb.gimp_file_load(filename, filename)
        new_name = filename.rsplit(".",1)[0] + ".png"
        layer = pdb.gimp_image_merge_visible_layers(img, 1)
    
        pdb.gimp_file_save(img, layer, new_name, new_name)
        pdb.gimp_image_delete(img)
    
    convert('${XCFFILE}')
    
    pdb.gimp_quit(1)
    EOF
    
    0 讨论(0)
  • 2021-02-01 03:40

    I know this is not strictly the correct answer but seeing as a I got directed here while searching.

    I modified the example code here to create a workable plugin

    http://registry.gimp.org/node/28124

    There is a bit of code from another answer on this page

    #!/usr/bin/env python
    
    from gimpfu import *
    import os
    
    
    
    def batch_convert_xcf_to_png(img, layer, inputFolder, outputFolder):
        ''' Convert the xcf images in a directory to png.
    
        Parameters:
        img : image The current image (unused).
        layer : layer The layer of the image that is selected (unused).
        inputFolder : string The folder of the images that must be modified.
        outputFolder : string The folder in which save the modified images.
        '''
        # Iterate the folder
        for file in os.listdir(inputFolder):
            try:
                # Build the full file paths.
                inputPath = inputFolder + "\\" + file
    
                new_name = file.rsplit(".",1)[0] + ".png"
                outputPath = outputFolder + "\\" + new_name
    
                # Open the file if is a XCF image.
                image = None
                if(file.lower().endswith(('.xcf'))):
                    image = pdb.gimp_xcf_load(1,inputPath, inputPath)
    
    
                # Verify if the file is an image.
                if(image != None):
    
                    #layer = pdb.gimp_image_merge_visible_layers(image, gimpfu.CLIP_TO_IMAGE)
                    layer = pdb.gimp_image_merge_visible_layers(image, 1)
    
                    # Save the image.
                    pdb.file_png_save(image, image.layers[0], outputPath, outputPath, 0, 9, 0, 0, 0, 0, 0)
    
            except Exception as err:
                gimp.message("Unexpected error: " + str(err))   
    
    
    
    
    '''                
        img = pdb.gimp_file_load(filename, filename)
        new_name = filename.rsplit(".",1)[0] + ".png"
        layer = pdb.gimp_image_merge_visible_layers(img, gimpfu.CLIP_TO_IMAGE)
    
        pdb.gimp_file_save(img, layer, new_name, new_name)
        pdb.gimp_image_delete(img)
    '''    
    
    
    register(
            "batch_convert_xcf_to_png",
            "convert chris",
            "convert ",
            "Chris O'Halloran",
            "Chris O'Halloran",
            "2014",
            "<Image>/Filters/Test/Batch batch_convert_xcf_to_png",
            "*",
            [
                (PF_DIRNAME, "inputFolder", "Input directory", ""),
                (PF_DIRNAME, "outputFolder", "Output directory", ""),            
            ],
            [],
            batch_convert_xcf_to_png)
    
    
    
    main()
    
    0 讨论(0)
  • 2021-02-01 03:41

    There are a few ways to go through this - my preferred method is always developing a GIMP-Python plug-in. Script-fu uses GIMP's built-in scheme implementation, which is extremely poor in handling I/O (such as listing files in a directory) - a task which is absolutely trivial in Python.

    SO, since you said you don't want to save new scripts (you could do it because you can add new plug-in and scripts directories on edit->preferences->folder options so that you don't need to write on ~/.gimp*/plugins/)

    Anyway, you can open the python console under filters, and paste this snippet in the interactive prompt.

    import gimpfu
    def convert(filename):
        img = pdb.gimp_file_load(filename, filename)
        new_name = filename.rsplit(".",1)[0] + ".png"
        layer = pdb.gimp_image_merge_visible_layers(img, gimpfu.CLIP_TO_IMAGE)
    
        pdb.gimp_file_save(img, layer, new_name, new_name)
        pdb.gimp_image_delete(img)
    

    This small function will open any image, passed as a file path, flatten it, and save it as a png with the default settings, in the same directory.

    Following the function, you can simply type:

    from glob import glob
    for filename in glob("*.xcf"):
        convert(filename)
    

    On the interactive prompt to convert all .xcf files on the current directory to .png

    (If you don't have gimp-python installed, it may be a separate package on your linux distribution, just install it using your favorite tool - for those under windows, and gimp-2.6, the instructions on this page have have to be followed - it should become easier on gimp 2.8)

    Another way, altogether, applies if your images are sequentially numbered in their filenames, such as myimage_001.xcf, mymage_002.xcf and so on. If they are so arranged you could install GIMP-GAP (gimp animation package) which allows one to apply any filters or actions in such an image sequence.

    0 讨论(0)
  • 2021-02-01 03:41

    Use xcftools

    It's possible that this tool wasn't available (or in any case widely known) at the time this question was originally asked, but the xcf2png terminal command from the xcftools package does exactly what you ask and is very good. I use it for my thesis scripts and would be my go-to choice for this question.

    From the documentation:

    This is a set of fast command-line tools for extracting information from the Gimp's native file format XCF.
    The tools are designed to allow efficient use of layered XCF files as sources in a build system that use 'make' and similar tools to manage automatic processing of the graphics.
    These tools work independently of the Gimp engine and do not require the Gimp to even be installed.

    "xcf2png" converts XCF files to PNG format, flattening layers if necessary. Transparency information can be kept in the image, or a background color can be specified on the command line.


    (PS. I spotted xcftools mentioned in the comments just after I decided to post an answer about it, but I'm posting anyway as that comment was easy to miss (I saw it because I specifically checked for it) and I think xcftools deserves a proper answer's slot, as it really is the most appropriate answer at this point in time.)

    0 讨论(0)
提交回复
热议问题