comictagger/scripts/shrink.py
beville@gmail.com 1ff43db2ce Add-on for reducing page sizes in comics
git-svn-id: http://comictagger.googlecode.com/svn/trunk@545 6c5673fe-1810-88d6-992b-cd32ca31540c
2013-03-24 17:45:10 +00:00

189 lines
5.2 KiB
Python

#!/usr/bin/python
"""
Reduce the image size of pages in the comic archive
"""
"""
Copyright 2013 Anthony Beville
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import sys
import os
import tempfile
import zipfile
import shutil
import Image
import comictaggerlib.utils
from comictaggerlib.settings import *
from comictaggerlib.comicarchive import *
subfolder_name = "ORIGINALS"
max_height = 2000
def main():
utils.fix_output_encoding()
settings = ComicTaggerSettings()
# this can only work with files with ComicRack tags
style = MetaDataStyle.CIX
if len(sys.argv) < 2:
print >> sys.stderr, "usage: {0} comic_folder ".format(sys.argv[0])
return
filelist = utils.get_recursive_filelist( sys.argv[1:] )
#first make a list of all comic archive files
comics_list = []
max_name_len = 2
fmt_str = u"{{0:{0}}}".format(max_name_len)
for filename in filelist:
ca = ComicArchive(filename, settings )
if (ca.seemsToBeAComicArchive()):
# Check the images in the file, see if we need to reduce any
for idx in range(ca.getNumberOfPages()):
in_data = ca.getPage( idx )
if in_data is not None:
try:
im = Image.open(StringIO.StringIO(in_data))
w,h = im.size
if h > max_height:
comics_list.append( ca )
max_name_len = max ( max_name_len, len(filename))
fmt_str = u"{{0:{0}}}".format(max_name_len)
print >> sys.stderr, fmt_str.format( filename ) + "\r",
sys.stderr.flush()
break
except IOError:
#doesn't appear to be an image
pass
print >> sys.stderr, fmt_str.format( "" ) + "\r",
print "-----------------------------------------------"
print "Found {0} comics with over-large pages".format( len(comics_list))
print "-----------------------------------------------"
for item in comics_list:
print item.path
#now actually process those files with over-large pages
for ca in comics_list:
filename = ca.path
curr_folder = os.path.dirname( filename )
curr_subfolder = os.path.join( curr_folder, subfolder_name )
#skip any of our generated subfolders...
if os.path.basename(curr_folder) == subfolder_name:
continue
sys.stdout.write("Processing: " + filename)
# verify that we can write to current folder
if not os.access(filename, os.W_OK):
print "Can't move: {0}: skipped!".format(filename)
continue
if not os.path.exists( curr_subfolder ) and not os.access(curr_folder, os.W_OK):
print "Can't create subfolder here: {0}: skipped!".format(filename)
continue
if not os.path.exists( curr_subfolder ):
os.mkdir( curr_subfolder )
if not os.access(curr_subfolder, os.W_OK):
print "Can't write to the subfolder here: {0}: skipped!".format(filename)
continue
# generate a new file with temp name
tmp_fd, tmp_name = tempfile.mkstemp( dir=os.path.dirname(filename) )
os.close( tmp_fd )
cix_md = None
if ca.hasCIX():
cix_md = ca.readCIX()
try:
zout = zipfile.ZipFile (tmp_name, 'w')
# Check the images in the file, see if we want to reduce them
page_count = ca.getNumberOfPages()
for idx in range(ca.getNumberOfPages()):
name = ca.getPageName( idx )
in_data = ca.getPage( idx )
if in_data is not None:
try:
im = Image.open(StringIO.StringIO(in_data))
w,h = im.size
if h > max_height:
#resize the image
hpercent = (max_height/float(h))
wsize = int((float(w)*float(hpercent)))
size=(wsize, max_height)
im = im.resize(size, Image.ANTIALIAS)
output = StringIO.StringIO()
im.save(output, format="JPEG", quality=85)
out_data = output.getvalue()
output.close()
except IOError:
#doesn't appear to be an image
out_data = in_data
else:
#page is empty?? nothing to write
out_data = ""
sys.stdout.write('.')
sys.stdout.flush()
#Generate a new name for the page file
zout.writestr(name, out_data)
#preserve the old comment
comment = ca.archiver.getArchiveComment()
if comment is not None:
zout.comment = ca.archiver.getArchiveComment()
except Exception as e:
print "Failure creating new archive: {0}!".format(filename)
print e, sys.exc_info()[0]
zout.close()
os.unlink( tmp_name )
else:
zout.close()
# Success! Now move the files
shutil.move( filename, curr_subfolder )
os.rename( tmp_name, filename )
# TODO: We might have converted a rar to a zip, and should probably change
# the extension, as needed.
print "Done!".format(filename)
# Create a new archive object for the new file, and write the old CIX data, w/o page info
if cix_md is not None:
ca = ComicArchive( filename, settings )
cix_md.pages = []
ca.writeCIX( cix_md )
if __name__ == '__main__':
main()