4

I am rotating an image with the following python code:

from PIL import Image

img = Image.open('banana.jpg')
rotated = img.rotate(10)
rotated.save('banana-rotated.jpg')

This makes the following transformation:

enter image description here to enter image description here

As you can see, the background is black. This question asks how to fill the background with a specific color. However, I would like to fill the background with the color of the image. Because I need to rotate many images, I do not want to set the background to a fixed color.

Is there some way to extend the image at the edges, with a color extrapolated from the image? Ideally, this would also work if the image does not have a uniform background.

Peter
  • 401
  • 1
  • 5
  • 17
  • the correct way is to use a separate image for the background and then put the `transparent` version of another image(which you wish to rotate) on top of the background image. The rotation of the foreground image will not affect the background and also it will not have any visible borders. – anekix Mar 27 '18 at 10:22
  • @anekix: That sounds promising. But what should I use as the background image? Because I rotate many images, I need a separate background image for each one. I guess I could use the image I want to rotate as the background image? But maybe there is a better way? – Peter Mar 27 '18 at 10:35
  • are these images generated dynamically?like user submitted or you just have a bunch of images you want to process? – anekix Mar 27 '18 at 10:37
  • @anekix: I want to process a bunch of images. They are not generated dynamically, but there are a lot of them. – Peter Mar 27 '18 at 10:39
  • 1
    you can refer [this](https://stackoverflow.com/questions/16702966/rotate-image-and-crop-out-black-borders) for some help.The result that you get above is expected as there is no notion of background and foreground image in your example. – anekix Mar 27 '18 at 10:44
  • 1
    If you know the type of images, you can get the RGB of the region of the 4 corners, and use that to fill the new corners. This could work on your images. In general there is no flat background color, so the usual method is rotate + crop. – Giacomo Catenazzi Mar 27 '18 at 12:18

2 Answers2

5

This could help: https://pillow.readthedocs.io/en/5.2.x/releasenotes/5.2.0.html#image-rotate

Pillow 5.2.0 onwards, A new named parameter called fillcolor, has been added to Image.rotate. This color specifies the background color to use in the area outside the rotated image.

image.rotate(45, fillcolor='white')

Could help if image was rotated by x degrees other than 90,180,270,

Baptiste Mille-Mathias
  • 2,144
  • 4
  • 31
  • 37
storesource
  • 141
  • 1
  • 7
  • 2
    I think that author has explicitly written that he doesn't want to use the hardcoded color (like `white`), but the color extrapolated from the image. – pptaszni Sep 04 '18 at 14:34
  • @Ptaq666 You could always use the background colour as the parameter. This is one of many solution one could use. This is the simplest way to tackle this problem. – storesource Sep 05 '18 at 05:16
1

It's not great but you can always fill borders with the average color of the original border

 image.rotate(5, fillcolor=tuple(np.mean(np.array(image)[0,:], axis=0).astype(int)))
Alexis Benichoux
  • 790
  • 4
  • 13