def _makeDisplayPhoto( self, format=None, # pylint: disable=redefined-builtin quality=_MARKER, resolution=None, frame=None, image_size=None, crop=False, ): """Create given display.""" if quality is _MARKER: quality = self.getDefaultImageQuality(format) width, height = image_size # pylint: disable=unpacking-non-sequence base, ext = splitext(self.id) id_ = '%s_%s_%s.%s' % ( base, width, height, ext, ) image = OFSImage( id_, self.getTitle(), self._getDisplayData(format, quality, resolution, frame, image_size, crop)) return image.content_type, aq_base(image)
def _makeDisplayPhoto(self, format=None, quality=_MARKER, resolution=None, frame=None, image_size=None): """Create given display.""" if quality is _MARKER: quality = self.getDefaultImageQuality(format) width, height = image_size base, ext = splitext(self.id) id = '%s_%s_%s.%s' % ( base, width, height, ext, ) image = OFSImage( id, self.getTitle(), self._getDisplayData(format, quality, resolution, frame, image_size)) return image.content_type, aq_base(image)
def _getContentTypeAndImageData( self, format, # pylint: disable=redefined-builtin quality, resolution, frame, image_size, crop, ): """Return the content type and the image data as str or PData.""" if crop: width, height = image_size else: width, height = self._getAspectRatioSize(*image_size) if ((width, height) == image_size or (width, height) == (0, 0))\ and quality == self.getDefaultImageQuality(format) and resolution is None and frame is None\ and not format: # No resizing, no conversion, return raw image return self.getContentType(), self.getData() image_file = self._resize(quality, width, height, format, resolution, frame, crop) image = OFSImage('', '', image_file) content_type = image.content_type if content_type == 'application/octet-stream': # If OFS Image could not guess content type, try with PIL image_file.seek(0) try: pil_image = PIL.Image.open(image_file) except IOError: pass else: content_type = pil_image.get_format_mimetype() mimetype_list = self.getPortalObject( ).mimetypes_registry.lookup(content_type) if mimetype_list: content_type = mimetype_list[0].normalized() return content_type, image.data
def includeImageList(self, data): """Include Images in ODF archive - data: zipped archive content """ builder = OOoBuilder(data) content = builder.extract('content.xml') xml_doc = etree.XML(content) image_tag_list = xml_doc.xpath('//*[name() = "draw:image"]') SVG_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0' XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink' ratio_px_cm = 2.54 / 100. # Flag to enable modification of OOoBuilder odt_content_modified = False for image_tag in image_tag_list: frame = image_tag.getparent() #Try to get image file from ZODB href_attribute_list = image_tag.xpath( './/@*[name() = "xlink:href"]') url = href_attribute_list[0] parse_result = urlparse(unquote(url)) # urlparse return a 6-tuple: scheme, netloc, path, params, query, fragment netloc = parse_result[1] path = parse_result[2] if path and netloc in ('', None): # it makes sense to include only relative to current site images not remote ones which can be taken by OOo # OOo corrupt relative Links inside HTML content during odt conversion # <img src="REF.TO.IMAGE" ... /> become <draw:image xlink:href="../REF.TO.IMAGE" ... /> # So remove "../" added by OOo path = CLEAN_RELATIVE_PATH.sub('', path) # in some cases like Web Page content "/../" can be contained in image URL which will break # restrictedTraverse calls, our best guess is to remove it path = path.replace('/../', '') # remove occurencies of '//' or '///' in path (happens with web pages) and leave # a traversable relative URL path = '/'.join( [x for x in path.split('/') if x.strip() != '']) # retrieve http parameters and use them to convert image query_parameter_string = parse_result[4] image_parameter_dict = dict(parse_qsl(query_parameter_string)) try: image = self.context.restrictedTraverse(path) except (AttributeError, KeyError): #Image not found, this image is probably not hosted by ZODB. Do nothing image = None if image is not None: odt_content_modified = True content_type = image.getContentType() format = image_parameter_dict.pop('format', None) # convert API accepts only a certail range of arguments for key, value in ensure_list( image_parameter_dict.items()): if key not in ( 'format', 'display', 'quality', 'resolution', ): image_parameter_dict.pop(key) if getattr(image, 'convert', None) is not None: # The document support conversion so perform conversion # according given parameters mime, image_data = image.convert( format, **image_parameter_dict) # wrapp converted data into OFSImage in order to compute metadatas # on converted result image = OFSImage(image.getId(), image.getTitle(), image_data) # image should be OFSImage data = str(image.data) width = image.width height = image.height if height: frame.attrib.update({ '{%s}height' % SVG_NAMESPACE: '%.3fcm' % (height * ratio_px_cm) }) if width: frame.attrib.update({ '{%s}width' % SVG_NAMESPACE: '%.3fcm' % (width * ratio_px_cm) }) if not format: mimetype_list = self.context.getPortalObject( ).mimetypes_registry.lookup(content_type) # guess a format with help of mimetypes_registry for mimetype_object in mimetype_list: if mimetype_object.extensions: format = mimetype_object.extensions[0] break elif mimetype_object.globs: format = mimetype_object.globs[0].strip('*.') break new_path = builder.addImage(data, format=format) image_tag.attrib.update( {'{%s}href' % XLINK_NAMESPACE: new_path}) if odt_content_modified: builder.replace( 'content.xml', etree.tostring(xml_doc, encoding='utf-8', xml_declaration=True, pretty_print=False)) return builder.render()
def generate_thumbnails(self, pdf_file_data_string): document_page_count = 0 page_number = 0 images = None pdf = None pdf_file_data_string = str(pdf_file_data_string) """If the file is a pdf file then we look inside with PyPDF and see how many pages there are. """ # if we've got a pdf file, # get the pdf file as a file object containing the data in a string # pdf_file_object = StringIO.StringIO(pdf_file_data_string) # create a pyPdf object from the pdf file data try: pdf = pyPdf.PdfFileReader(cStringIO.StringIO(pdf_file_data_string)) except: logger.warn("error opening pdf file, trying to fix it...") fixed_pdf_string = self.fixPdf(pdf_file_data_string) #try to reopen the pdf file again try: pdf = pyPdf.PdfFileReader(cStringIO.StringIO(fixed_pdf_string)) except: logger.warn("this pdf file cannot be fixed.") if pdf.isEncrypted: try: decrypt = pdf.decrypt('') if decrypt == 0: logger.warn("This pdf is password protected.") except: logger.warn( "Errors have been found while attempting to decrypt the pdf file." ) if pdf: # get the number of pages in the pdf file from the pyPdf object document_page_count = pdf.getNumPages() logger.info("Found a PDF file with %d pages." % (document_page_count)) if document_page_count > 0: # if we're dealing with a pdf file, # set the thumbnail size registry = getUtility(IRegistry) config = registry.forInterface(IPDFPeekConfiguration) thumb_size = (config.thumbnail_width, config.thumbnail_length) preview_size = (config.preview_width, config.preview_length) # set up the images dict images = {} for page in range(document_page_count): # for each page in the pdf file, # set up a human readable page number counter starting at 1 page_number = page + 1 # set up the image object ids and titles image_id = "%d_preview" % page_number image_title = "Page %d Preview" % page_number image_thumb_id = "%d_thumb" % page_number image_thumb_title = "Page %d Thumbnail" % page_number # create a file object to store the thumbnail and preview in raw_image_thumb = cStringIO.StringIO() raw_image_preview = cStringIO.StringIO() # run ghostscript, convert pdf page into image raw_image = self.ghostscript_transform( pdf_file_data_string, page_number) # use PIL to generate thumbnail from image_result img_thumb = Image.open(cStringIO.StringIO(raw_image)) img_thumb.thumbnail(thumb_size, Image.ANTIALIAS) # save the resulting thumbnail in the file object img_thumb.save(raw_image_thumb, "PNG") # use PIL to generate preview from image_result img_preview = Image.open(cStringIO.StringIO(raw_image)) img_preview.thumbnail(preview_size, Image.ANTIALIAS) # save the resulting thumbnail in the file object img_preview.save(raw_image_preview, "PNG") # create the OFS.Image objects image_full_object = OFSImage(image_id, image_title, raw_image_preview) image_thumb_object = OFSImage(image_thumb_id, image_thumb_title, raw_image_thumb) # add the objects to the images dict images[image_id] = image_full_object images[image_thumb_id] = image_thumb_object logger.info("Thumbnail generated.") else: logger.error("Error: %d pages in PDF file." % (document_page_count)) return images
def get_thumbnails(self, page_start=0, pages=1): """Fix other peoples missing docstrings.""" thumb_size = (self.settings.thumbnail_width, self.settings.thumbnail_length) preview_size = (self.settings.preview_width, self.settings.preview_length) # set up the images dict images = {} # Extracting self.pages pages logger.info('Extracting {0:d} page screenshots'.format(self.pages)) for page in range(page_start, page_start + pages): # for each page in the pdf file, # set up a human readable page number counter starting at 1 page_number = page + 1 # set up the image object ids and titles image_id = u'%d_preview' % page_number image_title = u'Page %d Preview' % page_number image_thumb_id = u'%d_thumb' % page_number image_thumb_title = u'Page %d Thumbnail' % page_number # create a file object to store the thumbnail and preview in raw_image_thumb = StringIO() raw_image_preview = StringIO() # run ghostscript, convert pdf page into image raw_image = self.ghostscript_transform(page_number) # use PIL to generate thumbnail from image_result try: img_thumb = Image.open(StringIO(raw_image)) except IOError: logger.error('This is not an image: {0}'.format(raw_image)) break img_thumb.thumbnail(thumb_size, Image.ANTIALIAS) # save the resulting thumbnail in the file object img_thumb.save(raw_image_thumb, format=self.img_thumb_format, quality=self.img_thumb_quality, optimize=self.img_thumb_optimize, progressive=self.img_thumb_progressive) # use PIL to generate preview from image_result img_preview = Image.open(StringIO(raw_image)) img_preview.thumbnail(preview_size, Image.ANTIALIAS) # save the resulting thumbnail in the file object img_preview.save(raw_image_preview, format=self.img_preview_format, quality=self.img_preview_quality, optimize=self.img_preview_optimize, progressive=self.img_preview_progressive) # create the OFS.Image objects if HAS_BLOBIMAGE: image_full_object = NamedBlobImage( filename=image_id, data=raw_image_preview.getvalue(), contentType='image/' + self.img_preview_format.lower()) image_thumb_object = NamedBlobImage( filename=image_thumb_id, data=raw_image_thumb.getvalue(), contentType='image/' + self.img_thumb_format.lower()) else: image_full_object = OFSImage( image_id, image_title, raw_image_preview) image_thumb_object = OFSImage( image_thumb_id, image_thumb_title, raw_image_thumb) # add the objects to the images dict images[image_id] = image_full_object images[image_thumb_id] = image_thumb_object logger.info('Thumbnail generated.') return images
def render_odg_view(self, field, value, as_string, ooo_builder, REQUEST, render_prefix, attr_dict, local_name): """ return an image xml node rendered in odg format if as_string is True (default) the returned value is a string (xml reprensation of the node), if it's False, the value returned is the node object. attr_dict can be used for additional parameters (like style). """ if attr_dict is None: attr_dict = {} draw_frame_node = None if value in ('', None): return None path = '/'.join(REQUEST.physicalPathFromURL(value)) path = path.encode() image_object = field.getPortalObject().restrictedTraverse(path) display = field.get_value('image_display') format = field.get_value('image_format') quality = field.get_value('image_quality') image_parameter_dict = {'format': format} if display: image_parameter_dict['display'] = display if quality: image_parameter_dict['quality'] = quality # convert the image using fields parameters. In this way, if an image # is displayed in the form as a thumbnail, it will be added in the odg # document as thumbnail size/quality content_type, image_data = image_object.convert(**image_parameter_dict) image = OFSImage('', '', image_data) width = image.width height = image.height if image_data is None: return draw_frame_node # Big images are cut into smaller chunks, so it's required to cast to # str. See OFS/Image -> _read_data method for more information image_data = str(image_data) format = content_type.split('/')[-1] # add the image to the odg document picture_path = ooo_builder.addImage(image=image_data, format=format, content_type=content_type) # create the xml nodes related to the image draw_frame_tag_name = '{%s}%s' % (DRAW_URI, 'frame') draw_frame_node = Element(draw_frame_tag_name, nsmap=NSMAP) draw_frame_node.attrib.update( attr_dict.get(draw_frame_tag_name, {}).pop(0)) # set the size of the image if display is not None: # if the image width and height are not on defined, use current # width and height if (image_object.getWidth(), image_object.getHeight()) not in \ ((-1, -1), (0,0)): width, height = image_object._getAspectRatioSize(width, height) if draw_frame_node.attrib.get('{%s}width' % SVG_URI) and \ draw_frame_node.attrib.get('{%s}height' % SVG_URI): # if a size already exist from attr_dict, try to resize the image to # fit this size (image should not be biger than size from attr_dict) # devide the value by 20 to have cm instead of px width, height = self._getPictureSize( width / 20., height / 20., target_width=draw_frame_node.attrib.get( '{%s}width' % SVG_URI, ''), target_height=draw_frame_node.attrib.get( '{%s}height' % SVG_URI, '')) draw_frame_node.set('{%s}width' % SVG_URI, str(width)) draw_frame_node.set('{%s}height' % SVG_URI, str(height)) image_tag_name = '{%s}%s' % (DRAW_URI, 'image') image_node = Element(image_tag_name, nsmap=NSMAP) image_node.attrib.update(attr_dict.get(image_tag_name, []).pop()) image_node.set('{%s}href' % XLINK_URI, picture_path) draw_frame_node.append(image_node) if as_string: return etree.tostring(draw_frame_node) return draw_frame_node