0
def rotate_picture_90_left(img: Image) -> Image:

    img_width, img_height = img.size
    pixels = img.load()  # create the pixel map

    # for every pixel
    for i in range(img_width):
        for j in range(img_height):
            r, g, b = pixels[i, j]
            pixels[j,i] = (r,g,b)

    return img

I am using pillow to assist me trying to manipulate the image and make it rotate clockwise by reversing the width and length to get the clockwise rotation of the image, but the result is just unable to compute,I was wondering how do i do this correctly?

norok2
  • 25,683
  • 4
  • 73
  • 99
Beier Mu
  • 51
  • 4
  • Think about how the i,j coordinates work and you’ll see that your code can’t possibly work to modify `img` in-place if the image isn’t square. – DisappointedByUnaccountableMod Apr 03 '20 at 06:55
  • Could you please complete your code with what `Image` is and possibly an appropriate set of `import`s? – norok2 Apr 03 '20 at 07:01
  • all of my sample test image are squares, maybe I should change it to pixels[i , j ] = pixels [j, i]? will that swap of coordinate work? – Beier Mu Apr 03 '20 at 07:14

1 Answers1

0

There are 3 main issues with your code:

  • you do not return a modified image, you just return the original one, since the modifications are done on pixels
  • the modification you do will not rotate the image if you do them inplace, because by the time you modify the pixel at (0, 1) with the pixel at (1, 0) you would have lost what you had in (0, 1) originally.
  • the algorithm would not produce a 90° rotation but a transposition!

If the image is square, the second issue can be addressed with swapping. Otherwise, all issues can be addressed by creating an empty result and filling it in using some algorithm similar to what you used.

However, note that unless you are doing this to learn, NumPy offers both np.rot90() and np.transpose().


In code, you can separate the array handling from the image handling. The image handling can be delegated to the following function:

import numpy as np
import PIL as pil


def modify_image(img: pil.Image, func: callable, *args, **kws):
    arr = np.array(img)  # transform to NumPy array
    result = func(arr, *args, **kws)
    return pil.Image.fromarray(result)  # transform to PIL image

As for the transformation, you could use np.rot90(), np.transpose() or something else:

new_img = modify_image(img, np.rot90)

Assuming you want to see how a 90° rotation can be implemented manually (to be clear: I would never use this code in production), you could use:

def rot90(arr):
    if arr.ndim > 2:
        shape = arr.shape[1::-1]  + arr.shape[2:]
    elif arr.ndim == 2:
        shape = arr.shape[::-1]
    else:
        raise ValueError('Input dim must be 2 or more')
    result = np.empty(shape, dtype=arr.dtype)
    for i in range(shape[0]):
        for j in range(shape[1]):
            result[shape[0] - i - 1, j, ...] = arr[j, i, ...]
    return result

to be used as before:

new_img = modify_image(img, rot90)
norok2
  • 25,683
  • 4
  • 73
  • 99
  • yes, i am doing this to learn, and I am still a bit confused, so should i be creating a new blank image and fill that image with the reversal of length and width of image, and should i not be using for loops because from my understanding of the second point is that if i use for loop everytime i loop the previous coordinate would of been changed by the time it gets there – Beier Mu Apr 03 '20 at 07:41
  • You have to create a new blank image, and you can use `for` loops, but inside the `for` loops you shall use: `target_pixels[i, j] = source_pixels[j, i]` or similar. – norok2 Apr 03 '20 at 07:51
  • do i need to create a new: 'target_img_width, target_img_height = target_img.size target_pixels = target_img.load()'? and than match the: target_pixels [i,j] = pixels[ j, i]? – Beier Mu Apr 03 '20 at 07:59
  • Why do want to use `target_img.load()`? – norok2 Apr 03 '20 at 08:10
  • does that create a new blank image load? – Beier Mu Apr 03 '20 at 08:44
  • What makes you think that? See [here](https://stackoverflow.com/questions/384759/how-to-convert-a-pil-image-into-a-numpy-array) and the updated answer. – norok2 Apr 03 '20 at 08:53