ruby 有没有一种方法可以将emoji与Cairo的“玩具”文本API一起使用?

blmhpbnm  于 2023-05-17  发布在  Ruby
关注(0)|答案(1)|浏览(153)

是否有任何字体或技术可以用于Cairo(通过Ruby绑定)来绘制包含emoji的文本?我读到的所有东西都说“使用Pango进行真实的的文本处理”,但Cairo做了我需要的所有其他事情,所以我希望有一种方法可以避免将其作为依赖项添加。
下面是我正在尝试制作的动态Open Graph图像的简化版本:

require 'cairo'

# Create a new image surface based on recommended OpenGraph dimensions
width = 1_200
height = 630
surface = Cairo::ImageSurface.new(width, height)

# Create a Cairo Context for the surface
cr = Cairo::Context.new(surface)

# Apply a background colour to the whole thing (almost white)
cr.set_source_rgb(0.95, 0.95, 0.95)
cr.paint

# Add a heading
heading = "Hi! 👋"
cr.set_source_rgb(0.31, 0.21, 0.27)
cr.select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD)
cr.set_font_size(100.0)
extents = cr.text_extents(heading)
centred_text_left_edge = width / 2 - extents.width / 2
cr.move_to(centred_text_left_edge, 130)
cr.show_text(heading)

# Write the image surface to a PNG file
surface.write_to_png("emoji-test-#{Time.now.strftime('%Y-%m-%dT%H:%M:%S.%L%z')}.png")

不幸的是,emoji被渲染为矩形(在macOS上运行,在其他平台上可能会有所不同):

我可以使用自定义字体吗?或者是否有其他技术可以显示表情符号?
看起来“正确”的选择是使用Pango,但是这个建议仍然适用于Ruby吗?我无法在我的M1 Mac上安装Pango gem,即使我可以,经过大量搜索,我能找到的唯一参考使用Pango与开罗从Ruby是a very old sample script that's no longer included in the Pango distibution
如果做不到这一点,我想我将不得不将表情符号保存为图像,并将它们绘制到Surface/Context上。这对我来说是可行的,因为我只想使用3个特定的表情符号,但它不能扩展到包括任意的表情符号。

bpzcxfmw

bpzcxfmw1#

如果其他人有更好的解决方案,我会很乐意接受另一个答案,但我最终还是回到了一个表情符号的PNG上。读到最后,了解这种方法的缺点。
首先,我保存了一个我想使用的表情符号的96x96像素PNG。wave.png)。然后我把它们画在表面上。下面是一个POC:

require 'cairo'

# Create a new image surface based on recommended OpenGraph dimensions
width = 1_200
height = 630
surface = Cairo::ImageSurface.new(width, height)

# Create a Cairo Context for the surface
cr = Cairo::Context.new(surface)

# Apply a background colour to the whole thing (almost white)
cr.set_source_rgb(0.95, 0.95, 0.95)
cr.paint

# Set up the heading
string = "Hi!"
cr.set_source_rgb(0.31, 0.21, 0.27)
cr.select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD)
cr.set_font_size(100.0)
text_box = cr.text_extents(string)

# Set up the emoji image
image = Cairo::ImageSurface.from_png("wave.png")

# Position the text in the centre (taking into account the image width)
horizontal_gap = 20 # trial and error
top_of_text = 130 # trial and error
line_width = text_box.width + image.width + horizontal_gap
text_left_edge = (width - line_width) / 2 # centred on page
cr.move_to(text_left_edge, top_of_text)
cr.show_text(string)

# Position the image next to the text
top_of_image = top_of_text - 85 # trial and error
image_left_edge = text_left_edge + text_box.width + horizontal_gap
cr.set_source(image, image_left_edge, top_of_image)
cr.paint

# Write the image surface to a PNG file
surface.write_to_png("emoji-test.png")

这将生成我的OpenGraph图像,其中包含文本和表情符号:

这种方法的缺点是:

  • 您需要单独创建每个表情符号PNG
  • 独立地缩放图像对我来说很困难(我还在表面上画了一个标志),所以我必须使PNG的确切大小,我希望他们显示
  • 它采取了大量的试验和错误,以获得文本和图像的位置令人满意
  • 版权风险…我不是律师,但我很确定,未经许可,不能合法使用苹果(或微软或谷歌)的表情符号图像:
  • JoyPixels拥有可授权的表情符号,可用于商业环境和客户端工作
  • Twitter Emoji (Twemoji)在Creative Commons下可用
  • 你可以使用open source icon set而不是emoji

相关问题