How to use PIL (Python Image Library), rotate the image and let the black background be transparent

I want to rotate the gray โ€œtestโ€ image and paste it into the blue background image. Now I can just remove the black color after rotating my gray โ€œtestโ€ image, but now it is white. How can I use Python to change the โ€œwhiteโ€ color section to blue?

Here is my code, can someone help me? I would appreciate.

dst_im = Image.new("RGBA", (196,283), "blue" ) im = src_im.convert('RGBA') rot = im.rotate( angle, expand=1 ).resize(size) f = Image.new( 'RGBA', rot.size, (255,)*4 ) im2 = Image.composite( rot, f, rot ) im2.convert(src_im.mode) im2_width, im2_height = im2.size cut_box = (0, 0, im2_width, im2_height ) paste_box = ( left, top, im2_width+left, im2_height+top ) region = im2.crop( cut_box ) dst_im.paste( region, paste_box ) dst_im.save("test.gif") 

enter image description here

+7
source share
2 answers

I got the impression that your code can be simplified as follows:

 from PIL import Image src_im = Image.open("winter3.jpg") angle = 45 size = 100, 100 dst_im = Image.new("RGBA", (196,283), "blue" ) im = src_im.convert('RGBA') rot = im.rotate( angle, expand=1 ).resize(size) dst_im.paste( rot, (50, 50), rot ) dst_im.save("test.png") 

This gives the following result:

enter image description here

+17
source

Another answer using PIL is clearly more concise. I had a similar problem and I had an image in ndarray. Yipes, mine came out much harder than user1202136. I only post it because it demonstrates another solution using numpy and arrays, but user1202136 solution is much better.

  import matplotlib.pyplot as plt import numpy as np import scipy.ndimage def rgba(rgb_img, alpha): ''' ' takes an rgb ndarray rxcx 3 of dtype=uint8 ' and adds an alpha 0-255 to each pixel ''' rows = len(rgb_img) # get image dimensions columns = len(rgb_img[0]) rgb_flat = rgb_img.reshape([rows * columns, 3]) # list of rgb pixels a = np.zeros([rows*columns, 1], dtype=np.uint8) # alpha for each pixel a.fill(alpha) rgba = np.column_stack([rgb_flat, a]) # place 4th column return rgba.reshape([rows, columns, 4]) # reform into rxcx 4 def pad_with_transparent_pixels(rgba_img): ''' ' takes an rgba image rxc ' and places within a buffer of [ 0 0 0 0] to become square, ' with sides = diagonal of img ''' rows = len(rgba_img) # get image dimensions columns = len(rgba_img[0]) diag = (rows**2 + columns**2)**0.5 diag = int(diag) + 1 top_pad_height = (diag-rows)/2 + 1 left_pad_width = (diag-columns)/2 + 1 top_pad = np.zeros([top_pad_height, diag, 4], dtype=np.uint8) left_pad = np.zeros([rows, left_pad_width, 4], dtype=np.uint8) right_pad = np.zeros([rows, # assures total width of top_pad for row_stack: diag - left_pad_width - columns, 4 ], dtype=np.uint8) center = np.column_stack([left_pad, rgba_img, right_pad]) return np.row_stack([top_pad, center, top_pad]) def clean_rotate(rgba_img,angle): rows = len(rgba_img) columns = len(rgba_img[0]) diag = (rows**2 + columns**2)**.5 diag = int(diag) pad_img = pad_with_transparent_pixels(rgba_img) rot_img = scipy.ndimage.rotate(pad_img, angle) rot_img_rows = len(rot_img) rot_img_columns = len(rot_img[0]) crop_side = max(1,(rot_img_columns - diag) / 2) #max to avoid splicing [:0] crop_top = max(1,(rot_img_rows - diag) / 2) print diag, crop_side, crop_top return rot_img[crop_top:-crop_top,crop_side:-crop_side] img = plt.imread('C:\\Users\\bbrown\\Desktop\\Maurine.jpg') # read in a jpg figure, axes = plt.subplots(1, 2) # create 1x2 grid of axes axes[0].imshow(img) # place image on first axes rgba_image = rgba(img, 255) # create an opaque rgba image rot_img = clean_rotate(rgba_image,50) #make a pattern of 10 images for i in range(10): rot_img = clean_rotate(rgba_image,5*i) axes[1].imshow(rot_img) plt.show() 
+1
source

All Articles