Added python only converter backend supporting resizing, zooming and rotation
This commit is contained in:
@@ -2,13 +2,6 @@ class ConverterBase(object):
|
||||
"""
|
||||
Base class that all backend classes must inherit
|
||||
"""
|
||||
|
||||
def identify_file(self, input_filepath, *args, **kwargs):
|
||||
raise NotImplementedError("Your %s class has not defined a identify_file() method, which is required." % self.__class__.__name__)
|
||||
|
||||
def identify_document(self, document, *args, **kwargs):
|
||||
raise NotImplementedError("Your %s class has not defined a identify_document() method, which is required." % self.__class__.__name__)
|
||||
|
||||
def convert_file(self, input_filepath, *args, **kwargs):
|
||||
raise NotImplementedError("Your %s class has not defined a convert_file() method, which is required." % self.__class__.__name__)
|
||||
|
||||
@@ -21,22 +14,5 @@ class ConverterBase(object):
|
||||
def get_available_transformations(self):
|
||||
raise NotImplementedError("Your %s class has not defined a get_available_transformations() method, which is required." % self.__class__.__name__)
|
||||
|
||||
def get_transformation_string(self, transformation_list):
|
||||
transformations = []
|
||||
warnings = []
|
||||
transformation_choices = self.get_available_transformations()
|
||||
for transformation in transformation_list:
|
||||
try:
|
||||
if transformation['transformation'] in transformation_choices:
|
||||
transformations.append(
|
||||
transformation_choices[transformation['transformation']]['command_line'] % eval(
|
||||
transformation['arguments']
|
||||
)
|
||||
)
|
||||
except Exception, e:
|
||||
warnings.append(e)
|
||||
|
||||
return u' '.join(transformations), warnings
|
||||
|
||||
def get_page_count(self):
|
||||
raise NotImplementedError("Your %s class has not defined a get_page_count() method, which is required." % self.__class__.__name__)
|
||||
|
||||
@@ -4,7 +4,8 @@ import re
|
||||
from converter.conf.settings import GM_PATH
|
||||
from converter.conf.settings import GM_SETTINGS
|
||||
from converter.literals import QUALITY_DEFAULT, QUALITY_SETTINGS
|
||||
from converter.exceptions import ConvertError, UnknownFormat, IdentifyError
|
||||
from converter.exceptions import ConvertError, UnknownFormat, \
|
||||
IdentifyError
|
||||
from converter.backends import ConverterBase
|
||||
from converter.literals import TRANSFORMATION_RESIZE, \
|
||||
TRANSFORMATION_ROTATE, TRANSFORMATION_DENSITY, \
|
||||
@@ -50,7 +51,7 @@ class ConverterClass(ConverterBase):
|
||||
arguments.append(u'-rotate')
|
||||
arguments.append(u'%s' % transformation['arguments']['degrees'])
|
||||
|
||||
if format == u'jpg':
|
||||
if format == u'jpeg':
|
||||
arguments.append(u'-quality')
|
||||
arguments.append(u'85')
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from converter.conf.settings import IM_IDENTIFY_PATH
|
||||
from converter.conf.settings import IM_CONVERT_PATH
|
||||
from converter.api import QUALITY_DEFAULT, QUALITY_SETTINGS
|
||||
@@ -12,6 +10,8 @@ from converter.backends import ConverterBase
|
||||
from converter.literals import TRANSFORMATION_RESIZE, \
|
||||
TRANSFORMATION_ROTATE, TRANSFORMATION_DENSITY, \
|
||||
TRANSFORMATION_ZOOM
|
||||
from converter.literals import DIMENSION_SEPARATOR, DEFAULT_PAGE_NUMBER, \
|
||||
DEFAULT_FILE_FORMAT
|
||||
|
||||
CONVERTER_ERROR_STRING_NO_DECODER = u'no decode delegate for this image format'
|
||||
|
||||
@@ -30,7 +30,6 @@ class ConverterClass(ConverterBase):
|
||||
raise IdentifyError(proc.stderr.readline())
|
||||
return proc.stdout.read()
|
||||
|
||||
|
||||
def convert_file(self, input_filepath, output_filepath, quality=QUALITY_DEFAULT, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT):
|
||||
arguments = []
|
||||
if transformations:
|
||||
@@ -51,7 +50,7 @@ class ConverterClass(ConverterBase):
|
||||
arguments.append(u'-rotate')
|
||||
arguments.append(u'%s' % transformation['arguments']['degrees'])
|
||||
|
||||
if format == u'jpg':
|
||||
if format == u'jpeg':
|
||||
arguments.append(u'-quality')
|
||||
arguments.append(u'85')
|
||||
|
||||
|
||||
@@ -6,13 +6,11 @@ from converter.literals import QUALITY_DEFAULT, QUALITY_SETTINGS
|
||||
from converter.exceptions import ConvertError, UnknownFormat, IdentifyError
|
||||
from converter.backends import ConverterBase
|
||||
from converter.literals import TRANSFORMATION_RESIZE, \
|
||||
TRANSFORMATION_ROTATE
|
||||
TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM
|
||||
from converter.literals import QUALITY_DEFAULT, DEFAULT_PAGE_NUMBER, \
|
||||
DEFAULT_FILE_FORMAT
|
||||
|
||||
class ConverterClass(ConverterBase):
|
||||
def identify_file(self, input_filepath, arguments=None):
|
||||
pass
|
||||
|
||||
|
||||
def get_page_count(self, input_filepath):
|
||||
page_count = 1
|
||||
im = Image.open(input_filepath)
|
||||
@@ -27,32 +25,38 @@ class ConverterClass(ConverterBase):
|
||||
|
||||
return page_count
|
||||
|
||||
|
||||
def convert_file(self, input_filepath, output_filepath, quality=QUALITY_DEFAULT, arguments=None):
|
||||
def convert_file(self, input_filepath, output_filepath, transformations=None, quality=QUALITY_DEFAULT, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT):
|
||||
try:
|
||||
im = Image.open(input_filepath)
|
||||
outfile, format = output_filepath.split(u':')
|
||||
im.save(outfile, format)
|
||||
'''
|
||||
command = []
|
||||
command.append(unicode(GM_PATH))
|
||||
command.append(u'convert')
|
||||
command.extend(unicode(QUALITY_SETTINGS[quality]).split())
|
||||
command.extend(unicode(GM_SETTINGS).split())
|
||||
command.append(unicode(input_filepath))
|
||||
if arguments:
|
||||
command.extend(unicode(arguments).split())
|
||||
command.append(unicode(output_filepath))
|
||||
proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
return_code = proc.wait()
|
||||
if return_code != 0:
|
||||
#Got an error from convert program
|
||||
error_line = proc.stderr.readline()
|
||||
if (CONVERTER_ERROR_STRING_NO_DECODER in error_line) or (CONVERTER_ERROR_STARTS_WITH in error_line):
|
||||
#Try to determine from error message which class of error is it
|
||||
except Exception: # Python Imaging Library doesn't recognize it as an image
|
||||
raise UnknownFormat
|
||||
else:
|
||||
raise ConvertError(error_line)
|
||||
'''
|
||||
|
||||
current_page = 0
|
||||
try:
|
||||
while current_page == page - 1:
|
||||
im.seek(im.tell() + 1)
|
||||
current_page += 1
|
||||
# do something to im
|
||||
except EOFError:
|
||||
pass # end of sequence
|
||||
|
||||
if transformations:
|
||||
for transformation in transformations:
|
||||
aspect = 1.0 * im.size[1] / im.size[0]
|
||||
if transformation['transformation'] == TRANSFORMATION_RESIZE:
|
||||
width = int(transformation['arguments']['width'])
|
||||
height = int(transformation['arguments'].get('height', 1.0 * width * aspect))
|
||||
im = im.resize((width, height), Image.ANTIALIAS)
|
||||
elif transformation['transformation'] == TRANSFORMATION_ZOOM:
|
||||
decimal_value = float(transformation['arguments']['percent']) / 100
|
||||
im = im.transform((im.size[0] * decimal_value, im.size[1] * decimal_value), Image.EXTENT, (0, 0, im.size[0], im.size[1]))
|
||||
elif transformation['transformation'] == TRANSFORMATION_ROTATE:
|
||||
# PIL counter degress counter-clockwise, reverse them
|
||||
im = im.rotate(360 - transformation['arguments']['degrees'])
|
||||
|
||||
if im.mode not in ('L', 'RGB'):
|
||||
im = im.convert('RGB')
|
||||
im.save(output_filepath, format=file_format)
|
||||
|
||||
def get_format_list(self):
|
||||
"""
|
||||
@@ -65,16 +69,8 @@ class ConverterClass(ConverterBase):
|
||||
|
||||
return formats
|
||||
|
||||
|
||||
def get_available_transformations(self):
|
||||
return [
|
||||
TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE
|
||||
TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, \
|
||||
TRANSFORMATION_ZOOM
|
||||
]
|
||||
|
||||
|
||||
def get_page_count(self, input_filepath):
|
||||
try:
|
||||
return len(self.identify_file(unicode(input_filepath)).splitlines())
|
||||
except:
|
||||
#TODO: send to other page number identifying program
|
||||
return 1
|
||||
|
||||
@@ -8,7 +8,7 @@ from converter.conf.settings import PRINT_QUALITY_OPTIONS
|
||||
DEFAULT_ZOOM_LEVEL = 100
|
||||
DEFAULT_ROTATION = 0
|
||||
DEFAULT_PAGE_NUMBER = 1
|
||||
DEFAULT_FILE_FORMAT = u'jpg'
|
||||
DEFAULT_FILE_FORMAT = u'jpeg'
|
||||
DEFAULT_OCR_FILE_FORMAT = u'tif'
|
||||
|
||||
QUALITY_DEFAULT = u'quality_default'
|
||||
|
||||
Reference in New Issue
Block a user