1
0
mirror of https://github.com/ciromattia/kcc synced 2025-12-15 18:56:28 +00:00

Merge branch 'master' of github.com:ciromattia/kcc

This commit is contained in:
Ciro Mattia Gonano
2013-05-28 12:18:58 +02:00
3 changed files with 266 additions and 209 deletions

144
README.md
View File

@@ -1,4 +1,4 @@
# KCC
# KCC
`KCC` (a.k.a. `KindleComicConverter`) is a Python app to convert comic files or folders to ePub or Panel View MOBI.
It was initally developed for Kindle but since v2.2 it outputs valid ePub 2.0 so _**despite its name, KCC is
@@ -16,9 +16,14 @@ _kc2_ in no way is a replacement for **KCC** so you can be quite confident we'll
You can find the latest released binary at the following links:
- OS X: [https://dl.dropbox.com/u/16806101/KindleComicConverter_osx_2.9.zip](https://dl.dropbox.com/u/16806101/KindleComicConverter_osx_2.9.zip)
- Win64: [https://dl.dropbox.com/u/16806101/KindleComicConverter_win-amd64_2.9.zip](https://dl.dropbox.com/u/16806101/KindleComicConverter_win-amd64_2.9.zip)
- Win32: [http://pawelj.vulturis.eu/Shared/KindleComicConverter_win-x86_2.9.zip](http://pawelj.vulturis.eu/Shared/KindleComicConverter_win-x86_2.9.zip) *(thanks to [AcidWeb](https://github.com/AcidWeb))*
- Win32: [http://pawelj.vulturis.eu/Shared/KindleComicConverter_win-x86_2.9.zip](http://pawelj.vulturis.eu/Shared/KindleComicConverter_win-x86_2.9.zip)
- Linux: Just download sourcecode and launch `python kcc.py` *(Provided you have Python and Pillow installed)*
## AWKCC .NET GUI
![AWKCC](http://pawelj.vulturis.eu/Shared/CurrentAWKCC.png)
[All-in-one package for Windows users](http://www.mobileread.com/forums/showpost.php?p=2444957&postcount=3)
## INPUT FORMATS
`kcc` can understand and convert, at the moment, the following file types:
- PNG, JPG, GIF, TIFF, BMP
@@ -53,7 +58,7 @@ Options:
--version show program's version number and exit
-h, --help show this help message and exit
-p PROFILE, --profile=PROFILE
Device profile (Choose one among K1, K2, K3, K4NT, K4T, KDX, KDXG or KHD) [Default=KHD]
Device profile (Choose one among K1, K2, K3, K4NT, K4T, KDX, KDXG, KHD, KF, KFHD, KFHD8) [Default=KHD]
-t TITLE, --title=TITLE
Comic title [Default=filename]
-m, --manga-style Manga style (Right-to-left reading and splitting) [Default=False]
@@ -88,55 +93,92 @@ The app relies and includes the following scripts/binaries:
- `magic.py` from [python-magic](https://github.com/ahupp/python-magic) library
## CHANGELOG
- 1.00: Initial version
- 1.10: Added support for CBZ/CBR files in comic2ebook.py
- 1.11: Added support for CBZ/CBR files in KindleComicConverter
- 1.20: Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait
with landscape target), add palette and other image optimizations from Mangle.
WARNING: PIL is required for all image mangling!
- 1.30: Fixed an issue in OPF generation for device resolution
Reworked options system (call with -h option to get the inline help)
- 1.40: Added some options for controlling image optimization
Further optimization (ImageOps, page numbering cut, autocontrast)
- 1.41: Fixed a serious bug on resizing when img ratio was bigger than device one
- 1.50: Added subfolder support for multiple chapters.
- 2.0: GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
- 2.1: Added basic error reporting
- 2.2: Added (valid!) ePub 2.0 output
Rename .zip files to .cbz to avoid overwriting
- 2.3: Fixed win32 ePub generation, folder handling, filenames with spaces and subfolders
- 2.4: Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
Fixed "add folders" from GUI.
- 2.5: Added --black-borders option to set added borders black when page's ratio is not the device's one (#11).
Fixes epub containing zipped itself (#10)
- 2.6: Added --rotate option to rotate landscape images instead of splitting them (#16, #24)
Added --output option to customize ePub output dir/file (#22)
Add rendition:layout and rendition:orientation ePub meta tags (supported by new kindlegen 2.8)
Fixed natural sorting for files (#18)
- 2.7: Lots of GUI improvements (#27, #13)
Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27)
Added --nodithering option to prevent dithering optimizations (#27)
Epub margins support (#30)
Fixed no file added if file has no spaces on Windows (#25)
Gracefully exit if unrar missing (#15)
Do not call kindlegen if source epub is bigger than 320MB (#17)
Get filetype from magic number (#14)
PDF conversion works again
- 2.8: updated rarfile library
Panel View support + HQ support (#36) - new option: --nopanelviewhq
Split profiles for K4NT and K4T
Rewrite of Landscape Mode support (huge readability improvement for KPW)
Upscale use now BILINEAR method
Added generic CSS file
Optimized archive extraction for zip/rar files (#40)
- 2.9: Added support for generating a plain CBZ (skipping all the EPUB/Mobi generation) (#45)
Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name
Rarfile library updated to 2.6
Added GIF, TIFF and BMP to supported formats (#42)
Filenames slugifications (#28, #31, #9, #8)
- 2.10: Kindle Fire support (color ePub/Mobi)
Panel View support for horizontal content
####1.00
* Initial version
####1.10
* Added support for CBZ/CBR files in comic2ebook.py
####1.11
* Added support for CBZ/CBR files in KindleComicConverter
####1.20
* Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait with landscape target), add palette and other image optimizations from Mangle. WARNING: PIL is required for all image mangling!
####1.30
* Fixed an issue in OPF generation for device resolution
* Reworked options system (call with -h option to get the inline help)
####1.40
* Added some options for controlling image optimization
* Further optimization (ImageOps, page numbering cut, autocontrast)
####1.41
* Fixed a serious bug on resizing when img ratio was bigger than device one
####1.50
* Added subfolder support for multiple chapters.
####2.0
* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
####2.1
* Added basic error reporting
#### 2.2:
* Added (valid!) ePub 2.0 output
* Rename .zip files to .cbz to avoid overwriting
####2.3
* Fixed win32 ePub generation, folder handling, filenames with spaces and subfolders
####2.4
* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
* Fixed "add folders" from GUI.
####2.5
* Added --black-borders option to set added borders black when page's ratio is not the device's one (#11).
* Fixes epub containing zipped itself (#10)
####2.6
* Added --rotate option to rotate landscape images instead of splitting them (#16, #24)
* Added --output option to customize ePub output dir/file (#22)
* Add rendition:layout and rendition:orientation ePub meta tags (supported by new kindlegen 2.8)
* Fixed natural sorting for files (#18)
####2.7
* Lots of GUI improvements (#27, #13)
* Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27)
* Added --nodithering option to prevent dithering optimizations (#27)
* Epub margins support (#30)
* Fixed no file added if file has no spaces on Windows (#25)
* Gracefully exit if unrar missing (#15)
* Do not call kindlegen if source epub is bigger than 320MB (#17)
* Get filetype from magic number (#14)
* PDF conversion works again
####2.8
* Updated rarfile library
* Panel View support + HQ support (#36) - new option: --nopanelviewhq
* Split profiles for K4NT and K4T
* Rewrite of Landscape Mode support (huge readability improvement for KPW)
* Upscale use now BILINEAR method
* Added generic CSS file
* Optimized archive extraction for zip/rar files (#40)
####2.9
* Added support for generating a plain CBZ (skipping all the EPUB/Mobi generation) (#45)
* Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name
* Rarfile library updated to 2.6
* Added GIF, TIFF and BMP to supported formats (#42)
* Filenames slugifications (#28, #31, #9, #8)
####2.10:
* Multiprocessing support
* Kindle Fire support (color ePub/Mobi)
* Panel View support for horizontal content
* Fixed panel order for horizontal pages when --rotate is enabled
* Disabled cropping and page number cutting for blank pages
## COPYRIGHT

View File

@@ -32,6 +32,7 @@ from shutil import copytree
from shutil import rmtree
from shutil import make_archive
from optparse import OptionParser
from multiprocessing import Pool
import image
import cbxarchive
import pdfjpgextract
@@ -40,6 +41,11 @@ import pdfjpgextract
def buildHTML(path, imgfile):
filename = getImageFileName(imgfile)
if filename is not None:
# All files marked with this sufix need horizontal Panel View.
if "_rotated" in str(filename):
rotate = True
else:
rotate = False
htmlpath = ''
postfix = ''
backref = 1
@@ -70,7 +76,7 @@ def buildHTML(path, imgfile):
imgfile, "\" class=\"singlePage\"/></div>\n"
])
if options.panelview:
if options.panelviewhorizontal:
if rotate:
if options.righttoleft:
f.writelines(["<div id=\"BoxTL\"><a class=\"app-amzn-magnify\" data-app-amzn-magnify=",
"'{\"targetId\":\"BoxTL-Panel-Parent\", \"ordinal\":1}'></a></div>\n",
@@ -250,7 +256,7 @@ def buildOPF(profile, dstdir, title, filelist, cover=None):
f.write("</manifest>\n<spine toc=\"ncx\">\n")
splitCountUsed = 1
for entry in reflist:
if entry.endswith("-1"):
if entry.endswith("-000001") or entry.endswith("-1"):
# noinspection PyRedundantParentheses
if ((options.righttoleft and facing == 'left') or (not options.righttoleft and facing == 'right')) and\
options.landscapemode:
@@ -260,7 +266,7 @@ def buildOPF(profile, dstdir, title, filelist, cover=None):
f.write("<itemref idref=\"page_" + entry + "\" properties=\"page-spread-" + facing1 + "\"/>\n")
else:
f.write("<itemref idref=\"page_" + entry + "\"/>\n")
elif entry.endswith("-2"):
elif entry.endswith("-000002") or entry.endswith("-2"):
if options.landscapemode:
f.write("<itemref idref=\"page_" + entry + "\" properties=\"page-spread-" + facing2 + "\"/>\n")
else:
@@ -309,16 +315,7 @@ def getImageFileName(imgfile):
return filename
def isInFilelist(filename, filelist):
filename = os.path.splitext(filename)
seen = False
for item in filelist:
if filename[0] == item[0]:
seen = True
return seen
def applyImgOptimization(img, isSplit=False, toRight=False):
def applyImgOptimization(img, isSplit, toRight, options):
img.cropWhiteSpace(10.0)
if options.cutpagenumbers:
img.cutPageNumber()
@@ -331,51 +328,62 @@ def applyImgOptimization(img, isSplit=False, toRight=False):
def dirImgProcess(path):
global options, splitCount
if options.righttoleft:
facing = "right"
else:
facing = "left"
work = []
pagenumber = 0
pagenumbermodifier = 0
pool = Pool()
for (dirpath, dirnames, filenames) in os.walk(path):
for afile in filenames:
if getImageFileName(afile) is not None:
if options.verbose:
print "Optimizing " + afile + " for " + options.profile
else:
print ".",
img = image.ComicPage(os.path.join(dirpath, afile), options.profile)
if options.nosplitrotate:
split = None
else:
split = img.splitPage(dirpath, options.righttoleft, options.rotate)
if split is not None:
if options.verbose:
print "Splitted " + afile
if options.righttoleft:
toRight1 = False
toRight2 = True
if facing == "left":
splitCount += 1
facing = "right"
else:
toRight1 = True
toRight2 = False
if facing == "right":
splitCount += 1
facing = "left"
img0 = image.ComicPage(split[0], options.profile)
applyImgOptimization(img0, True, toRight1)
img0.saveToDir(dirpath, options.forcepng, options.forcecolor)
img1 = image.ComicPage(split[1], options.profile)
applyImgOptimization(img1, True, toRight2)
img1.saveToDir(dirpath, options.forcepng, options.forcecolor)
else:
if facing == "right":
facing = "left"
else:
facing = "right"
applyImgOptimization(img)
img.saveToDir(dirpath, options.forcepng, options.forcecolor)
pagenumber += 1
work.append([afile, dirpath, pagenumber, options])
splitpages = pool.map(fileImgProcess, work)
pool.close()
pool.join()
splitpages = filter(None, splitpages)
splitpages.sort()
for page in splitpages:
if (page + pagenumbermodifier) % 2 == 0:
splitCount += 1
pagenumbermodifier += 1
pagenumbermodifier += 1
def fileImgProcess(work):
afile = work[0]
dirpath = work[1]
pagenumber = work[2]
options = work[3]
output = None
if options.verbose:
print "Optimizing " + afile + " for " + options.profile
else:
print ".",
img = image.ComicPage(os.path.join(dirpath, afile), options.profile)
if options.nosplitrotate:
split = None
else:
split = img.splitPage(dirpath, options.righttoleft, options.rotate)
if split is not None and split is not "R":
if options.verbose:
print "Splitted " + afile
if options.righttoleft:
toRight1 = False
toRight2 = True
else:
toRight1 = True
toRight2 = False
output = pagenumber
img0 = image.ComicPage(split[0], options.profile)
applyImgOptimization(img0, True, toRight1, options)
img0.saveToDir(dirpath, options.forcepng, options.forcecolor)
img1 = image.ComicPage(split[1], options.profile)
applyImgOptimization(img1, True, toRight2, options)
img1.saveToDir(dirpath, options.forcepng, options.forcecolor)
else:
applyImgOptimization(img, False, False, options)
img.saveToDir(dirpath, options.forcepng, options.forcecolor, split)
return output
def genEpubStruct(path):
@@ -387,8 +395,8 @@ def genEpubStruct(path):
sanitizeTree(os.path.join(path, 'OEBPS', 'Images'))
os.mkdir(os.path.join(path, 'OEBPS', 'Text'))
f = open(os.path.join(path, 'OEBPS', 'Text', 'style.css'), 'w')
#DON'T COMPRESS CSS. KINDLE WILL FAIL TO PARSE IT.
#Generic Panel View support + Margins fix for Non-Kindle devices.
# DON'T COMPRESS CSS. KINDLE WILL FAIL TO PARSE IT.
# Generic Panel View support + Margins fix for Non-Kindle devices.
f.writelines(["@page {\n",
"margin-bottom: 0;\n",
"margin-top: 0\n",
@@ -511,13 +519,6 @@ def genEpubStruct(path):
for afile in filenames:
filename = getImageFileName(afile)
if filename is not None:
if "credit" in afile.lower():
os.rename(os.path.join(dirpath, afile), os.path.join(dirpath, 'ZZZ999_' + afile))
afile = 'ZZZ999_' + afile
if "+" in afile.lower() or "#" in afile.lower():
newfilename = afile.replace('+', '_').replace('#', '_')
os.rename(os.path.join(dirpath, afile), os.path.join(dirpath, newfilename))
afile = newfilename
filelist.append(buildHTML(dirpath, afile))
if not chapter:
chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1]))
@@ -598,11 +599,11 @@ def sanitizeTree(filetree):
def Copyright():
print ('comic2ebook v%(__version__)s. '
'Written 2012 by Ciro Mattia Gonano.' % globals())
'Written 2013 by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals())
def Usage():
print "Generates HTML, NCX and OPF for a Comic ebook from a bunch of images."
print "Generates EPUB/CBZ comic ebook from a bunch of images."
parser.print_help()
@@ -621,8 +622,6 @@ def main(argv=None):
help="Outputs a CBZ archive and does not generate EPUB")
parser.add_option("--nopanelviewhq", action="store_true", dest="nopanelviewhq", default=False,
help="Disable high quality Panel View [Default=False]")
parser.add_option("--panelviewhorizontal", action="store_true", dest="panelviewhorizontal", default=False,
help="Enable horizontal Panel View [Default=False]")
parser.add_option("--noprocessing", action="store_false", dest="imgproc", default=True,
help="Do not apply image preprocessing (Page splitting and optimizations) [Default=True]")
parser.add_option("--forcepng", action="store_true", dest="forcepng", default=False,
@@ -696,25 +695,33 @@ def getOutputFilename(srcpath, wantedname, ext):
def checkOptions():
global options
# Landscape mode is only supported by Kindle Touch and Paperwhite.
if options.profile == 'K4T' or options.profile == 'KHD':
options.landscapemode = True
else:
options.landscapemode = False
# Older Kindle don't support Virtual Panel View. We providing them configuration that will fake that feature.
if options.profile == 'K3' or options.profile == 'K4NT':
#Real Panel View
# Real Panel View
options.panelview = True
else:
#Virtual Panel View
# Virtual Panel View
options.panelview = False
# Older Kindle don't need higher resolution files due lack of Panel View.
# Kindle Fire family have very high resolution. Bigger images are not needed.
if options.profile == 'K1' or options.profile == 'K2' or options.profile == 'KDX' or options.profile == 'KDXG'\
or options.profile == 'KF' or options.profile == 'KFHD' or options.profile == 'KFHD8':
options.nopanelviewhq = True
# Disabling grayscale conversion for Kindle Fire family.
# Forcing JPEG output. For now code can't provide color PNG files.
if options.profile == 'KF' or options.profile == 'KFHD' or options.profile == 'KFHD8':
options.forcecolor = True
options.forcepng = False
else:
options.forcecolor = False
if options.panelviewhorizontal:
# Mixing vertical and horizontal pages require real Panel View.
# Landscape mode don't work correcly without Virtual Panel View.
if options.rotate:
options.panelview = True
options.landscapemode = False
@@ -723,6 +730,7 @@ def getEpubPath():
global epub_path
return epub_path
if __name__ == "__main__":
Copyright()
main(sys.argv[1:])

View File

@@ -20,7 +20,7 @@ __copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>'
__docformat__ = 'restructuredtext en'
import os
from PIL import Image, ImageOps, ImageStat
from PIL import Image, ImageOps, ImageStat, ImageChops
class ImageFlags:
@@ -119,16 +119,21 @@ class ComicPage:
raise RuntimeError('Cannot read image file %s' % source)
self.image = self.image.convert('RGB')
def saveToDir(self, targetdir, forcepng, color=False):
def saveToDir(self, targetdir, forcepng, color, sufix=None):
filename = os.path.basename(self.origFileName)
try:
if not color:
self.image = self.image.convert('L') # convert to grayscale
# Sufix is used to recognise which files need horizontal Panel View.
if sufix == "R":
sufix = "_rotated"
else:
sufix = ""
os.remove(os.path.join(targetdir, filename))
if forcepng:
self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".png"), "PNG")
self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + sufix + ".png"), "PNG")
else:
self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".jpg"), "JPEG")
self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + sufix + ".jpg"), "JPEG")
except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
@@ -202,7 +207,7 @@ class ComicPage:
if (width > height) != (dstwidth > dstheight):
if rotate:
self.image = self.image.rotate(90)
return None
return "R"
else:
if width > height:
# source is landscape, so split by the width
@@ -232,95 +237,97 @@ class ComicPage:
return None
def cutPageNumber(self):
widthImg, heightImg = self.image.size
delta = 2
diff = delta
fixedThreshold = 5
if ImageStat.Stat(self.image).var[0] < 2 * fixedThreshold:
return self.image
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < fixedThreshold\
and diff < heightImg:
diff += delta
diff -= delta
pageNumberCut1 = diff
if diff < delta:
if ImageChops.invert(self.image).getbbox() is not None:
widthImg, heightImg = self.image.size
delta = 2
diff = delta
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] - oldStat > 0\
and diff < heightImg / 4:
fixedThreshold = 5
if ImageStat.Stat(self.image).var[0] < 2 * fixedThreshold:
return self.image
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < fixedThreshold\
and diff < heightImg:
diff += delta
diff -= delta
pageNumberCut1 = diff
if diff < delta:
diff = delta
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta
diff -= delta
pageNumberCut2 = diff
diff += delta
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]\
< fixedThreshold + oldStat and diff < heightImg / 4:
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] - oldStat > 0\
and diff < heightImg / 4:
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta
diff -= delta
pageNumberCut2 = diff
diff += delta
diff -= delta
pageNumberCut3 = diff
delta = 5
diff = delta
while ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut2, diff, heightImg))).var[0] < fixedThreshold\
and diff < widthImg:
diff += delta
diff -= delta
pageNumberX1 = diff
diff = delta
while ImageStat.Stat(self.image.crop((widthImg - diff, heightImg - pageNumberCut2,
widthImg, heightImg))).var[0] < fixedThreshold and diff < widthImg:
diff += delta
diff -= delta
pageNumberX2 = widthImg - diff
if pageNumberCut3 - pageNumberCut1 > 2 * delta\
and float(pageNumberX2 - pageNumberX1) / float(pageNumberCut2 - pageNumberCut1) <= 9.0\
and ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut3, widthImg, heightImg))).var[0]\
/ ImageStat.Stat(self.image).var[0] < 0.1\
and pageNumberCut3 < heightImg / 4 - delta:
diff = pageNumberCut3
else:
diff = pageNumberCut1
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]\
< fixedThreshold + oldStat and diff < heightImg / 4:
diff += delta
diff -= delta
pageNumberCut3 = diff
delta = 5
diff = delta
while ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut2, diff, heightImg))).var[0] < fixedThreshold\
and diff < widthImg:
diff += delta
diff -= delta
pageNumberX1 = diff
diff = delta
while ImageStat.Stat(self.image.crop((widthImg - diff, heightImg - pageNumberCut2,
widthImg, heightImg))).var[0] < fixedThreshold and diff < widthImg:
diff += delta
diff -= delta
pageNumberX2 = widthImg - diff
if pageNumberCut3 - pageNumberCut1 > 2 * delta\
and float(pageNumberX2 - pageNumberX1) / float(pageNumberCut2 - pageNumberCut1) <= 9.0\
and ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut3, widthImg, heightImg))).var[0]\
/ ImageStat.Stat(self.image).var[0] < 0.1\
and pageNumberCut3 < heightImg / 4 - delta:
diff = pageNumberCut3
else:
diff = pageNumberCut1
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
return self.image
def cropWhiteSpace(self, threshold):
widthImg, heightImg = self.image.size
delta = 10
diff = delta
# top
while ImageStat.Stat(self.image.crop((0, 0, widthImg, diff))).var[0] < threshold and diff < heightImg:
diff += delta
diff -= delta
# print "Top crop: %s"%diff
self.image = self.image.crop((0, diff, widthImg, heightImg))
widthImg, heightImg = self.image.size
diff = delta
# left
while ImageStat.Stat(self.image.crop((0, 0, diff, heightImg))).var[0] < threshold and diff < widthImg:
diff += delta
diff -= delta
# print "Left crop: %s"%diff
self.image = self.image.crop((diff, 0, widthImg, heightImg))
widthImg, heightImg = self.image.size
diff = delta
# down
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < threshold\
and diff < heightImg:
diff += delta
diff -= delta
# print "Down crop: %s"%diff
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
widthImg, heightImg = self.image.size
diff = delta
# right
while ImageStat.Stat(self.image.crop((widthImg - diff, 0, widthImg, heightImg))).var[0] < threshold\
and diff < widthImg:
diff += delta
diff -= delta
# print "Right crop: %s"%diff
self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
# print "New size: %sx%s"%(self.image.size[0],self.image.size[1])
if ImageChops.invert(self.image).getbbox() is not None:
widthImg, heightImg = self.image.size
delta = 10
diff = delta
# top
while ImageStat.Stat(self.image.crop((0, 0, widthImg, diff))).var[0] < threshold and diff < heightImg:
diff += delta
diff -= delta
# print "Top crop: %s"%diff
self.image = self.image.crop((0, diff, widthImg, heightImg))
widthImg, heightImg = self.image.size
diff = delta
# left
while ImageStat.Stat(self.image.crop((0, 0, diff, heightImg))).var[0] < threshold and diff < widthImg:
diff += delta
diff -= delta
# print "Left crop: %s"%diff
self.image = self.image.crop((diff, 0, widthImg, heightImg))
widthImg, heightImg = self.image.size
diff = delta
# down
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < threshold\
and diff < heightImg:
diff += delta
diff -= delta
# print "Down crop: %s"%diff
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
widthImg, heightImg = self.image.size
diff = delta
# right
while ImageStat.Stat(self.image.crop((widthImg - diff, 0, widthImg, heightImg))).var[0] < threshold\
and diff < widthImg:
diff += delta
diff -= delta
# print "Right crop: %s"%diff
self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
# print "New size: %sx%s"%(self.image.size[0],self.image.size[1])
return self.image
# def addProgressbar(self, file_number, files_totalnumber, size, howoften):