构建自己的个人资料贴纸/框架工具
#初学者 #编程 #python #图片

在大多数互联网上,我们的身份被压缩成一个小的个人资料照片和显示名称,这些是微型画布,我们可以在上面表达自己的个性或发表声明。也许参与社会运动,代表组织或品牌;或只是为了宣布我们“开放工作”或感觉到万圣节精神ð»

很好奇如何构建其中一个图像生成器供人们制作个人资料照片?这是Python中的一个简单版本,该版本使用自定义框架和贴纸的部分透明的图像覆盖层。

这取了用户的个人资料照片(来自Twitter),在顶部添加覆盖图像,然后您可以将结果映像作为数据URL获取以在HTML中渲染或将其写入(临时)文件(也可以也可以转回Twitter以更新用户的个人资料照片)。

这篇文章的灵感:我们最近将此功能构建为一个有趣的小项目。感兴趣和我们一起工作吗? We're hiring!


首先,让我们从Twitter获取用户的个人资料照片。我已经手持有关Twitter客户端的作品(对不起),但是您可以使用Tweepy

from PIL import Image 
import requests 

PFP_IMAGE_SIZE = (400, 400)  # max/standard size on Twitter

def get_original_pfp_image(twitter_screen_name):
    # TODO(you) Implement this
    client = create_twitter_client_for_app()  

    twitter_user_json = client.get_twitter_user_data_by_screen_name(
        twitter_screen_name)
    pfp_url = twitter_user_json.get("profile_image_url_https", "")
    pfp_original_url = pfp_url.replace("_normal", "")   

    pfp_image = Image.open(
        requests.get(pfp_original_url, stream=True).raw)

    # We aren't guaranteed that the user's profile image is 
    # the right size, which will cause issues when trying to 
    # apply the overlay. 
    if pfp_image.size != PFP_IMAGE_SIZE:  
        pfp_image = pfp_image.resize(
            PFP_IMAGE_SIZE, Image.ANTIALIAS)

    return pfp_image

如果要简化开发和测试,则可以通过本地图像路径进行。

from PIL import Image 

PFP_IMAGE_SIZE = (400, 400)  

# Note that this has a slightly different function signature 
# than the alternative sample code. 
def get_original_pfp_image(pfp_image_path):
    pfp_image = Image.open(pfp_image_path)

    if pfp_image.size != PFP_IMAGE_SIZE:  
        pfp_image = pfp_image.resize(
            PFP_IMAGE_SIZE, Image.ANTIALIAS)

    return pfp_image


接下来,让我们加载覆盖图像,用原始配置文件照片复合,然后创建新的覆盖图像。

此处的覆盖图应为具有透明度的400x400 PNG。

Spooky Blobby frame and sticker

import PIL
from PIL import Image

def get_overlay_image(overlay_image_path):
    overlay_image = Image.open(overlay_image_path)
    return overlay_image

def generate_overlaid_image(twitter_screen_name):
    pfp_image = get_original_pfp_image(twitter_screen_name)
    if not pfp_image:
        return None

    # We need RGBA mode for transparency in the image
    pfp_image_rgba = pfp_image.convert(mode="RGBA")  

    # TODO(you) Replace with your overlay image path
    overlay_image = get_overlay_image("overlay.png")
    overlaid_pfp_image = PIL.Image.alpha_composite(
        pfp_image_rgba, overlay_image)
    return overlaid_pfp_image

现在让我们将图像作为数据URL,以便我们可以在html中渲染!

import base64
from io import BytesIO

DATA_IMAGE_PREFIX = "data:image/png;base64,"

def generate_overlaid_pfp_image_data_url(twitter_screen_name):
    overlaid_pfp_image = generate_overlaid_pfp_image(
        twitter_screen_name)
    if not overlaid_pfp_image:
        return None

    image_io = BytesIO()
    overlaid_pfp_image.save(image_io, "png", quality=95)
    data_url = DATA_IMAGE_PREFIX + base64.b64encode(
        image_io.getvalue()).decode("ascii")
    return data_url

在Jinja中预览 - 例如,Twitter使用的所有不同尺寸 - 我们只使用此映像数据URL作为img元素的src

{% for dims in [(24, 24), (48, 48), (73, 73), (400, 400)] %}
    <img src="{{ image_data_url }}" 
         width="{{ dims[0] }}" 
         height="{{ dims[1] }}" />
{% endfor %}

最后,如果您想在Twitter上设置用户的配置文件照片,则可以创建一个临时文件并通过API发送。

import base64
from io import BytesIO

DATA_IMAGE_PREFIX = "data:image/png;base64,"

def update_user_twitter_pfp(twitter_user_id, image_data_url):
    image_data = image_data_url[len(DATA_IMAGE_PREFIX):]

    buffer = BytesIO(base64.b64decode(image_data))
    image_tempfile = tempfile.NamedTemporaryFile(suffix=".png")

    try:
        image_tempfile.write(buffer.read())
        image_tempfile.flush()

        # This client is created with the user's OAuth 
        # credentials (vs. app credentials) so we can 
        # set their profile photo. 
        client = create_twitter_client_for_user(
            twitter_user_id)
        client.update_twitter_user_profile_image(
            image_tempfile.name)
    finally:
        buffer.close()
        image_tempfile.close()

这是外观!

Profile photo sticker/frame tool