Reputation: 929
I have a folder of images saved in .xcf format, and I would like to batch convert them to a more convenient format. I've tried a few approaches that haven't worked:
I used to do this using IrfanView, but that no longer works because it refuses to open the latest version of .xcf files.
I tried using IMageMagick mogrify and convert, but they both give me "memory allocation failed" -- perhaps they also don't understand the new format?
I tried the xcf2png command line tool and it gives me the message "Warning: XCF version 11 not supported (trying anyway...)" before creating an empty image.
My last hope is to write a batch convert script that will work in the latest version of Gimp itself, but I don't have any experience with ScriptFu. I found a script that converts some other file types (http://beefchunk.com/documentation/lang/gimp/GIMP-Scripts-Fu.html#convertjpg-script-fu) but don't quite have the knowledge to modify it. Does anybody know the right calls/arguments to read xcf and write png?
Upvotes: 5
Views: 1993
Reputation: 869
Here is a self-contained bash script that should convert all xcf files in your current directory into png format copies. It should work on any Linux computer with Gimp installed. It does not require any installation in script directories:
#!/bin/bash
# xcfs2png.sh
# Invoke The GIMP with Script-Fu convert-xcf-png
# No error checking.
{
cat <<EOF
(define (convert-xcf-png filename outpath)
(let* (
(image (car (gimp-xcf-load RUN-NONINTERACTIVE filename filename )))
(drawable (car (gimp-image-merge-visible-layers image CLIP-TO-IMAGE)))
)
(begin (display "Exporting ")(display filename)(display " -> ")(display outpath)(newline))
(file-png-save2 RUN-NONINTERACTIVE image drawable outpath outpath 0 9 0 0 0 0 0 0 0)
(gimp-image-delete image)
)
)
(gimp-message-set-handler 1) ; Messages to standard output
EOF
for i in *.xcf; do
echo "(convert-xcf-png \"$i\" \"${i%%.xcf}.png\")"
done
echo "(gimp-quit 0)"
} | gimp -i -b -
Tested working with Gimp v2.10.18 on Kubuntu 20.04. Thanks to patdavid at pixls.us for the original script.
Upvotes: 7
Reputation: 8914
#!/usr/bin/python
import os,glob,sys,time
from gimpfu import *
def process(infile):
print "Processing file %s " % infile
image = pdb.gimp_xcf_load(0,infile,infile)
print "File %s loaded OK" % infile
# The API saves a layer, so make a layer from the visible image
savedlayer = pdb.gimp_layer_new_from_visible(image,image,"Saved image")
outfile=os.path.splitext(infile)[0]+'.png'
print "Saving to %s" % outfile
pdb.file_png_save(image,savedlayer,outfile, outfile,True,9,True,True,True,True,True)
print "Saved to %s" % outfile
pdb.gimp_image_delete(image)
def run(directory):
start=time.time()
print "Running on directory \"%s\"" % directory
for infile in glob.glob(os.path.join(directory, '*.xcf')):
process(infile)
end=time.time()
print "Finished, total processing time: %.2f seconds" % (end-start)
if __name__ == "__main__":
print "Running as __main__ with args: %s" % sys.argv
convertXCF.py
(this is Python, so mind the indentation)gimp -idf --batch-interpreter python-fu-eval -b "import sys;sys.path=['.']+sys.path;import convertXCF;convertXCF.run('/path/to/the/directory')" -b "pdb.gimp_quit(1)"
Some more explanations here.
Upvotes: 3