Cristian's PDF generation patch
This commit is contained in:
parent
a71ff52e22
commit
8077ca5391
8
README
8
README
@ -0,0 +1,8 @@
|
||||
REQUIREMENTS
|
||||
============
|
||||
|
||||
Python Image Library (PIL)
|
||||
PyQT4
|
||||
Reportlab
|
||||
|
||||
Mangle 2.4 Unofficial version
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010 Alex Yatskov
|
||||
#
|
||||
|
@ -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,9 +210,12 @@ 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)'
|
||||
)
|
||||
self.addImageFiles(filenames)
|
||||
if(self.containsCbzFile(filenames)):
|
||||
self.addCBZFiles(filenames)
|
||||
else:
|
||||
self.addImageFiles(filenames)
|
||||
|
||||
|
||||
def onBookAddDirectory(self):
|
||||
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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,16 +171,17 @@ 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)
|
||||
image = orientImage(image, size)
|
||||
if flags & ImageFlags.Resize:
|
||||
image = resizeImage(image, size)
|
||||
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)
|
||||
image = frameImage(image, tuple(palette[:3]), tuple(palette[-3:]), size)
|
||||
if flags & ImageFlags.Quantize:
|
||||
image = quantizeImage(image, palette)
|
||||
image = quantizeImage(image, palette)
|
||||
|
||||
try:
|
||||
image.save(target)
|
||||
|
@ -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,10 +58,12 @@ 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():
|
||||
imageFlags |= ImageFlags.Frame
|
||||
imageFlags |= ImageFlags.Frame
|
||||
|
||||
modified = (
|
||||
self.book.title != title or
|
||||
|
49
mangle/pdfimage.py
Normal file
49
mangle/pdfimage.py
Normal 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()
|
@ -99,7 +99,7 @@
|
||||
<widget class="QComboBox" name="comboBoxFormat">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Images & CBZ</string>
|
||||
<string>Images & CBZ & 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>
|
||||
|
Loading…
Reference in New Issue
Block a user