title: Why does PIL.Image.rotate() results in loss of quality despite `resample=Image.BICUBIC`
body: <p>Per <a href="https://stackoverflow.com/a/17822099/1639359">https://stackoverflow.com/a/17822099/1639359</a> using <code>resample=PIL.Image.BICUBIC</code> should retain quality through rotation.  This question is follow up from my comment on the above answer that it is not working for me.</p>
  
  <h3>What version of Python and PIL do we have:</h3>
  
  <pre class="lang-py prettyprint-override"><code>import sys
  print(sys.version)
  </code></pre>
  
  <pre><code>3.7.3 (default, Mar 27 2019, 22:11:17)
  [GCC 7.3.0]
  </code></pre>
  
  <pre class="lang-py prettyprint-override"><code>import PIL
  import PIL.Image
  print(PIL.__version__)
  print(PIL.Image.__version__)
  </code></pre>
  
  <pre><code>6.2.1
  6.2.1
  </code></pre>
  
  <h3>Open our test image, and save it. <br>Notice the loss of quality; saved file is much smaller than original:</h3>
  
  <pre class="lang-py prettyprint-override"><code>img = PIL.Image.open('test_image.jpg')
  holdexif = img.info['exif']
  img.save('testsave.jpg',"jpeg",exif=holdexif)
  
  %ls -l 'test_image.jpg'
  %ls -l 'testsave.jpg'
  </code></pre>
  
  <pre><code>-rwxrwxrwx 1 dino dino 1926859 Dec 24 21:28 test_image.jpg*
  -rwxrwxrwx 1 dino dino 452343 Dec 27 13:16 testsave.jpg*
  </code></pre>
  
  <h3>Per <a href="https://stackoverflow.com/questions/4354543/determining-jpg-quality-in-python-pil/4355281#4355281">Determining JPG quality in Python (PIL)</a> <br>setting <code>quality='keep'</code> prevents the loss of quality on save:</h3>
  
  <pre class="lang-py prettyprint-override"><code>img.save('testsave.jpg',"jpeg",exif=holdexif,quality='keep')
  
  %ls -l 'test_image.jpg'
  %ls -l 'testsave.jpg'
  </code></pre>
  
  <pre><code>-rwxrwxrwx 1 dino dino 1926859 Dec 24 21:28 test_image.jpg*
  -rwxrwxrwx 1 dino dino 1926911 Dec 27 13:16 testsave.jpg*
  </code></pre>
  
  <hr>
  
  <h3>If we rotate the image, two things happen:</h3>
  
  <ul>
  <li><code>img.format</code> disappears</li>
  <li>quality is reduced significantly (even though we use <code>resample=PIL.Image.BICUBIC</code>)</li>
  </ul>
  
  <pre class="lang-py prettyprint-override"><code>print(img.format)
  </code></pre>
  
  <pre><code>JPEG
  </code></pre>
  
  <pre class="lang-py prettyprint-override"><code>rotated_img = img.rotate(-90,resample=PIL.Image.BICUBIC,expand=True)
  </code></pre>
  
  <pre class="lang-py prettyprint-override"><code>print(img.format)
  print(rotated_img.format)
  </code></pre>
  
  <pre><code>JPEG
  None
  </code></pre>
  
  <hr>
  
  <h3>Saving the rotated file shows the loss of quality:</h3>
  
  <pre class="lang-py prettyprint-override"><code>rotated_img.format="JPEG"  # quality='keep' will raise exception if format != 'JPEG'
  rotated_img.save('testsave.jpg',"jpeg",exif=holdexif,quality='keep')
  %ls -l 'test_image.jpg'
  %ls -l 'testsave.jpg'
  </code></pre>
  
  <pre><code>-rwxrwxrwx 1 dino dino 1926859 Dec 24 21:28 test_image.jpg*
  -rwxrwxrwx 1 dino dino 450997 Dec 27 13:16 testsave.jpg*
  </code></pre>
  
  <h3>Questions:</h3>
  
  <h3>1. What, if anything, am I doing wrong?</h3>
  
  <h3>2. Why does <code>img.format</code> disappear on rotate?  What else is disappearing?</h3>
  
  <h3>3. And, just as an aside, is there another way to detect the loss of quality (I only know to save the file and see that it is much smaller).</h3>
  
  <hr>
  
  <p>After @MarkRansom 's comments, I would like to add some color to my question:  Although I have been coding for many years, I only last week began playing with images.  <em>Without a doubt my knowledge of image processing is minimal at best, with significant gaps and misunderstandings about how things work.</em>  </p>
  
  <p>That said, from a coding perspective, I would expect that a method on an object would do pretty much only what that method suggests, with no side effects.  For example, I would expect rotate() only to rotate the image, and not clear out meta data at the same time.  Even if, let's say for efficiency sake, the default behavior for the PIL package is to always drop the meta data, I would hope there would be an option (either global, or on a per-method basis) for something like <code>preserve_metadata=True</code></p>
  
  <p>Regarding "the only good way to judge quality" being "to look at the images themselves," I can certainly understand that being the case on an absolute basis.  However on a relative basis, most notably when comparing the "same" image before and after some processing, it seems to me there could be ways to physically measure, <em>or at least estimate,</em> the difference in quality before and after the processing.  (Of course, I don't yet know enough about images to know what the best method of doing that would be; thus part of the reason for my question).  It also seems to me (at least from my beginner perspective) that very often people would want to do whatever processing that want to do <em>with little or no loss of quality</em> at the same time.  Thanks for your patience and help filling in my knowledge gaps, and with the answers.</p>