User:Inductiveload/Scripts/Universal batch image to DJVU converter/Windows

This script will take either a directory of images or a list of image files and collate them in order into a DJVU file. This script needs Imagemagick, and you have to specify the Imagemagick and DjvuLibre paths inside the script to match your system. The script can handle JPG, PNG, TIFF, GIF, and any other file that Imagemagick can convert to PPM.

To convert a directory of images in alphabetical order (all filetypes)
python djvuify.py -i "C:\dir" -o "C:\dir\out.djvu"
To convert a directory of images as bitonal
python djvuify.py -i "C:\dir" -b -o "C:\dir\out.djvu"
To convert a directory of images in alphabetical order (jpgs only)
python djvuify.py -i "C:\dir" -e .jpg -o "C:\dir\out.djvu"
To convert a list of images in a text file
python djvuify.py -i "C:\dir\list.txt" -l -o "C:\dir\out.djvu"
To convert a directory of images numbered sequentially by Windows ("a (0).jpg", "a (1).jpg"..."a (10).jpg"...)
python djvuify.py -i "C:\dir" -r -o "C:\dir\out.djvu"
Debugging messages

Add the "-d" flag

Set DJVU quality for anthing but TIFF and bitonal, use "-q" parameter (you can go up to 48, the highest quality)
python djvuify.py -i "C:\dir" -q 48 -o "C:\dir\out.djvu"

Source code edit

#!/usr/bin/env python

import os, glob, subprocess, re, optparse

#CONVERT A DIRECTORY OF IMAGES TO A DJVU FILE

def main():
    
    parser = optparse.OptionParser(usage='Usage: %prog -i <source directory> <options> -o <output file>')
    parser.add_option('-i', dest='dir', action='store',\
                             help='the directory of images or list of files to collate to DJVU (required)')
    parser.add_option('-l', dest='list', action='store_true', default=False,\
                             help='the -i parameter refers to a list of files to collate in order' )
    parser.add_option('-r', dest='rename', action='store_true', default=False,\
                             help='rename files that were automatically named by Windows to a format that will sort well' )
    parser.add_option('-q', dest='quality', action='store', default='48',\
                             help='quality parameter for the c44 function (decibel), defualt=48' )
    parser.add_option('-d', dest='debug', action='store_true', default=False,\
                             help='toggle debugging information' )
    parser.add_option('-b', dest='bitonal', action='store_true', default=False,\
                             help='bitonal flag' )
    parser.add_option('-e', dest='ext', action='store', default='.*',\
                             help='image file extension (optional, default collates all types together)' )
    parser.add_option('-o', dest='out', action='store',\
                             help='the output file for the DJVU (required). This will be overwritten if it exists' )
                             
    (opts, args) = parser.parse_args()
                             
    # check mandatory options
    if opts.dir is None:
        print("The input directory/list '-i' must be given\n")
        parser.print_help()
        exit(-1)
        
    if opts.out is None :
        print("The output file (-o) must be given\n")
        parser.print_help()
        exit(-1)
        
    if opts.rename and opts.list :
        print("The options '-r' and '-l' cannot both be given\n")
        parser.print_help()
        exit(-1)

    if opts.ext != '.*' and opts.list :
        print("The options '-r' and '-l' cannot both be given\n")
        parser.print_help()
        exit(-1)
        
    Collate(opts)


    
class Collate():

    def __init__(self, opts):
        self.opts = opts
        if self.opts.rename:
            self.renumber()
            
        #create temporary DJVU file
       
        
        self.opts.tempDjvu = os.path.join(os.path.dirname(self.opts.dir), 'IMG-DJVU-CONVERTER-TEMP.djvu')
        
        if self.opts.bitonal:
            self.opts.tempPpm  = os.path.join(os.path.dirname(self.opts.dir), 'IMG-DJVU-CONVERTER-TEMP.pbm')
        else:
            self.opts.tempPpm  = os.path.join(os.path.dirname(self.opts.dir), 'IMG-DJVU-CONVERTER-TEMP.ppm')
        
        #define djvu and imagemagick directories
        self.opts.djvuDir=r"c:\program files\djvuzone\djvulibre" #directory of djvu libre executables 
        

        self.opts.imckDir = r"C:\program files\imagemagick" #directory of image magick executables
        
        #remove output file if it exists
        self.clearOutFile()  
        

        #process each file
        if not self.opts.list:
            for infile in os.listdir(self.opts.dir):  #for every file in the directory
            
                root, ext = os.path.splitext(infile)
                if ext == self.opts.ext or self.opts.ext == '.*':
                    self.processFile(os.path.join(self.opts.dir, infile))
        else:
            listfile = open(self.opts.dir, 'r')
            for infile in listfile:
                self.processFile(infile.strip() )
                
                
        #Delete the temporary files
        self.cleanUp()
        
        if self.opts.debug:
            print('\nAll files converted and collated successfully')
    
    def renumber( self ):
     
        if self.opts.debug:
            print('\tRenaming files to a good sorting format.')
            
        #rename files to have leading zero numbers so they sort properly
        
        for infile in os.listdir(self.opts.dir):  #for every file in the directory
        
            root, ext = os.path.splitext(infile)
            if ext == self.opts.ext or self.opts.ext == '.*':

                m = re.search('(.*)\((\d+)\)', infile)
                if m:
                    index = int(m.group(2)) #this is the numeric index
                    index = '%04d' % index  #pad with zeros
                    newname = m.group(1) + index + ext#append to name
                    print(newname)
                    os.rename(os.path.join(self.opts.dir, infile), os.path.join(self.opts.dir, newname))
        return
            
    def clearOutFile( self ):
    
        if os.path.exists(self.opts.out):
            if self.opts.debug:
                print('\tOutput file exists. Deleting.')
            os.remove(self.opts.out)
        return
        
    def cleanUp( self ):
    
        if os.path.exists(self.opts.tempDjvu):
            if self.opts.debug:
                print('\tDeleting temporary DJVU file.')
            os.remove(self.opts.tempDjvu)
        return

     
    def processFile(self, infile):

        if self.opts.debug:
            print('\tProcessing: ' + infile)

        root, ext = os.path.splitext( infile )

        if not self.opts.bitonal and ext =='.jpg':
        
            #convert jpg to a temp djvu file
            cmd = [os.path.join(self.opts.djvuDir, 'c44.exe'), '-decibel', self.opts.quality, infile, self.opts.tempDjvu]
            #print(cmd)
            subprocess.call(cmd)
            
        elif self.opts.bitonal and (ext == '.tiff' or ext=='.tif'):
            #convert jpg to a temp djvu file
            cmd = [os.path.join(self.opts.djvuDir, 'cjb2.exe') ,infile, self.opts.tempDjvu]
            #print(cmd)
            subprocess.call(cmd)
        
        else :#ext == '.gif' or ext=='.png': #image needs converting
            
            cmd = [os.path.join(self.opts.imckDir, 'convert.exe'), infile, self.opts.tempPpm]
            print(cmd)
            subprocess.call(cmd)
            
            if self.opts.bitonal:
                cmd = [os.path.join(self.opts.djvuDir, 'cjb2.exe'), self.opts.tempPpm, self.opts.tempDjvu]
            else:
                cmd = [os.path.join(self.opts.djvuDir, 'c44.exe'), '-decibel', self.opts.quality, self.opts.tempPpm, self.opts.tempDjvu]
            #print(cmd)
            subprocess.call(cmd)
            os.remove(self.opts.tempPpm)
            
            
        
        if os.path.exists(self.opts.out):
            #Add the djvu file to the collated file
            cmd = [os.path.join(self.opts.djvuDir, 'djvm.exe'),'-i', self.opts.out,self.opts.tempDjvu]
        else:
            # Create the collated file
            cmd = [os.path.join(self.opts.djvuDir, 'djvm.exe'), '-c',self.opts.out,self.opts.tempDjvu]
        subprocess.call(cmd)

        


if __name__ == "__main__":
    try: 
        main()
    finally:
        None
        #wikipedia.stopme()