diff --git a/mangle/book.py b/mangle/book.py index 1a3e6aa..fe8edfa 100644 --- a/mangle/book.py +++ b/mangle/book.py @@ -30,9 +30,18 @@ import util # Sort function use to sort files in a natural order, by lowering # characters, and manage multi levels of integers (tome 1/ page 1.jpg, etc etc) +# cf: See http://www.codinghorror.com/blog/archives/001018.html def natural_key(string_): - """See http://www.codinghorror.com/blog/archives/001018.html""" - return [int(s) if s.isdigit() else s.lower() for s in re.split(r'(\d+)', string_)] + l = [] + for s in re.split(r'(\d+)', string_): + # QString do not have isdigit, so convert it if need + if isinstance(s, QtCore.QString): + s = unicode(s) + if s.isdigit(): + l.append(int(s)) + else: + l.append(s.lower()) + return l class Book(object): diff --git a/mangle/image.py b/mangle/image.py index 67358e1..421bec3 100644 --- a/mangle/image.py +++ b/mangle/image.py @@ -16,20 +16,20 @@ import os -from PIL import Image, ImageDraw - +from PIL import Image, ImageDraw, ImageStat, ImageChops class ImageFlags: - Orient = 1 << 0 - Resize = 1 << 1 - Frame = 1 << 2 - Quantize = 1 << 3 - Stretch = 1 << 4 - Split = 1 << 5 # split right then left - SplitRight = 1 << 6 # split only the right page - SplitLeft = 1 << 7 # split only the left page + Orient = 1 << 0 + Resize = 1 << 1 + Frame = 1 << 2 + Quantize = 1 << 3 + Stretch = 1 << 4 + Split = 1 << 5 # split right then left + SplitRight = 1 << 6 # split only the right page + SplitLeft = 1 << 7 # split only the left page SplitInverse = 1 << 8 # split left then right page + AutoCrop = 1 << 9 # split left then right page class KindleData: @@ -179,6 +179,15 @@ def orientImage(image, size): return image +# We will auto crop the image, by removing just white part around the image +# by inverting colors, and asking a bounder box ^^ +@protect_bad_image +def autoCropImage(image): + x0, y0, xend, yend = ImageChops.invert(image).getbbox() + image = image.crop((x0, y0, xend, yend)) + return image + + def frameImage(image, foreground, background, size): widthDev, heightDev = size widthImg, heightImg = image.size @@ -240,6 +249,9 @@ def convertImage(source, target, device, flags): raise RuntimeError('Unexpected output device %s' % device) # Load image from source path image = loadImage(source) + + + # Format according to palette image = formatImage(image) # Apply flag transforms @@ -257,6 +269,10 @@ def convertImage(source, target, device, flags): if (flags & ImageFlags.SplitInverse): image = splitRight(image) + # Auto crop the image, but before manage size and co, clean the source so + if flags & ImageFlags.AutoCrop: + image = autoCropImage(image) + if flags & ImageFlags.Orient: image = orientImage(image, size) if flags & ImageFlags.Resize: @@ -265,7 +281,10 @@ def convertImage(source, target, device, flags): image = stretchImage(image, size) if flags & ImageFlags.Frame: image = frameImage(image, tuple(palette[:3]), tuple(palette[-3:]), size) + + + if flags & ImageFlags.Quantize: image = quantizeImage(image, palette) - - saveImage(image, target) + + saveImage(image, target) \ No newline at end of file diff --git a/mangle/options.py b/mangle/options.py index 19d6929..08a29dd 100644 --- a/mangle/options.py +++ b/mangle/options.py @@ -72,6 +72,8 @@ class DialogOptions(QtGui.QDialog): imageFlags |= ImageFlags.Split if self.checkboxSplitInverse.isChecked(): imageFlags |= ImageFlags.SplitInverse + if self.checkboxAutoCrop.isChecked(): + imageFlags |= ImageFlags.AutoCrop # If we did modified a value, update the book # and only if we did change something to not diff --git a/mangle/ui/options.ui b/mangle/ui/options.ui index 65df9bf..3619bbb 100644 --- a/mangle/ui/options.ui +++ b/mangle/ui/options.ui @@ -181,14 +181,21 @@ - + Split images into two pages (left, right) - + + + + Auto crop image (remove white around the image) + + + + Size