繁体   English   中英

python-pptx:读取字体颜色

[英]python-pptx: read font color

我想从给定的文本框中读取字体颜色。 我可以提取字体名称和粗体,但不能提取颜色(或字体名称)。

这是我的代码:

text_frame = shape.text_frame
paragraph = text_frame.paragraphs[0]

for run in paragraph.runs:
    font = run.font
    try:
        font_size = font.size.pt
        print(font_size)
        font_bold = font.bold
        print(font_bold)
        font_name = font.name
        print(font_name)
        color = font.color.rgb
        print(color)
    except:
        pass

返回:

36.0
True
None

谢谢

在PowerPoint中(在这方面大致类似于CSS),可以在(至少被某些人称为) 样式层次结构中的各种级别上应用字体属性。 这些的最低层覆盖了上面的所有层,直接将样式应用于特定的运行。 使用.bold.color这样的属性,只能检索像这样的直接应用的属性。

可能存在诸如.effective_bold.effective_color类的属性, .effective_color可以在样式层次结构中导航,以计算在渲染时将应用的值,但是(尚未)。

因此font.color.rgbNone值指示run从其样式层次结构(例如,段落默认值,形状默认值,主题或演示文稿默认值等) 继承其颜色设置,但不幸的是,没有遍历样式层次结构以确定其颜色有效的颜色设置是。

我对填充也有同样的需求。 差别不是那么大。 它以类似的方式工作。 简化只是将“fill.fore_color”更改为“font.color”。

首先是检查给定的颜色是否特定(rgb 不是 None)。 如果是你已经得到了。 如果没有,请追求主题颜色路径以从那里获取 RGB 值。

srgb = font.color.rgb
if srgb == None:
    theme_color = font.color.theme_color
    brightness = font.color.brightness

现在你拥有的是一个 theme_color 和一个亮度。 主题颜色实际上是一个数值,用于定义 PowerPoint 中使用的“强调”颜色。 它可以通过 MSO_THEME_COLOR 解析,通过私有字典“_member_to_xml”,您可以使用它来定义提取它所需的 xml 路径:

from pptx.enum.dml import MSO_THEME_COLOR
accent = MSO_THEME_COLOR._member_to_xml[theme_color]
xpath = 'a:themeElements/a:clrScheme/a:{}/a:srgbClr/@val'.format(accent)

要进行提取,您需要有适当的可用主题信息,您可以通过从您所在的当前幻灯片使用的布局定义的 slide_master 中提取主题信息来获得这些信息。为此需要更多导入:

from pptx.opc.constants import RELATIONSHIP_TYPE as RT
from pptx.oxml import parse_xml
slide_master_part = slide.slide_layout.slide_master.part
theme_part = slide_master_part.part_related_by(RT.THEME)
theme = parse_xml(theme_part.blob)  # theme here is an <a:theme> element

现在终于,你有什么需要找出使用什么 PPT 强调色,回到我们之前定义的 xpath,并使用我们刚刚找到的主题翻译它:

hex_color = theme.xpath(xpath)[0]

如果没有亮度(亮度为零),您的 hex_color 不仅定义了使用的口音,还定义了真正的 RGB 颜色。 这是使用您想要的任何方法从十六进制颜色值中提取的。 例如图像颜色:

from PIL import ImageColor
import numpy as np
srgb = np.array(ImageColor.getcolor('#{}'.format(hex_color), 'RGB'))

但是,如果亮度(我们在开始时找到主题颜色时发现的)不为零,我们还有更多工作要做。 然后,真实颜色比由亮度值定义的强调色更暗或更亮。 获得真实 RGB 所需的额外步骤需要调整该亮度。 以与 PowerPoint 中类似的方式使颜色更亮需要转换为 HSL。 然后改变亮度,然后转换回RGB:

import colorsys
srgb = srgb / 255
h, luminance, s = colorsys.rgb_to_hls(*srgb)
lum_mod = 100000 * (1 - brightness)
lum_off = 100000 * brightness
luminance = luminance * (lum_mod / 100000) + (lum_off / 100000)
srgb = np.array(colorsys.hls_to_rgb(h, luminance, s))
srgb = (srgb * 255).round(0).astype(int)

我根据需要在上面显示了做一种颜色的步骤。 每张幻灯片只需要找到幻灯片母版主题一次,实际上在 PPT 演示文稿中每个母版只需要一次。 因此,真正的代码最好拆分为适合您需求的顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM