Merge pull request #24 from naparuba/master

Master
This commit is contained in:
Alex Yatskov 2015-10-23 10:54:31 +09:00
commit f1f94ccfba
6 changed files with 94 additions and 51 deletions

View File

@ -30,9 +30,18 @@ import util
# Sort function use to sort files in a natural order, by lowering # 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) # 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_): def natural_key(string_):
"""See http://www.codinghorror.com/blog/archives/001018.html""" l = []
return [int(s) if s.isdigit() else s.lower() for s in re.split(r'(\d+)', string_)] 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): class Book(object):

View File

@ -16,10 +16,10 @@
import os import os
import shutil import shutil
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from image import ImageFlags
from image import ImageFlags
import cbz import cbz
import image import image
import pdfimage import pdfimage
@ -121,7 +121,6 @@ class DialogConvert(QtGui.QProgressDialog):
archive = self.archive archive = self.archive
pdf = self.pdf pdf = self.pdf
# Maybe the user ask for a split, but the picture is not a large one, so skip # Maybe the user ask for a split, but the picture is not a large one, so skip
# it but only for this picture # it but only for this picture
if (flags & ImageFlags.Split) or (flags & ImageFlags.SplitInverse): if (flags & ImageFlags.Split) or (flags & ImageFlags.SplitInverse):

View File

@ -16,8 +16,7 @@
import os import os
from PIL import Image, ImageDraw from PIL import Image, ImageDraw, ImageStat, ImageChops
class ImageFlags: class ImageFlags:
@ -30,6 +29,7 @@ class ImageFlags:
SplitRight = 1 << 6 # split only the right page SplitRight = 1 << 6 # split only the right page
SplitLeft = 1 << 7 # split only the left page SplitLeft = 1 << 7 # split only the left page
SplitInverse = 1 << 8 # split left then right page SplitInverse = 1 << 8 # split left then right page
AutoCrop = 1 << 9 # split left then right page
class KindleData: class KindleData:
@ -179,6 +179,15 @@ def orientImage(image, size):
return image 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): def frameImage(image, foreground, background, size):
widthDev, heightDev = size widthDev, heightDev = size
widthImg, heightImg = image.size widthImg, heightImg = image.size
@ -240,6 +249,9 @@ def convertImage(source, target, device, flags):
raise RuntimeError('Unexpected output device %s' % device) raise RuntimeError('Unexpected output device %s' % device)
# Load image from source path # Load image from source path
image = loadImage(source) image = loadImage(source)
# Format according to palette # Format according to palette
image = formatImage(image) image = formatImage(image)
# Apply flag transforms # Apply flag transforms
@ -257,6 +269,10 @@ def convertImage(source, target, device, flags):
if (flags & ImageFlags.SplitInverse): if (flags & ImageFlags.SplitInverse):
image = splitRight(image) 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: if flags & ImageFlags.Orient:
image = orientImage(image, size) image = orientImage(image, size)
if flags & ImageFlags.Resize: if flags & ImageFlags.Resize:
@ -265,6 +281,9 @@ def convertImage(source, target, device, flags):
image = stretchImage(image, size) image = stretchImage(image, size)
if flags & ImageFlags.Frame: if flags & ImageFlags.Frame:
image = frameImage(image, tuple(palette[:3]), tuple(palette[-3:]), size) image = frameImage(image, tuple(palette[:3]), tuple(palette[-3:]), size)
if flags & ImageFlags.Quantize: if flags & ImageFlags.Quantize:
image = quantizeImage(image, palette) image = quantizeImage(image, palette)

View File

@ -35,6 +35,7 @@ class DialogOptions(QtGui.QDialog):
self.moveDialogToOptions() self.moveDialogToOptions()
# Get options from current book (like a loaded one) and set the dialog values
def moveOptionsToDialog(self): def moveOptionsToDialog(self):
self.lineEditTitle.setText(self.book.title or 'Untitled') self.lineEditTitle.setText(self.book.title or 'Untitled')
self.comboBoxDevice.setCurrentIndex(max(self.comboBoxDevice.findText(self.book.device), 0)) self.comboBoxDevice.setCurrentIndex(max(self.comboBoxDevice.findText(self.book.device), 0))
@ -47,12 +48,15 @@ class DialogOptions(QtGui.QDialog):
self.checkboxFrame.setChecked(self.book.imageFlags & ImageFlags.Frame) self.checkboxFrame.setChecked(self.book.imageFlags & ImageFlags.Frame)
# Save parameters set on the dialogs to the book object if need
def moveDialogToOptions(self): def moveDialogToOptions(self):
# First get dialog values
title = self.lineEditTitle.text() title = self.lineEditTitle.text()
device = self.comboBoxDevice.currentText() device = self.comboBoxDevice.currentText()
outputFormat = self.comboBoxFormat.currentText() outputFormat = self.comboBoxFormat.currentText()
overwrite = self.checkboxOverwrite.isChecked() overwrite = self.checkboxOverwrite.isChecked()
# Now compute flags
imageFlags = 0 imageFlags = 0
if self.checkboxOrient.isChecked(): if self.checkboxOrient.isChecked():
imageFlags |= ImageFlags.Orient imageFlags |= ImageFlags.Orient
@ -68,7 +72,12 @@ class DialogOptions(QtGui.QDialog):
imageFlags |= ImageFlags.Split imageFlags |= ImageFlags.Split
if self.checkboxSplitInverse.isChecked(): if self.checkboxSplitInverse.isChecked():
imageFlags |= ImageFlags.SplitInverse 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
# warn for nothing the user
modified = ( modified = (
self.book.title != title or self.book.title != title or
self.book.device != device or self.book.device != device or

View File

@ -188,6 +188,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkboxAutoCrop">
<property name="text">
<string>Auto crop image (remove white around the image)</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">