Repository: python-pillow/Pillow

Problem statement:
"integer expected, got float" exception trying to save a BMP image with original DPI
Consider the following code:

```python
from PIL import Image
from StringIO import StringIO

image = Image.open('image.jpg')
out = StringIO()
print image.info

image.save(out, 'JPEG', quality=95, dpi=image.info['dpi'])
```

This results in an exception:

```
$ /tmp/venv/bin/python t.py 
{'compression': 0, 'dpi': (0.0, 0.0)}
Traceback (most recent call last):
  File "t.py", line 8, in <module>
    image.save(out, 'JPEG', quality=95, dpi=image.info['dpi'])
  File "/tmp/venv/local/lib/python2.7/site-packages/PIL/Image.py", line 1693, in save
    save_handler(self, fp, filename)
  File "/tmp/venv/local/lib/python2.7/site-packages/PIL/JpegImagePlugin.py", line 697, in _save
    ImageFile._save(im, fp, [("jpeg", (0, 0)+im.size, 0, rawmode)], bufsize)
  File "/tmp/venv/local/lib/python2.7/site-packages/PIL/ImageFile.py", line 476, in _save
    e = Image._getencoder(im.mode, e, a, im.encoderconfig)
  File "/tmp/venv/local/lib/python2.7/site-packages/PIL/Image.py", line 434, in _getencoder
    return encoder(mode, *args + extra)
TypeError: integer argument expected, got float
```

when image.jpg is a BMP format image, which I have attached.

The root cause is that the image.info.dpi is a tuple with floats, which the save() call is throwing an exception on.

Question is, why is the DPI setting coming back as a float? Should it be cast to an integer there? Also, why is it 0.0 ?
![image](https://cloud.githubusercontent.com/assets/3730318/8359514/c2e79728-1b1b-11e5-87a7-8995a8c6490e.jpg)



Hints:

Patch:
diff --git a/PIL/BmpImagePlugin.py b/PIL/BmpImagePlugin.py
--- a/PIL/BmpImagePlugin.py
+++ b/PIL/BmpImagePlugin.py
@@ -103,7 +103,9 @@ def _bitmap(self, header=0, offset=0):
                 file_info['pixels_per_meter'] = (i32(header_data[20:24]), i32(header_data[24:28]))
                 file_info['colors'] = i32(header_data[28:32])
                 file_info['palette_padding'] = 4
-                self.info["dpi"] = tuple(map(lambda x: math.ceil(x / 39.3701), file_info['pixels_per_meter']))
+                self.info["dpi"] = tuple(
+                    map(lambda x: int(math.ceil(x / 39.3701)),
+                        file_info['pixels_per_meter']))
                 if file_info['compression'] == self.BITFIELDS:
                     if len(header_data) >= 52:
                         for idx, mask in enumerate(['r_mask', 'g_mask', 'b_mask', 'a_mask']):


Test patch:
diff --git a/Tests/images/hopper.bmp b/Tests/images/hopper.bmp
new file mode 100644
Binary files /dev/null and b/Tests/images/hopper.bmp differ
diff --git a/Tests/test_file_bmp.py b/Tests/test_file_bmp.py
--- a/Tests/test_file_bmp.py
+++ b/Tests/test_file_bmp.py
@@ -49,6 +49,22 @@ def test_dpi(self):
 
         self.assertEqual(reloaded.info["dpi"], dpi)
 
+    def test_save_bmp_with_dpi(self):
+        # Test for #1301
+        # Arrange
+        outfile = self.tempfile("temp.jpg")
+        im = Image.open("Tests/images/hopper.bmp")
+
+        # Act
+        im.save(outfile, 'JPEG', dpi=im.info['dpi'])
+
+        # Assert
+        reloaded = Image.open(outfile)
+        reloaded.load()
+        self.assertEqual(im.info['dpi'], reloaded.info['dpi'])
+        self.assertEqual(im.size, reloaded.size)
+        self.assertEqual(reloaded.format, "JPEG")
+
 
 if __name__ == '__main__':
     unittest.main()