python-pillow / Pillow

Python Imaging Library (Fork)
https://python-pillow.org
Other
12.27k stars 2.23k forks source link

Can't show emojis from tweepy (twitter api) #6508

Closed khaledmsm closed 2 years ago

khaledmsm commented 2 years ago

What did you do?

I'm currently programming a bot that copy tweets that mention on and paste it on image I'm using python , pillow , tweepy

when the bot get the tweet text from api and trying to paste it on image the emojis cant show on image , i tried a notocolor and other fonts but the issue doesn't fixed

also im using libraqm because the main language of the project is arabic

What did you expect to happen?

ican see the emojis thats get from tweepy api thats included on tweets

What actually happened?

icant see the emojis thats get from tweepy api thats included on tweets and i searched for fonts but if i found font thats support emoji its not support the alphabet and if i found one that support alphabet it dosent support emojis

and this a results https://i.stack.imgur.com/QBMqE.jpg https://i.stack.imgur.com/JDPP2.jpg and this original tweet https://i.stack.imgur.com/wagTI.png

What are your OS, Python and Pillow versions?

import tweepy
from PIL import Image,ImageDraw , ImageFont
import requests
from io import BytesIO

CONSUMER_KEY = ""
CONSUMER_SECRET = ''
ACCESS_KEY = ''
ACCESS_SECRET = ''

auth = tweepy.OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET)

auth.set_access_token(ACCESS_KEY,ACCESS_SECRET)

api = tweepy.API(auth)

mentions = api.mentions_timeline()
print(mentions)

for mention in mentions:
    tweet_id = api.get_status(mention.in_reply_to_status_id).id
    status_obj = api.get_status(tweet_id ,tweet_mode="extended")
    print(status_obj.full_text)
    save_id_inreplyto = status_obj.in_reply_to_status_id
    save_id_text = status_obj.full_text

    orginal_url = api.get_status(tweet_id).user.profile_image_url
    replaced_url = orginal_url.replace("normal", "400x400")

    response = requests.get(replaced_url)
    avatar = Image.open(BytesIO(response.content))
    resized_av = avatar.resize((200,200))

    #print(api.get_status(save_id_inreplyto).profile_image_url)

    tweet = save_id_text
    img = Image.new('RGB', (1080, 1080), color=(178, 255, 233))

    ####
    # crop image
    width, height = resized_av.size
    x = (width - height) // 2
    img_cropped = resized_av.crop((x, 0, x + height, height))

    # create grayscale image with white circle (255) on black background (0)
    mask = Image.new('L', img_cropped.size)
    mask_draw = ImageDraw.Draw(mask)
    width, height = img_cropped.size
    mask_draw.ellipse((0, 0, width, height), fill=255)
    mask.save('mask_circle.jpg', quality=95)

    #mask.show()

    # add mask as alpha channel
    img_cropped.putalpha(mask)

    # save as png which keeps alpha channel
    #img_cropped.save('dog_circle.png')

    ####
    twittericon = Image.open('twittericon.png')
    img.paste(img_cropped,(300, 100),mask)
    resized_ti = twittericon.resize((100, 100))
    img.paste(resized_ti, (300, 200))
    d = ImageDraw.Draw(img)
    fnt = ImageFont.truetype('C:\\Users\\kmm\\Desktop\\fonts\\NotoSansArabic-VariableFont_wdth,wght.ttf', 30)

    d.text((280, 150), "@ 😃"+api.get_status(mention.in_reply_to_status_id).user.screen_name, font=fnt, fill=(220, 180, 10))
    d.text((540,540),tweet, font=fnt, fill=(220, 180, 10),anchor="ms")

    img.save('pil1_text'+str(mention.id)+'.jpg' ,format='JPEG', subsampling=0, quality=100)
    #print(api.update_status_with_media(status="@"+mention.user.screen_name,filename='pil_text'+mention.id_str+'.jpg',in_reply_to_status_id=mention.id_str,tweet_mode = 'extended'))
    print("tweeted with media")
hugovk commented 2 years ago

Simpler reproducer without Tweepy:

from PIL import Image, ImageDraw, ImageFont

text = "thread emoji: 🧵"
im = Image.new("RGB", (500, 100))
d = ImageDraw.Draw(im)
# https://github.com/google/fonts/blob/main/ofl/notosansarabicui/NotoSansArabicUI%5Bwdth%2Cwght%5D.ttf
fnt = ImageFont.truetype("NotoSansArabicUI[wdth,wght].ttf", 30)

d.text((20, 20), text, font=fnt)

im.save("output.jpg", format="JPEG", subsampling=0, quality=100)

With macOS/Python 3.10/FriBiDi not installed:

image

radarhere commented 2 years ago

i searched for fonts but if i found font thats support emoji its not support the alphabet and if i found one that support alphabet it dosent support emojis

So you can actually get Pillow to work with emojis, and you can get Pillow to work with arabic characters, just not both in the same font? I think this is just a duplicate of #4808.

Perhaps the most helpful comment in that issue at the moment is https://github.com/python-pillow/Pillow/issues/4808#issuecomment-1141719845, where a user describes how to merge two fonts into one using Python.

khaledmsm commented 2 years ago

i searched for fonts but if i found font thats support emoji its not support the alphabet and if i found one that support alphabet it dosent support emojis

So you can actually get Pillow to work with emojis, and you can get Pillow to work with arabic characters, just not both in the same font? I think this is just a duplicate of #4808.

Perhaps the most helpful comment in that issue at the moment is #4808 (comment), where a user describes how to merge two fonts into one using Python.

thanks alot