mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Initial implementation of PDF cropping tool, pdftrim
This commit is contained in:
commit
e7f2612643
@ -86,7 +86,7 @@ class PRS505(Device):
|
||||
deviceclass=cls.__name__,
|
||||
vendor_id=hex(cls.VENDOR_ID),
|
||||
product_id=hex(cls.PRODUCT_ID),
|
||||
bcd=hex(cls.BCD),
|
||||
bcd=hex(cls.BCD[0]),
|
||||
main_memory=cls.MAIN_MEMORY_VOLUME_LABEL,
|
||||
storage_card=cls.STORAGE_CARD_VOLUME_LABEL,
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ class Device(_Device):
|
||||
|
||||
VENDOR_ID = 0x0
|
||||
PRODUCT_ID = 0x0
|
||||
BCD = 0x0
|
||||
BCD = None
|
||||
|
||||
VENDOR_NAME = ''
|
||||
PRODUCT_NAME = ''
|
||||
@ -38,11 +38,9 @@ class Device(_Device):
|
||||
<match key="info.category" string="volume">
|
||||
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.vendor_id" int="%(vendor_id)s">
|
||||
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.product_id" int="%(product_id)s">
|
||||
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">
|
||||
<match key="volume.is_partition" bool="false">
|
||||
<match key="volume.is_partition" bool="false">
|
||||
<merge key="volume.label" type="string">%(main_memory)s</merge>
|
||||
<merge key="%(app)s.mainvolume" type="string">%(deviceclass)s</merge>
|
||||
</match>
|
||||
</match>
|
||||
</match>
|
||||
</match>
|
||||
@ -52,11 +50,9 @@ class Device(_Device):
|
||||
<match key="info.category" string="volume">
|
||||
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.vendor_id" int="%(vendor_id)s">
|
||||
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.product_id" int="%(product_id)s">
|
||||
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">
|
||||
<match key="volume.is_partition" bool="true">
|
||||
<match key="volume.is_partition" bool="true">
|
||||
<merge key="volume.label" type="string">%(storage_card)s</merge>
|
||||
<merge key="%(app)s.cardvolume" type="string">%(deviceclass)s</merge>
|
||||
</match>
|
||||
</match>
|
||||
</match>
|
||||
</match>
|
||||
@ -68,17 +64,22 @@ class Device(_Device):
|
||||
self._main_prefix = self._card_prefix = None
|
||||
|
||||
@classmethod
|
||||
def get_fdi(cls):
|
||||
def get_bcd_less_fdi(cls):
|
||||
return cls.FDI_TEMPLATE%dict(
|
||||
app=__appname__,
|
||||
deviceclass=cls.__name__,
|
||||
vendor_id=hex(cls.VENDOR_ID),
|
||||
product_id=hex(cls.PRODUCT_ID),
|
||||
bcd=hex(cls.BCD),
|
||||
main_memory=cls.MAIN_MEMORY_VOLUME_LABEL,
|
||||
storage_card=cls.STORAGE_CARD_VOLUME_LABEL,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_fdi(cls):
|
||||
if cls.BCD is None:
|
||||
return cls.get_bcd_less_fdi()
|
||||
raise NotImplementedError('TODO:')
|
||||
|
||||
def set_progress_reporter(self, report_progress):
|
||||
self.report_progress = report_progress
|
||||
|
||||
|
81
src/calibre/ebooks/pdf/pdftrim.py
Normal file
81
src/calibre/ebooks/pdf/pdftrim.py
Normal file
@ -0,0 +1,81 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, James Beal, james_@catbus.co.uk'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
'crop a pdf file'
|
||||
|
||||
import os, sys, re
|
||||
from calibre.utils.config import Config, StringConfig
|
||||
from pyPdf import PdfFileWriter, PdfFileReader
|
||||
|
||||
def config(defaults=None):
|
||||
desc = _('Options to control the transformation of pdf')
|
||||
default_crop=10
|
||||
if defaults is None:
|
||||
c = Config('trimpdf', desc)
|
||||
else:
|
||||
c = StringConfig(defaults, desc)
|
||||
c.add_opt('verbose', ['-v', '--verbose'], default=0, action='count',
|
||||
help=_('Be verbose, useful for debugging. Can be specified multiple times for greater verbosity.'))
|
||||
c.add_opt('output', ['-o', '--output'],default='cropped.pdf',
|
||||
help=_('Path to output file. By default a file is created in the current directory.'))
|
||||
c.add_opt('bottom_left_x', [ '-x', '--leftx'], default=default_crop,
|
||||
help=_('Number of pixels to crop from the left most x (default is %d) ')%default_crop )
|
||||
c.add_opt('bottom_left_y', [ '-y', '--lefty'], default=default_crop,
|
||||
help=_('Number of pixels to crop from the left most y (default is %d) ')%default_crop )
|
||||
c.add_opt('top_right_x', [ '-v', '--rightx'], default=default_crop,
|
||||
help=_('Number of pixels to crop from the right most x (default is %d) ')%default_crop )
|
||||
c.add_opt('top_right_y', [ '-w', '--righty'], default=default_crop,
|
||||
help=_('Number of pixels to crop from the right most y (default is %d)')%default_crop )
|
||||
c.add_opt('bounding', ['-b', '--bounding'],
|
||||
help=_('A file generated by ghostscript which allows each page to be individually cropped'))
|
||||
return c
|
||||
|
||||
|
||||
def option_parser():
|
||||
c = config()
|
||||
return c.option_parser(usage=_('''\
|
||||
%prog [options] file.pdf
|
||||
|
||||
Crop a pdf.
|
||||
'''))
|
||||
|
||||
def main(args=sys.argv):
|
||||
parser = option_parser()
|
||||
opts, args = parser.parse_args(args)
|
||||
source = os.path.abspath(args[1])
|
||||
input_pdf = PdfFileReader(file(source, "rb"))
|
||||
if opts.bounding != None:
|
||||
try:
|
||||
bounding = open( opts.bounding , 'r' )
|
||||
bounding_regex= re.compile('%%BoundingBox: (?P<bottom_x>[0-9]+) (?P<bottom_y>[0-9]+) (?P<top_x>[0-9]+) (?P<top_y>[0-9]+)')
|
||||
except:
|
||||
print 'Error opening %s' % opts.bounding
|
||||
return 1
|
||||
output_pdf = PdfFileWriter()
|
||||
for page_number in range (0, input_pdf.getNumPages() ):
|
||||
page = input_pdf.getPage(page_number)
|
||||
if opts.bounding != None:
|
||||
while True:
|
||||
line=bounding.readline()
|
||||
match=bounding_regex.search(line)
|
||||
if match !=None:
|
||||
break
|
||||
page.mediaBox.upperRight = (match.group('top_x'),match.group('top_y'))
|
||||
page.mediaBox.lowerLeft = (match.group('bottom_x'),match.group('bottom_y'))
|
||||
else:
|
||||
page.mediaBox.upperRight = (page.bleedBox.getUpperRight_x()-opts.top_right_x,page.bleedBox.getUpperRight_y()-opts.top_right_y)
|
||||
page.mediaBox.lowerLeft = (page.bleedBox.getLowerLeft_x()+opts.bottom_left_x,page.bleedBox.getLowerLeft_y()+opts.bottom_left_y)
|
||||
output_pdf.addPage(page)
|
||||
if opts.bounding != None:
|
||||
bounding.close()
|
||||
output_file = file(opts.output, "wb")
|
||||
output_pdf.write(output_file)
|
||||
output_file.close()
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
@ -65,6 +65,7 @@ entry_points = {
|
||||
'calibre-fontconfig = calibre.utils.fontconfig:main',
|
||||
'calibre-parallel = calibre.parallel:main',
|
||||
'calibre-customize = calibre.customize.ui:main',
|
||||
'pdftrim = calibre.ebooks.pdf.pdftrim:main' ,
|
||||
],
|
||||
'gui_scripts' : [
|
||||
__appname__+' = calibre.gui2.main:main',
|
||||
|
Loading…
x
Reference in New Issue
Block a user