Repository: python-pillow/Pillow

Issue:
Save as PDF with resolution/dpi float dpi result
### What did you do?
Saved the PDF with `resolution=300`
`img.save(outpath + "/" + "test.pdf", resolution=300)`

### What did you expect to happen?
PDF with 300 resolution...
If you save with ".jpg" as extension the resolution will be 300 integer

### What actually happened?
PDF with 300.235 resolution ...
Photoshop CC 2019
![grafik](https://user-images.githubusercontent.com/5721838/50969565-37ec3400-14df-11e9-8344-0a961decb689.png)

Also shown in Adobe Acrobat DC
![grafik](https://user-images.githubusercontent.com/5721838/51019607-c7dfbb80-157b-11e9-9642-1e1e20f4f48f.png)
How to get resolution in Adobe Acrobat DC
Tools > Print Production/ Output Preview > Preview: Object Inspector >Click on image



### What are your OS, Python and Pillow versions?

* OS: 
Windows 10
* Python: 
3.5.2
* Pillow: 
5.4.1



Discussion:
What application is that a screenshot from?
> 
> 
> What application is that a screenshot from?

Photoshop CC
I think more common would be Adobe Acrobat CC also shown in edited post.

Resolving patch:
diff --git a/src/PIL/PdfImagePlugin.py b/src/PIL/PdfImagePlugin.py
--- a/src/PIL/PdfImagePlugin.py
+++ b/src/PIL/PdfImagePlugin.py
@@ -202,8 +202,8 @@ def _save(im, fp, filename, save_all=False):
                 MediaBox=[
                     0,
                     0,
-                    int(width * 72.0 / resolution),
-                    int(height * 72.0 / resolution),
+                    width * 72.0 / resolution,
+                    height * 72.0 / resolution,
                 ],
                 Contents=contents_refs[pageNumber],
             )
@@ -211,9 +211,9 @@ def _save(im, fp, filename, save_all=False):
             #
             # page contents
 
-            page_contents = b"q %d 0 0 %d 0 0 cm /image Do Q\n" % (
-                int(width * 72.0 / resolution),
-                int(height * 72.0 / resolution),
+            page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % (
+                width * 72.0 / resolution,
+                height * 72.0 / resolution,
             )
 
             existing_pdf.write_obj(contents_refs[pageNumber], stream=page_contents)
diff --git a/src/PIL/PdfParser.py b/src/PIL/PdfParser.py
--- a/src/PIL/PdfParser.py
+++ b/src/PIL/PdfParser.py
@@ -330,6 +330,8 @@ def pdf_repr(x):
         return bytes(x)
     elif isinstance(x, int):
         return str(x).encode("us-ascii")
+    elif isinstance(x, float):
+        return str(x).encode("us-ascii")
     elif isinstance(x, time.struct_time):
         return b"(D:" + time.strftime("%Y%m%d%H%M%SZ", x).encode("us-ascii") + b")"
     elif isinstance(x, dict):


Test patch:
diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py
--- a/Tests/test_file_pdf.py
+++ b/Tests/test_file_pdf.py
@@ -30,7 +30,7 @@ def helper_save_as_pdf(tmp_path, mode, **kwargs):
     with open(outfile, "rb") as fp:
         contents = fp.read()
     size = tuple(
-        int(d) for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
+        float(d) for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
     )
     assert im.size == size
 
@@ -86,6 +86,27 @@ def test_unsupported_mode(tmp_path):
         im.save(outfile)
 
 
+def test_resolution(tmp_path):
+    im = hopper()
+
+    outfile = str(tmp_path / "temp.pdf")
+    im.save(outfile, resolution=150)
+
+    with open(outfile, "rb") as fp:
+        contents = fp.read()
+
+    size = tuple(
+        float(d)
+        for d in contents.split(b"stream\nq ")[1].split(b" 0 0 cm")[0].split(b" 0 0 ")
+    )
+    assert size == (61.44, 61.44)
+
+    size = tuple(
+        float(d) for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
+    )
+    assert size == (61.44, 61.44)
+
+
 @mark_if_feature_version(
     pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
 )