Cristian's PDF generation patch

This commit is contained in:
Alex Yatskov 2012-07-28 11:08:50 -07:00
parent a71ff52e22
commit 8077ca5391
8 changed files with 158 additions and 19 deletions

8
README
View File

@ -0,0 +1,8 @@
REQUIREMENTS
============
Python Image Library (PIL)
PyQT4
Reportlab
Mangle 2.4 Unofficial version

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python
# Copyright (C) 2010 Alex Yatskov
#

View File

@ -16,8 +16,11 @@
import os
import os.path
from os.path import basename
import util
import tempfile
from PyQt4 import QtGui, QtCore, QtXml, uic
from zipfile import ZipFile
from image import ImageFlags
from about import DialogAbout
from options import DialogOptions
@ -26,7 +29,7 @@ from convert import DialogConvert
class Book(object):
DefaultDevice = 'Kindle 4'
DefaultOutputFormat = 'Images & CBZ'
DefaultOutputFormat = 'PDF only'
DefaultOverwrite = True
DefaultImageFlags = ImageFlags.Orient | ImageFlags.Resize | ImageFlags.Quantize
@ -207,8 +210,11 @@ class MainWindowBook(QtGui.QMainWindow):
filenames = QtGui.QFileDialog.getOpenFileNames(
parent=self,
caption='Select image file(s) to add',
filter='Image files (*.jpeg *.jpg *.gif *.png);;All files (*.*)'
filter='Image files (*.jpeg *.jpg *.gif *.png);;Comic files (*.cbz)'
)
if(self.containsCbzFile(filenames)):
self.addCBZFiles(filenames)
else:
self.addImageFiles(filenames)
@ -364,7 +370,6 @@ class MainWindowBook(QtGui.QMainWindow):
self.book.images.append(filename)
self.book.modified = True
def addImageDirs(self, directories):
filenames = []
@ -377,6 +382,33 @@ class MainWindowBook(QtGui.QMainWindow):
self.addImageFiles(filenames)
def addCBZFiles(self, filenames):
directories = []
tempDir = tempfile.gettempdir()
filenames.sort()
filenamesListed = []
for i in xrange(0, self.listWidgetFiles.count()):
filenamesListed.append(self.listWidgetFiles.item(i).text())
for filename in filenames:
folderName = os.path.splitext(basename(str(filename)))[0]
path = tempDir + "/" + folderName + "/"
cbzFile = ZipFile(str(filename))
for f in cbzFile.namelist():
if f.endswith('/'):
try:
os.makedirs(path+f)
except:
pass #the dir exists so we are going to extract the images only.
else:
cbzFile.extract(f, path)
#Add the directories
if os.path.isdir(unicode(path)):
directories.append(path)
#Add the files
self.addImageDirs(directories)
def isImageFile(self, filename):
imageExts = ['.jpeg', '.jpg', '.gif', '.png']
@ -386,6 +418,17 @@ class MainWindowBook(QtGui.QMainWindow):
os.path.splitext(filename)[1].lower() in imageExts
)
def containsCbzFile(self, filenames):
cbzExts = ['.cbz']
for filename in filenames:
filename = unicode(filename)
result = (
os.path.isfile(filename) and
os.path.splitext(filename)[1].lower() in cbzExts
)
if result == True:
return result
return False
def cleanupBookFile(self, filename):
if len(os.path.splitext(unicode(filename))[1]) == 0:

View File

@ -18,6 +18,7 @@ import os, shutil
from PyQt4 import QtGui, QtCore
import image
import cbz
import pdfimage
class DialogConvert(QtGui.QProgressDialog):
@ -36,6 +37,11 @@ class DialogConvert(QtGui.QProgressDialog):
if 'CBZ' in self.book.outputFormat:
self.archive = cbz.Archive(self.bookPath)
self.pdf = None
if "PDF" in self.book.outputFormat:
self.pdf = pdfimage.PDFImage(self.bookPath, str(self.book.title), str(self.book.device))
def showEvent(self, event):
if self.timer is None:
@ -50,6 +56,9 @@ class DialogConvert(QtGui.QProgressDialog):
# Close the archive if we created a CBZ file
if self.archive is not None:
self.archive.close()
#Close and generate the PDF File
if self.pdf is not None:
self.pdf.close()
# Remove image directory if the user didn't wish for images
if 'Image' not in self.book.outputFormat:
@ -98,6 +107,8 @@ class DialogConvert(QtGui.QProgressDialog):
image.convertImage(source, target, str(self.book.device), self.book.imageFlags)
if self.archive is not None:
self.archive.addFile(target)
if self.pdf is not None:
self.pdf.addImage(target)
except RuntimeError, error:
result = QtGui.QMessageBox.critical(
self,

View File

@ -22,6 +22,7 @@ class ImageFlags:
Resize = 1 << 1
Frame = 1 << 2
Quantize = 1 << 3
Stretch = 1 << 4
class KindleData:
@ -89,6 +90,10 @@ def quantizeImage(image, palette):
return image.quantize(palette=palImg)
def stretchImage(image, size):
widthDev, heightDev = size
return image.resize((widthDev, heightDev), Image.ANTIALIAS)
def resizeImage(image, size):
widthDev, heightDev = size
widthImg, heightImg = image.size
@ -166,12 +171,13 @@ def convertImage(source, target, device, flags):
image = Image.open(source)
except IOError:
raise RuntimeError('Cannot read image file %s' % source)
image = formatImage(image)
if flags & ImageFlags.Orient:
image = orientImage(image, size)
if flags & ImageFlags.Resize:
image = resizeImage(image, size)
if flags & ImageFlags.Stretch:
image = stretchImage(image, size)
if flags & ImageFlags.Frame:
image = frameImage(image, tuple(palette[:3]), tuple(palette[-3:]), size)
if flags & ImageFlags.Quantize:

View File

@ -42,6 +42,7 @@ class DialogOptions(QtGui.QDialog):
self.checkboxOverwrite.setChecked(self.book.overwrite)
self.checkboxOrient.setChecked(self.book.imageFlags & ImageFlags.Orient)
self.checkboxResize.setChecked(self.book.imageFlags & ImageFlags.Resize)
self.checkboxStretch.setChecked(self.book.imageFlags & ImageFlags.Stretch)
self.checkboxQuantize.setChecked(self.book.imageFlags & ImageFlags.Quantize)
self.checkboxFrame.setChecked(self.book.imageFlags & ImageFlags.Frame)
@ -57,6 +58,8 @@ class DialogOptions(QtGui.QDialog):
imageFlags |= ImageFlags.Orient
if self.checkboxResize.isChecked():
imageFlags |= ImageFlags.Resize
if self.checkboxStretch.isChecked():
imageFlags |= ImageFlags.Stretch
if self.checkboxQuantize.isChecked():
imageFlags |= ImageFlags.Quantize
if self.checkboxFrame.isChecked():

49
mangle/pdfimage.py Normal file
View File

@ -0,0 +1,49 @@
# Copyright (C) 2012 Cristian Lizana <cristian@lizana.in>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os.path
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from image import KindleData
class PDFImage(object):
def __init__(self, path, title, device):
outputDirectory = os.path.dirname(path)
outputFileName = '%s.pdf' % os.path.basename(path)
outputPath = os.path.join(outputDirectory, outputFileName)
self.currentDevice = device
self.bookTitle = title
self.pageSize = KindleData.Profiles[self.currentDevice][0]
#pagesize could be letter or A4 for standarization but we need to control some image sizes
self.canvas = canvas.Canvas(outputPath, pagesize=self.pageSize)
self.canvas.setAuthor("Mangle")
self.canvas.setTitle(self.bookTitle)
self.canvas.setSubject("Created for " + self.currentDevice)
def addImage(self, filename):
self.canvas.drawImage(filename, 0, 0, width=self.pageSize[0], height=self.pageSize[1], preserveAspectRatio=True, anchor='c')
self.canvas.showPage()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
def close(self):
self.canvas.save()

View File

@ -99,7 +99,7 @@
<widget class="QComboBox" name="comboBoxFormat">
<item>
<property name="text">
<string>Images &amp; CBZ</string>
<string>Images &amp; CBZ &amp; PDF</string>
</property>
</item>
<item>
@ -107,6 +107,11 @@
<string>Images only</string>
</property>
</item>
<item>
<property name="text">
<string>PDF only</string>
</property>
</item>
<item>
<property name="text">
<string>CBZ only</string>
@ -130,13 +135,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkboxResize">
<property name="text">
<string>Resize images to center on screen</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkboxQuantize">
<property name="text">
@ -150,6 +148,27 @@
<string>Draw frame around images</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="checkboxResize">
<property name="text">
<string>Resize images to center on screen</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="checkboxStretch">
<property name="text">
<string>Stretch images to fill the screen</string>
</property>
</widget>
</item>
</layout>
</widget>