--- Begin Message ---
Dave,
One more suggestion from a user of your odtwriter package. I won’t
quote it in full here; as always, see http://bugs.debian.org/493056 to
read all of it.
Basically, there are two issues:
(1) OpenOffice.org does not look at image sizes itself. Thus, odtwriter
always has to add svg:height= and svg:width= specifications to
draw:frames. Otherwise, OOo renders the picture as a very tiny
frame.
(2) odtwriter does not look at DPI values stored in images.
I suggest the attached patch, which tries to solve these problems and
additionally adds unit support as described in [1]. It honors the DPI
value of the image if the user specifies a width and/or height in a
device-dependent unit (i.e., pixels), or if they don’t specify any.
[1]
http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#length-units
Kind regards,
--
Michael Schutte <[EMAIL PROTECTED]>
commit f7f420792eb5165c9df847cd4e5397c4f425017c
Author: Michael Schutte <[EMAIL PROTECTED]>
Date: Mon Aug 11 12:48:37 2008 +0200
Properly scale images
* Always provide complete size information. OpenOffice.org does not
figure out image sizes itself, but shows a really tiny square
instead. This means that PIL is now always required when working
with images, except when the user specifies width *and* height on all
of them.
* Support the usage of device-independent units, see
<http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#length-units>
* Read DPI information from the image files, defaulting to 72dpi. If
the image size is specified in pixels or automatically taken from the
file, this value is used to convert pixels to inches.
diff --git a/odtwriter/__init__.py b/odtwriter/__init__.py
index 0b0887c..1490833 100644
--- a/odtwriter/__init__.py
+++ b/odtwriter/__init__.py
@@ -1755,16 +1755,21 @@ class ODFTranslator(nodes.GenericNodeVisitor):
def depart_image(self, node):
pass
- def get_image_width_height(self, node, attr, scale):
+ def get_image_width_height(self, node, attr):
size = None
if attr in node.attributes:
+ size = node.attributes[attr]
+ unit = size[-2:]
+ if unit.isalpha():
+ size = size[:-2]
+ else:
+ unit = 'px'
try:
- size = int(node.attributes[attr])
- size *= 35.278 / 1000.0
- size *= scale
+ size = float(size)
except ValueError, e:
print 'Error: Invalid %s for image: "%s"' % (
- attr, node.attributes[attr], )
+ attr, node.attributes[attr])
+ size = [size, unit]
return size
def get_image_scale(self, node):
@@ -1781,30 +1786,41 @@ class ODFTranslator(nodes.GenericNodeVisitor):
scale = 1.0
return scale
- def get_image_scale_width_height(self, node, source):
+ def get_image_scaled_width_height(self, node, source):
scale = self.get_image_scale(node)
- width = self.get_image_width_height(node, 'width', scale)
- height = self.get_image_width_height(node, 'height', scale)
- if ('scale' in node.attributes and
- ('width' not in node.attributes or
- 'height' not in node.attributes)):
- if Image is not None:
- if source in self.image_dict:
- filename, destination = self.image_dict[source]
- imageobj = Image.open(filename, 'r')
- width, height = imageobj.size
- width = width * (35.278 / 1000.0)
- width *= scale
- height = height * (35.278 / 1000.0)
- height *= scale
- else:
- raise RuntimeError, 'image has scale and no height/width and PIL not installed'
- return scale, width, height
+ width = self.get_image_width_height(node, 'width')
+ height = self.get_image_width_height(node, 'height')
+
+ dpi = (72, 72)
+ if Image is not None and source in self.image_dict:
+ filename, destination = self.image_dict[source]
+ imageobj = Image.open(filename, 'r')
+ dpi = imageobj.info.get('dpi', dpi)
+ # dpi information can be (xdpi, ydpi) or xydpi
+ try: iter(dpi)
+ except: dpi = (dpi, dpi)
+ else:
+ imageobj = None
+
+ if width is None or height is None:
+ if imageobj is None:
+ raise RuntimeError, 'image size not fully specified and PIL not installed'
+ if width is None: width = [imageobj.size[0], 'px']
+ if height is None: height = [imageobj.size[1], 'px']
+
+ width[0] *= scale
+ height[0] *= scale
+ if width[1] == 'px': width = [width[0] / dpi[0], 'in']
+ if height[1] == 'px': height = [height[0] / dpi[1], 'in']
+
+ width[0] = str(width[0])
+ height[0] = str(height[0])
+ return ''.join(width), ''.join(height)
def generate_figure(self, node, source, destination, current_element):
#ipshell('At generate_figure')
caption = None
- scale, width, height = self.get_image_scale_width_height(node, source)
+ width, height = self.get_image_scaled_width_height(node, source)
for node1 in node.parent.children:
if node1.tagname == 'caption':
caption = node1.astext()
@@ -1883,8 +1899,8 @@ class ODFTranslator(nodes.GenericNodeVisitor):
'text:anchor-type': 'paragraph',
'draw:z-index': '1',
}
- if width is not None:
- attrib['svg:width'] = '%.2fcm' % (width, )
+ attrib['svg:width'] = width
+ attrib['svg:height'] = height
el3 = SubElement(current_element, 'draw:frame', attrib=attrib)
attrib = {}
el4 = SubElement(el3, 'draw:text-box', attrib=attrib)
@@ -1899,7 +1915,7 @@ class ODFTranslator(nodes.GenericNodeVisitor):
def generate_image(self, node, source, destination, current_element,
#ipshell('At generate_image')
frame_attrs=None):
- scale, width, height = self.get_image_scale_width_height(node, source)
+ width, height = self.get_image_scaled_width_height(node, source)
self.image_style_count += 1
style_name = 'rstframestyle%d' % self.image_style_count
# Add the style.
@@ -1965,10 +1981,8 @@ class ODFTranslator(nodes.GenericNodeVisitor):
attrib['text:anchor-type'] = 'char'
else:
attrib['text:anchor-type'] = 'paragraph'
- if width is not None:
- attrib['svg:width'] = '%.2fcm' % (width, )
- if height is not None:
- attrib['svg:height'] = '%.2fcm' % (height, )
+ attrib['svg:width'] = width
+ attrib['svg:height'] = height
el1 = SubElement(current_element, 'draw:frame', attrib=attrib)
el2 = SubElement(el1, 'draw:image', attrib={
'xlink:href': '%s' % (destination, ),
signature.asc
Description: Digital signature
--- End Message ---