Summary
A quick recipe for readers of digital comics
Advertisement
There are two standards formats for digital comics, denoted by the extensions .cbz
(zipped files) and .cbr (files compressed with the rar utility). There are many free programs to read comics in such formats: for instance CDisplay on Windows and Comix on Linux.
The other day I got a comic book as a set of images in different directories,
and I could not read it with Comix. So I wrote the following Python script to generate
the .cbz files for me. It may be of use to somebody, so I have decided to put it
in the public domain (it took me 15 minutes to write it). You can also use it to zip all
the .jpeg images you have in your hard disk, especially your pictures.
"""
A small program to collect jpeg images into .cbz files. Usage:
$ python %s <root>
The program recursively scans all subdirectories of <root>.
"""
import os, sys, zipfile
def write(msg):
sys.stdout.write(msg)
sys.stdout.flush()
def cancel(msg):
write('\x08' * len(msg))
def makecbz(dirname):
for cd, dirs, files in os.walk(dirname):
images = [os.path.join(cd, f) for f in files if f.lower().endswith(
('.jpg', '.jpeg'))]
if images:
out = cd + '.cbz'
write('Writing %s [0000]' % out)
z = zipfile.ZipFile(out, 'w')
try:
for i, img in enumerate(images):
msg = '[%04d]' % (i+1)
cancel(msg)
z.write(img)
write(msg)
finally:
write('\n')
z.close()
if __name__ == '__main__':
try:
dirname = sys.argv[1]
except IndexError:
sys.exit(__doc__ % sys.argv[0])
makecbz(dirname)
And that took me about two minutes to write, most of which was concerned with checking if I needed any other zip switches. Fortunately, the zip man page has a nice example.
> Well, pretty I suppose, but not as pretty as: > > find $1 -name '*.jpg' -o -name '*.jpeg' | zip -@ $1.cbz
Two concerns: portability and the fact that this code is flattening the directory structure, whereas the original Python code keeps it: for every subdirectory containing jpeg images a different .cbz file is created.This is important when you have more a comic book, or a comic book split in chapters, you have one subdirectory for each chapter and you want generate a .cbz file per chapter.
> > Well, pretty I suppose, but not as pretty as: > > > > find $1 -name '*.jpg' -o -name '*.jpeg' | zip -@ $1.cbz > > Two concerns: portability
If you're stuck on Windows, install Cygwin (or maybe Msys; I have no Windows machine, so I can't try it). After all, you had to install Python on Windows at some point too.
> and the fact that this code is > flattening the directory structure, whereas the original > Python code keeps it: for every subdirectory containing > jpeg images a different .cbz file is created.
Fair enough. It doesn't flatten the structure internally to the zipfile, because the directories on the file system correspond to directories in the zipfile. But if you want to create separate zipfiles... hmm...(two minutes later)...
for d in `find -type d` do (cd $d; ls | egrep '\.jpe?g$') | zip -@ $(basename $d).cbz done
Zip will report annoying but harmless errors for directories containing no JPEGs. What's more, if two subdirectories have the same basename, this will cause their files to be put in the same zipfile, but that's easily fixable too.