我想旋转和通过旋转的图像,就像在图像所附。我的结果不是居中的,文本不在图像中。图像大小是794x1096,你能帮我吗?
这是我的密码:
x = input('Insert Name Here ')
y = input('Insert full name')
img = Image.open("Path/watermark_example.png")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('calibri.ttf', 55)
draw.text((30, 300),x,(128, 128, 128, 255), font=font)
draw.text((500, 500),x,(128, 128, 128, 255),font=font)
img1 = img.rotate(15, expand = True, fillcolor = 'white')
img.putalpha(128)
img.paste(img1)
img.show()
img.save(f'Path/watermark_example{y}.png')
发布于 2020-07-16 08:29:42
它更容易创建正常的水平水印,因为它需要较少的工作。
您必须创建新的空图像RGBA
,其大小与原始图像相同,但具有透明的背景(..., ..., ..., 0)
。接下来,您可以以不同的透明度和不同的位置使用这个新的图像文本。最后,您必须使用Image.alpha_composite(original_image, text_image)
将文本放在图像上,并具有预期的透明度。
要将文本放在中间,必须使用以下方法计算其上/左角
x = original_image_width/2 - text_width/2
y = original_image_height/2 - text_height/2
from PIL import Image, ImageDraw, ImageFont
#name = input('Name: ')
name = 'example'
# --- original image ---
#original_image_size = (794, 1096)
#original_image = Image.new('RGBA', image_size, 'white')
original_image = Image.open('lenna.png').convert("RGBA")
original_image_size = original_image.size
# --- watermarks image ---
# image with the same size and transparent color (..., ..., ..., 0)
watermarks_image = Image.new('RGBA', original_image_size, (255,255,255,0))
watermarks_draw = ImageDraw.Draw(watermarks_image)
font = ImageFont.truetype('arial.ttf', 55)
# calculate text size in pixels (width, height)
text_size = font.getsize(name)
# calculate top/left corner for centered text
#x = (image_size[0] - text_size[0])//2
#y = (image_size[1] - text_size[1])//2
x = original_image_size[0]//2 - text_size[0]//2
y = original_image_size[1]//2 - text_size[1]//2
# draw text
watermarks_draw.text((x, y), name, (255, 255, 255, 192), font=font)
# --- put watermarks image on original image ---
combined_image = Image.alpha_composite(original_image, watermarks_image)
# --- result ---
combined_image.show()
combined_image.save(f'lenna_1_{name}.png')
现在,您可以将文本放在不同的位置,并且可以使用for
-loop进行此操作。
from PIL import Image, ImageDraw, ImageFont
#name = input('Name: ')
name = 'example'
# --- original image ---
#original_image_size = (794, 1096)
#original_image = Image.new('RGBA', image_size, 'white')
original_image = Image.open('lenna.png').convert("RGBA")
original_image_size = original_image.size
# --- watermarks image ---
# image with the same size and transparent color (..., ..., ..., 0)
watermarks_image = Image.new('RGBA', original_image_size, (255,255,255,0))
watermarks_draw = ImageDraw.Draw(watermarks_image)
font = ImageFont.truetype('arial.ttf', 15)
# calculate text size in pixels (width, height)
text_size = font.getsize(name)
# calculate top/left corner for centered text
parts = 8
offset_x = original_image_size[0]//parts
offset_y = original_image_size[1]//parts
start_x = original_image_size[0]//parts - text_size[0]//2
start_y = original_image_size[1]//parts - text_size[1]//2
for a in range(0, parts, 2):
for b in range(0, parts, 2):
x = start_x + a*offset_x
y = start_y + b*offset_y
watermarks_draw.text((x, y), name, (255, 255, 255, 240), font=font)
# --- put watermarks image on original image ---
combined_image = Image.alpha_composite(original_image, watermarks_image)
# --- result ---
combined_image.show()
combined_image.save(f'lenna_2_{name}.png')
需要更多的工作来放置旋转图像,因为首先要生成文本图像,然后使用paste()
旋转图像,然后使用alpha_composite()
将透明图像放到原始图像上。
from PIL import Image, ImageDraw, ImageFont
#name = input('Name: ')
name = 'example'
# --- original image ---
#original_image_size = (794, 1096)
#original_image = Image.new('RGBA', image_size, 'white')
original_image = Image.open('lenna.png').convert("RGBA")
original_image_size = original_image.size
# --- text image ---
font = ImageFont.truetype('arial.ttf', 55)
# calculate text size in pixels (width, height)
text_size = font.getsize(name)
# create image for text
text_image = Image.new('RGBA', text_size, (255,255,255,0))
text_draw = ImageDraw.Draw(text_image)
# draw text on image
text_draw.text((0, 0), name, (255, 255, 255, 129), font=font)
# rotate text image and fill with transparent color
rotated_text_image = text_image.rotate(45, expand=True, fillcolor=(0,0,0,0))
rotated_text_image_size = rotated_text_image.size
#rotated_text_image.show()
# --- watermarks image ---
# image with the same size and transparent color (..., ..., ..., 0)
watermarks_image = Image.new('RGBA', original_image_size, (255,255,255,0))
# calculate top/left corner for centered text
x = original_image_size[0]//2 - rotated_text_image_size[0]//2
y = original_image_size[1]//2 - rotated_text_image_size[1]//2
# put text on watermarks image
watermarks_image.paste(rotated_text_image, (x, y))
# --- put watermarks image on original image ---
combined_image = Image.alpha_composite(original_image, watermarks_image)
# --- result ---
combined_image.show()
combined_image.save(f'lenna_3_{name}.png')
这个版本是通用的,因为您也可以使用这个方法来放置水平文本--您只需跳过rotate()
。如果需要,还可以添加一些重新标度或其他修改。
但是,当文本图像太大,一个带有文本的矩形与其他矩形与文本重叠时,可能会出现问题,因为paste()
删除了以前的内容。然后它需要更复杂的alpha_composite()
版本,而不是paste()
版本。
BTW:维基百科的原始兰娜图片:
编辑:
以前的版本有重叠文本图像的问题。
新版本将每一个文本分开组合,解决了这个问题。
from PIL import Image, ImageDraw, ImageFont
#name = input('Name: ')
name = 'example'
# --- original image ---
#original_image_size = (794, 1096)
#original_image = Image.new('RGBA', image_size, 'white')
original_image = Image.open('lenna.png').convert("RGBA")
original_image_size = original_image.size
# --- text image ---
font = ImageFont.truetype('arial.ttf', 55)
# calculate text size in pixels (width, height)
text_size = font.getsize(name)
# create image for text
text_image = Image.new('RGBA', text_size, (255,255,255,0))
text_draw = ImageDraw.Draw(text_image)
# draw text on image
text_draw.text((0, 0), name, (255, 255, 255, 129), font=font)
# rotate text image and fill with transparent color
rotated_text_image = text_image.rotate(45, expand=True, fillcolor=(0,0,0,0))
rotated_text_image_size = rotated_text_image.size
#rotated_text_image.show()
# --- watermarks image ---
combined_image = original_image
# calculate top/left corner for centered text
parts = 8
offset_x = original_image_size[0]//parts
offset_y = original_image_size[1]//parts
start_x = original_image_size[0]//parts - rotated_text_image_size[0]//2
start_y = original_image_size[1]//parts - rotated_text_image_size[1]//2
for a in range(0, parts, 2):
for b in range(0, parts, 2):
x = start_x + a*offset_x
y = start_y + b*offset_y
# image with the same size and transparent color (..., ..., ..., 0)
watermarks_image = Image.new('RGBA', original_image_size, (255,255,255,0))
# put text in expected place on watermarks image
watermarks_image.paste(rotated_text_image, (x, y))
# put watermarks image on original image
combined_image = Image.alpha_composite(combined_image, watermarks_image)
#combined_image.show()
# --- result ---
combined_image.show()
combined_image.save(f'lenna_4b_{name}.png')
编辑:
我更改代码使用行中的行数来计算位置。
对于两个字,我把宽度分成三个部分。在这个版本中,我使用行来显示这些部分。文本的中心部分代替了交叉线。
这个计算有一个缺点-它创造了更大的边缘周围的图像。
它会通过不同的计算来减少它。它必须得到图像的宽度和减法2*text_width,然后将它分成3部分。第一个元素的位置需要1*part_size + 0*text_with
,对于第二个2*part_size + 1*text_with
,对于n个n*part_size + (n-1)*text_with
from PIL import Image, ImageDraw, ImageFont
#name = input('Name: ')
name = 'example'
# --- original image ---
#original_image_size = (794, 1096)
#original_image = Image.new('RGBA', image_size, 'white')
original_image = Image.open('lenna.png').convert("RGBA")
original_image_size = original_image.size
# --- watermarks image ---
# image with the same size and transparent color (..., ..., ..., 0)
watermarks_image = Image.new('RGBA', original_image_size, (255,255,255,0))
watermarks_draw = ImageDraw.Draw(watermarks_image)
font = ImageFont.truetype('arial.ttf', 35)
# calculate text size in pixels (width, height)
text_size = font.getsize(name)
# calculate
words_in_row = 2
words_in_col = 2
parts_x = words_in_row + 1 # 3
size_x = original_image_size[0]//parts_x
offset_x = text_size[0]//2 # half of text's width
parts_y = words_in_col + 1 # 3
size_y = original_image_size[1]//parts_y
offset_y = text_size[1]//2 # half of text's height
for a in range(1, parts_x, 1):
line_x = a*size_x
line_heigth = original_image.size[1]
watermarks_draw.line((line_x, 0, line_x, line_heigth))
for b in range(1, parts_y, 1):
line_y = b*size_y
line_width = original_image.size[0]
watermarks_draw.line((0, line_y, line_width, line_y))
x = a*size_x - offset_x
y = b*size_y - offset_y
watermarks_draw.text((x, y), name, (255, 255, 255, 240), font=font)
# --- put watermarks image on original image ---
combined_image = Image.alpha_composite(original_image, watermarks_image)
# --- result ---
combined_image.show()
combined_image.save(f'lenna_2_{name}.png')
具有更好计算边距的代码
from PIL import Image, ImageDraw, ImageFont
#name = input('Name: ')
name = 'example'
# --- original image ---
#original_image_size = (794, 1096)
#original_image = Image.new('RGBA', image_size, 'white')
original_image = Image.open('lenna.png').convert("RGBA")
original_image_size = original_image.size
# --- watermarks image ---
# image with the same size and transparent color (..., ..., ..., 0)
watermarks_image = Image.new('RGBA', original_image_size, (255,255,255,0))
watermarks_draw = ImageDraw.Draw(watermarks_image)
font = ImageFont.truetype('arial.ttf', 35)
# calculate text size in pixels (width, height)
text_size = font.getsize(name)
text_width, text_height = text_size
# calculate
words_in_row = 2
words_in_col = 4
parts_x = words_in_row + 1 # 3
margin_x = (original_image_size[0] - words_in_row*text_width)//parts_x
offset_x = text_width//2 # half of text's width
parts_y = words_in_col + 1 # 3
margin_y = (original_image_size[1] - words_in_col*text_height)//parts_y
offset_y = text_size[1]//2 # half of text's height
for a in range(0, parts_x, 1):
line_height = original_image.size[1]
line_x = (a+1) * margin_x + a * text_width
watermarks_draw.line((line_x, 0, line_x, line_height))
line_x += text_width
watermarks_draw.line((line_x, 0, line_x, line_height))
for b in range(0, parts_y, 1):
line_width = original_image.size[0]
line_y = (b+1) * margin_y + b * text_height
watermarks_draw.line((0, line_y, line_width, line_y))
line_y += text_height
watermarks_draw.line((0, line_y, line_width, line_y))
x = (a+1) * margin_x + a * text_width
y = (b+1) * margin_y + b * text_height
watermarks_draw.text((x, y), name, (255, 255, 255, 240), font=font)
# --- put watermarks image on original image ---
combined_image = Image.alpha_composite(original_image, watermarks_image)
# --- result ---
combined_image.show()
combined_image.save(f'lenna_7_{name}.png')
https://stackoverflow.com/questions/62910445
复制相似问题