Управление темами презентаций на Android
Введение
Тема презентации определяет согласованный набор цветов, шрифтов, стилей фона, заливок, линий и эффектов. Объекты, учитывающие тему, ссылаются на эти общие определения, а не хранят каждое визуальное свойство как фиксированное значение, поэтому изменение темы может одновременно обновить множество объектов.
В Aspose.Slides тема уровня презентации доступна через Presentation.getMasterTheme. Презентация также может содержать переопределения темы на более низких уровнях. Мастер может переопределять тему презентации через MasterThemeManager.getOverrideTheme, тогда как макет или отдельный слайд могут переопределять унаследованную тему через BaseOverrideThemeManager.getOverrideTheme. На практике эффективная тема для слайда разрешается по этой цепочке наследования: тема презентации, переопределение мастера, переопределение макета и переопределение слайда.

Ниже представлены наиболее распространённые рабочие процессы с темами: просмотр темы, изменение цветов и шрифтов, копирование или применение темы, обновление стилей фона и эффектов, а также чтение эффективных значений после разрешения наследования и переопределений.
Просмотр темы
Объект MasterTheme раскрывает цветовую схему темы, схему шрифтов и схему форматов через MasterTheme.getColorScheme, MasterTheme.getFontScheme, и MasterTheme.getFormatScheme. Проверка этих коллекций перед их изменением особенно полезна, когда презентация поступает из внешнего источника, поскольку количество и содержание записей стилей могут различаться.
Следующий пример считывает основные свойства темы и сообщает, сколько стилей фона, заливки, линии и эффектов хранится в теме:
import com.aspose.slides.*;
import android.graphics.Color;
Presentation presentation = new Presentation("input.pptx");
try {
IMasterTheme theme = presentation.getMasterTheme();
int accent1 = theme.getColorScheme().getAccent1().getColor();
System.out.println("Theme name: " + theme.getName());
System.out.println(String.format("Accent 1: Color [A=%d, R=%d, G=%d, B=%d]", Color.alpha(accent1), Color.red(accent1), Color.green(accent1), Color.blue(accent1)));
System.out.println("Major Latin font: " + theme.getFontScheme().getMajor().getLatinFont().getFontName());
System.out.println("Minor Latin font: " + theme.getFontScheme().getMinor().getLatinFont().getFontName());
System.out.println("Background fill styles: " + theme.getFormatScheme().getBackgroundFillStyles().size());
System.out.println("Fill styles: " + theme.getFormatScheme().getFillStyles().size());
System.out.println("Line styles: " + theme.getFormatScheme().getLineStyles().size());
System.out.println("Effect styles: " + theme.getFormatScheme().getEffectStyles().size());
} finally {
presentation.dispose();
}
Если файл использует несколько мастеров, не следует предполагать, что каждый слайд имеет одну и ту же эффективную тему. Просмотрите мастер, связанный со слайдом, и используйте рабочий процесс эффективной темы, показанный далее в этой статье, когда могут присутствовать переопределения макета или слайда.
Изменение цветов темы
Заливки, линии и текст, учитывающие тему, могут ссылаться на логический цвет из перечисления SchemeColor. Когда вы изменяете соответствующую запись в IColorScheme, все объекты, которые всё ещё ссылаются на этот цвет темы, разрешаются относительно нового значения. Объекты, использующие прямой RGB‑цвет, не изменяются при обновлении цвета темы.
Следующий сквозной пример создаёт форму, использующую Accent4, меняет цвет темы Accent4 на красный, сохраняет презентацию, открывает её заново и выводит эффективный цвет заливки:
import com.aspose.slides.*;
import android.graphics.Color;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, 100, 100);
shape.getFillFormat().setFillType(FillType.Solid);
shape.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
presentation.getMasterTheme().getColorScheme().getAccent4().setColor(Color.RED);
presentation.save("theme-color.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Presentation savedPresentation = new Presentation("theme-color.pptx");
try {
ISlide savedSlide = savedPresentation.getSlides().get_Item(0);
IShape savedShape = savedSlide.getShapes().get_Item(0);
IFillFormatEffectiveData effectiveFill = savedShape.getFillFormat().getEffective();
int effectiveColor = effectiveFill.getSolidFillColor();
System.out.println(String.format("Effective fill color: Color [A=%d, R=%d, G=%d, B=%d]", Color.alpha(effectiveColor), Color.red(effectiveColor), Color.green(effectiveColor), Color.blue(effectiveColor)));
} finally {
savedPresentation.dispose();
}
Поскольку прямоугольник остаётся связанным с Accent4, его видимый цвет становится красным после изменения темы. Если заменить цвет схемы прямым цветом на фигуре, последующие изменения Accent4 больше не будут влиять на эту заливку.
Использование цветов из дополнительной палитры
PowerPoint получает более светлые и более тёмные варианты из цвета темы, применяя преобразования цвета. Aspose.Slides раскрывает эти преобразования через перечисление ColorTransformOperation.

1 – Основные цвета темы.
2 – Более светлые и тёмные варианты, полученные из основных цветов темы.
Следующий пример создаёт шесть прямоугольников на основе Accent4, применяет к пяти из них преобразования яркости и сохраняет результат:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IShape shape1 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, 50, 50);
shape1.getFillFormat().setFillType(FillType.Solid);
shape1.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
IShape shape2 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 70, 50, 50);
shape2.getFillFormat().setFillType(FillType.Solid);
shape2.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
shape2.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.MultiplyLuminance, 0.2f);
shape2.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.AddLuminance, 0.8f);
IShape shape3 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 130, 50, 50);
shape3.getFillFormat().setFillType(FillType.Solid);
shape3.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
shape3.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.MultiplyLuminance, 0.4f);
shape3.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.AddLuminance, 0.6f);
IShape shape4 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 190, 50, 50);
shape4.getFillFormat().setFillType(FillType.Solid);
shape4.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
shape4.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.MultiplyLuminance, 0.6f);
shape4.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.AddLuminance, 0.4f);
IShape shape5 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 250, 50, 50);
shape5.getFillFormat().setFillType(FillType.Solid);
shape5.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
shape5.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.MultiplyLuminance, 0.75f);
IShape shape6 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 310, 50, 50);
shape6.getFillFormat().setFillType(FillType.Solid);
shape6.getFillFormat().getSolidFillColor().setSchemeColor(SchemeColor.Accent4);
shape6.getFillFormat().getSolidFillColor().getColorTransform().add(ColorTransformOperation.MultiplyLuminance, 0.5f);
presentation.save("theme-color-palette.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Эти варианты остаются основанными на цвете темы. Если позже изменится Accent4, преобразованные цвета будут пересчитаны из нового значения Accent4.
Сопоставление значений SchemeColor слотам IColorScheme
Перечисление SchemeColor использует Text1, Background1, Text2 и Background2, тогда как IColorScheme раскрывает те же слоты темы как Dark1, Light1, Dark2 и Light2. Сопоставление фиксировано:
Text1=Dark1Background1=Light1Text2=Dark2Background2=Light2
Это альтернативные названия одних и тех же слотов темы; они не являются значениями, которые динамически преобразуются из одной формы в другую.
Изменение шрифтов темы
Схема шрифтов темы содержит основной набор шрифтов для заголовков и вспомогательный набор шрифтов для основного текста. Методы IFontScheme.getMajor и IFontScheme.getMinor раскрывают эти наборы.
Идентификаторы шрифтов темы, совместимые с PowerPoint, могут использоваться при форматировании текста:
+mn-lt– Шрифт тела Latin (Minor Latin Font)+mj-lt– Шрифт заголовка Latin (Major Latin Font)+mn-ea– Шрифт тела East Asian (Minor East Asian Font)+mj-ea– Шрифт заголовка East Asian (Major East Asian Font)
Следующий пример создаёт один заголовок, использующий основной латинский шрифт темы, и одну строку основного текста, использующую вспомогательный латинский шрифт темы. Затем он меняет шрифты темы и сохраняет результат:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape heading = slide.getShapes().addAutoShape(ShapeType.Rectangle, 40, 40, 500, 60);
heading.getTextFrame().setText("Theme heading");
heading.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(0).getPortionFormat().setLatinFont(new FontData("+mj-lt"));
IAutoShape body = slide.getShapes().addAutoShape(ShapeType.Rectangle, 40, 120, 500, 60);
body.getTextFrame().setText("Theme body text");
body.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(0).getPortionFormat().setLatinFont(new FontData("+mn-lt"));
presentation.getMasterTheme().getFontScheme().getMajor().setLatinFont(new FontData("Aptos Display"));
presentation.getMasterTheme().getFontScheme().getMinor().setLatinFont(new FontData("Arial"));
presentation.save("theme-fonts.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Заголовок следует основному шрифту, а основной текст — вспомогательному. Текст, у которого указано явное имя шрифта вместо идентификатора темы, не будет автоматически переключаться при изменении схемы шрифтов темы.
Основные и вспомогательные коллекции шрифтов могут также содержать сопоставления шрифтов для отдельных систем письма, таких как кириллица, арабский, японский, грузинский и таана. Чтобы просмотреть, добавить, заменить или удалить эти сопоставления, см. Script-Specific Theme Fonts.
Tip
Для получения дополнительной информации о шрифтах презентации см. PowerPoint Fonts.Копирование или применение темы
Ниже представлены рабочие процессы, решающие различные задачи, связанные с темами.
Применение внешней темы к слайдам, зависящим от мастера
Используйте IMasterSlide.applyExternalThemeToDependingSlides когда у вас есть файл темы PowerPoint (.thmx) и вы хотите изменить стиль всех слайдов, зависящих от конкретного мастера. Выберите мастер из коллекции Presentation.getMasters, реализующей IMasterSlideCollection, и передайте путь к файлу темы в метод.
Метод выполняет следующие операции:
- Создаёт новый мастер‑слайд на основе выбранного мастера.
- Применяет внешнюю тему к новому мастеру.
- Присваивает новый мастер всем слайдам, которые ранее зависели от выбранного мастера.
- Возвращает созданный IMasterSlide.
Следующий пример применяет внешнюю тему к слайдам, зависящим от первого мастера, и сохраняет презентацию:
import com.aspose.slides.*;
Presentation presentation = new Presentation("presentation.pptx");
try {
IMasterSlide selectedMaster = presentation.getMasters().get_Item(0);
IMasterSlide themedMaster = selectedMaster.applyExternalThemeToDependingSlides("corporate-theme.thmx");
System.out.println("Created master: " + themedMaster.getName());
presentation.save("presentation-with-external-theme.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Недопустимая, повреждённая или неподдерживаемая тема может вызвать PptxReadException. Проверяйте пути, задаваемые пользователями, обрабатывайте ошибки доступа к файловой системе и сохраняйте презентацию только после успешного применения темы.
Только слайды, зависевшие от выбранного мастера, перепризначаются. Слайды, связанные с другими мастерами, сохраняют свои текущие мастера и темы. Цвета, шрифты, заливки, линии, фоны и эффекты, учитывающие тему, разрешаются относительно внешней темы. Прямо назначенные цвета, шрифты, заливки и другое явное форматирование могут остаться без изменений. Переопределения на уровне макета и слайда также могут иметь приоритет над значениями, унаследованными от нового мастера.
Тема может ссылаться на шрифты, недоступные в среде выполнения. Для согласованного рендеринга и экспорта установите требуемые шрифты, предоставьте их через custom font sources, или настройте font substitution.
Это прямой рабочий процесс уровня мастера: метод принимает путь к файлу .thmx и не требует ручного создания переопределений темы на уровне слайда или макета.
Применение разных внешних тем в презентации с несколькими мастерами
Когда нужный мастер неизвестен заранее, получите его из представительного слайда через ISlide.getLayoutSlide и ILayoutSlide.getMasterSlide. Сохраните оригинальные ссылки на мастера перед применением любых тем, поскольку каждый вызов создаёт новый мастер в презентации.
import com.aspose.slides.*;
Presentation presentation = new Presentation("multi-master-presentation.pptx");
try {
if (presentation.getSlides().size() < 5) {
System.out.println("The presentation does not contain the expected representative slides.");
} else {
IMasterSlide firstGroupMaster = presentation.getSlides().get_Item(0).getLayoutSlide().getMasterSlide();
IMasterSlide secondGroupMaster = presentation.getSlides().get_Item(4).getLayoutSlide().getMasterSlide();
if (firstGroupMaster.getSlideId() == secondGroupMaster.getSlideId()) {
System.out.println("The representative slides use the same master.");
} else {
IMasterSlide firstThemedMaster = firstGroupMaster.applyExternalThemeToDependingSlides("blue-theme.thmx");
IMasterSlide secondThemedMaster = secondGroupMaster.applyExternalThemeToDependingSlides("green-theme.thmx");
System.out.println("First themed master: " + firstThemedMaster.getName());
System.out.println("Second themed master: " + secondThemedMaster.getName());
presentation.save("multi-master-with-external-themes.pptx", SaveFormat.Pptx);
}
}
} finally {
presentation.dispose();
}
Первый вызов затронет только слайды, зависевшие от firstGroupMaster, а второй — только слайды, зависевшие от secondGroupMaster. Слайды, принадлежащие другим мастерам, не будут изменены.
Сохранение исходной темы при перемещении слайдов
Если нужно переместить слайд в другую презентацию и сохранить его первоначальный дизайн, клонируйте исходный мастер в целевую презентацию с помощью IMasterSlideCollection.addClone, затем клонируйте слайд с помощью ISlideCollection.addClone и клонированного мастера. Это переносит мастер, его макеты и связанную тему вместе.
import com.aspose.slides.*;
Presentation source = new Presentation("source-theme.pptx");
try {
Presentation target = new Presentation("target.pptx");
try {
ISlide sourceSlide = source.getSlides().get_Item(0);
IMasterSlide sourceMaster = sourceSlide.getLayoutSlide().getMasterSlide();
IMasterSlide clonedMaster = target.getMasters().addClone(sourceMaster);
target.getSlides().addClone(sourceSlide, clonedMaster, true);
target.save("theme-preserved.pptx", SaveFormat.Pptx);
} finally {
target.dispose();
}
} finally {
source.dispose();
}
Это предпочтительный процесс, когда исходный слайд должен выглядеть одинаково в целевом документе. Простое клонирование содержимого на несвязанный мастер получателя может изменить цвета, шрифты, фоны и эффекты, управляемые темой.
Применение значений темы к существующему слайду
Если целевой слайд должен оставаться на текущем мастере и макете, инициализируйте переопределение уровня слайда из исходной темы. Методы OverrideTheme.initColorSchemeFrom, OverrideTheme.initFontSchemeFrom, и OverrideTheme.initFormatSchemeFrom копируют три основных компонента темы в переопределение.
import com.aspose.slides.*;
Presentation source = new Presentation("source-theme.pptx");
try {
Presentation target = new Presentation("target.pptx");
try {
ISlide targetSlide = target.getSlides().get_Item(0);
IOverrideTheme overrideTheme = targetSlide.getThemeManager().getOverrideTheme();
overrideTheme.initColorSchemeFrom(source.getMasterTheme().getColorScheme());
overrideTheme.initFontSchemeFrom(source.getMasterTheme().getFontScheme());
overrideTheme.initFormatSchemeFrom(source.getMasterTheme().getFormatScheme());
target.save("theme-applied-to-slide.pptx", SaveFormat.Pptx);
} finally {
target.dispose();
}
} finally {
source.dispose();
}
Это изменяет тему, используемую этим слайдом, не меняя тему, унаследованную другими слайдами. Чтобы удалить локальное переопределение и вернуться к унаследованным значениям, вызовите OverrideTheme.clear.
Применение переопределения темы к макету
Переопределение уровня макета применяется к слайдам, использующим этот макет, если только конкретный слайд не имеет собственного переопределения. Те же методы инициализации можно использовать через LayoutSlideThemeManager:
import com.aspose.slides.*;
Presentation source = new Presentation("source-theme.pptx");
try {
Presentation target = new Presentation("target.pptx");
try {
ISlide targetSlide = target.getSlides().get_Item(0);
ILayoutSlide targetLayout = targetSlide.getLayoutSlide();
IOverrideTheme overrideTheme = targetLayout.getThemeManager().getOverrideTheme();
overrideTheme.initColorSchemeFrom(source.getMasterTheme().getColorScheme());
overrideTheme.initFontSchemeFrom(source.getMasterTheme().getFontScheme());
overrideTheme.initFormatSchemeFrom(source.getMasterTheme().getFormatScheme());
target.save("theme-applied-to-layout.pptx", SaveFormat.Pptx);
} finally {
target.dispose();
}
} finally {
source.dispose();
}
Используйте мастер‑или презентационную тему, когда многие макеты и слайды должны делить один базовый дизайн, переопределение макета — когда одной семье макетов нужен иной стиль, и переопределение слайда — только для истинных исключений. Чрезмерные переопределения уровня слайда усложняют предсказуемость последующих глобальных изменений темы.
Обновление стилей фона темы
Фоны темы хранятся в IFormatScheme.getBackgroundFillStyles. PowerPoint может показывать в интерфейсе больше вариантов фона, чем фактически определено в этой коллекции, потому что UI может комбинировать заливки темы с цветовыми схемами темы и другими ссылками стилей.

Перед использованием стиля фона проверьте хранимую коллекцию и текущий Background.getStyleIndex. Индекс стиля 0 означает отсутствие тематической заливки; положительные значения – ссылки на стили фона темы. Это отличается от индексации самой Java‑коллекции, где get_Item(0) обозначает первый элемент. Не предполагаете, что каждая презентация содержит одинаковое количество стилей фоновой заливки.
Следующий пример сообщает количество доступных фоновых заливок, назначает ссылку на тематический фон первому мастеру и сохраняет презентацию:
import com.aspose.slides.*;
Presentation presentation = new Presentation("input.pptx");
try {
IFillFormatCollection backgroundStyles = presentation.getMasterTheme().getFormatScheme().getBackgroundFillStyles();
System.out.println("Background fill styles: " + backgroundStyles.size());
if (backgroundStyles.size() == 0) {
throw new IllegalStateException("The presentation theme does not contain background fill styles.");
}
IMasterSlide masterSlide = presentation.getMasters().get_Item(0);
masterSlide.getBackground().setType(BackgroundType.Themed);
masterSlide.getBackground().setStyleIndex(1);
presentation.save("theme-background.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Видимый результат зависит от темы, на которую ссылается мастер, и от любых переопределений фона на уровне макета или слайда. Если слайд использует собственный фон, изменение только фона мастера может не изменить этот слайд. Используйте Background.getEffective когда необходимо узнать окончательный фон после применения наследования.
Warning
Не рассматривайте индекс стиля как ноль‑базовый индекс коллекции. Также избегайте жёсткого кодирования номера стиля из одного файла и предположения, что он будет выглядеть так же в другом файле; определения стилей темы зависят от конкретной презентации.Tip
Для прямого форматирования фона и наследования фона см. Presentation Background.Обновление эффектов темы
Схема форматов темы содержит отдельные коллекции стилей заливки, линии и эффекта, раскрываемые через IFormatScheme.getFillStyles, IFormatScheme.getLineStyles, и IFormatScheme.getEffectStyles. Обычные темы Office часто содержат три основных стиля, визуально соответствующие «тонкому», «умеренному» и «интенсивному» форматированию, но код должен проверять каждую коллекцию, а не предполагать фиксированное число записей.

При работе с этими коллекциями в Java индексация начала с нуля: get_Item(0) – первая сохранённая стиль, get_Item(2) – третий. Индексы ссылок стиля фигуры – отдельная концепция, раскрываемая через IShapeStyle. Изменение стиля темы влияет на фигуры, ссылающиеся на этот стиль; фигуры с прямым форматированием могут оставаться без изменений.
Следующий пример проверяет наличие необходимых записей стилей, меняет первый стиль линии, меняет третий стиль заливки, включат внешнюю тень в третьем стиле эффекта и сохраняет результат:
import com.aspose.slides.*;
import android.graphics.Color;
Presentation presentation = new Presentation("Subtle_Moderate_Intense.pptx");
try {
IFormatScheme formatScheme = presentation.getMasterTheme().getFormatScheme();
if (formatScheme.getLineStyles().size() < 1 || formatScheme.getFillStyles().size() < 3 || formatScheme.getEffectStyles().size() < 3) {
throw new IllegalStateException("The theme does not contain the style entries required by this example.");
}
formatScheme.getLineStyles().get_Item(0).getFillFormat().setFillType(FillType.Solid);
formatScheme.getLineStyles().get_Item(0).getFillFormat().getSolidFillColor().setColor(Color.RED);
formatScheme.getFillStyles().get_Item(2).setFillType(FillType.Solid);
formatScheme.getFillStyles().get_Item(2).getSolidFillColor().setColor(Color.rgb(34, 139, 34));
IEffectFormat effectFormat = formatScheme.getEffectStyles().get_Item(2).getEffectFormat();
effectFormat.enableOuterShadowEffect();
effectFormat.getOuterShadowEffect().setDistance(10f);
presentation.save("theme-effects.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Для фигур, ссылающихся на эти слоты, первый стиль линии темы станет красным, третий стиль заливки темы станет сплошным тёмно‑зелёным, а третий стиль эффекта получит внешнюю тень с расстоянием 10 пунктов. Точный визуальный результат всё равно зависит от того, какие слоты стиля каждая фигура использует и переопределяется ли прямое форматирование.

Определение, использует ли фактическая сплошная заливка цвет темы
Заливка может быть записана непосредственно в объекте или унаследована от абзаца, макета, мастера, стиля темы или другого уровня форматирования. Вызовите IFillFormat.getEffective, чтобы разрешить эту иерархию в неизменяемый IFillFormatEffectiveData. Сначала проверьте IFillFormatEffectiveData.getFillType. Только когда тип – FillType.Solid, следует читать свойства сплошной заливки.
Для сплошной заливки IFillFormatEffectiveData.getSolidFillColor возвращает окончательное отрисованное значение RGB после применения наследования, поиска в теме и преобразований цвета. IFillFormatEffectiveData.getSolidFillSchemeColor возвращает соответствующий логический слот SchemeColor, например Text1 или Accent6. Значение SchemeColor.NotDefined означает, что эффективная сплошная заливка не основана на цветовом слоте схемы. В рабочем процессе, где заливки либо являются цветовыми слотами темы, либо прямыми RGB‑цветами, это значение указывает на прямую RGB‑заливку.
Не используйте только локальное значение IColorFormat.getSchemeColor для классификации заливки. Например, часть текста может не иметь локально определённого слота схемы, поэтому её локальное значение – NotDefined, в то время как её эффективная заливка наследует цвет темы и разрешается как Text1 или Accent6. С другой стороны, getSolidFillSchemeColor сообщает, какой логический слот темы сгенерировал эффективный цвет, но не говорит, откуда этот слот пришёл – от объекта, абзаца, макета, мастера или другого уровня иерархии.
import com.aspose.slides.*;
import android.graphics.Color;
import java.util.function.BiConsumer;
BiConsumer<String, IFillFormat> auditFill = (objectName, localFill) -> {
IFillFormatEffectiveData effectiveFill = localFill.getEffective();
if (effectiveFill.getFillType() != FillType.Solid) {
System.out.println(objectName + ": fill type = " + effectiveFill.getFillType() + "; not a solid fill.");
return;
}
int rgb = effectiveFill.getSolidFillColor();
int effectiveSchemeColor = effectiveFill.getSolidFillSchemeColor();
int localSchemeColor = localFill.getSolidFillColor().getSchemeColor();
System.out.printf("%s: RGB = #%02X%02X%02X%n", objectName, Color.red(rgb), Color.green(rgb), Color.blue(rgb));
System.out.println(objectName + ": local scheme = " + localSchemeColor + ", effective scheme = " + effectiveSchemeColor);
if (effectiveSchemeColor == SchemeColor.NotDefined) {
System.out.println(objectName + ": direct RGB or another non-scheme fill; audit as theme-independent.");
} else {
System.out.println(objectName + ": theme-dependent through " + effectiveSchemeColor + ".");
}
};
Presentation presentation = new Presentation("input.pptx");
try {
int slideCount = presentation.getSlides().size();
for (int slideIndex = 0; slideIndex < slideCount; slideIndex++) {
ISlide slide = presentation.getSlides().get_Item(slideIndex);
int shapeCount = slide.getShapes().size();
for (int shapeIndex = 0; shapeIndex < shapeCount; shapeIndex++) {
IShape shape = slide.getShapes().get_Item(shapeIndex);
String shapeName = "Slide " + (slideIndex + 1) + ", shape " + (shapeIndex + 1);
auditFill.accept(shapeName, shape.getFillFormat());
if (shape instanceof IAutoShape) {
IAutoShape autoShape = (IAutoShape) shape;
int paragraphCount = autoShape.getTextFrame().getParagraphs().getCount();
for (int paragraphIndex = 0; paragraphIndex < paragraphCount; paragraphIndex++) {
IParagraph paragraph = autoShape.getTextFrame().getParagraphs().get_Item(paragraphIndex);
int portionCount = paragraph.getPortions().getCount();
for (int portionIndex = 0; portionIndex < portionCount; portionIndex++) {
IPortion portion = paragraph.getPortions().get_Item(portionIndex);
String portionName = shapeName + ", paragraph " + (paragraphIndex + 1) + ", portion " + (portionIndex + 1);
auditFill.accept(portionName, portion.getPortionFormat().getFillFormat());
}
}
}
}
}
} finally {
presentation.dispose();
}
Ветка NotDefined предоставляет список сплошных заливок, которые не будут реагировать на изменения слотов цветовой схемы темы. Проверьте эти объекты, когда презентация должна соответствовать новой фирменной палитре. Отчётный RGB‑значение всё ещё показывает текущий внешний вид, а значение схемы поясняет, связано ли он с темой.
Объекты эффективного формата – это снимки. После изменения темы презентации, переопределения темы или любого унаследованного форматирования вызовите getEffective снова и получите новый объект IFillFormatEffectiveData перед сравнением или выводом цветов.
Чтение эффективных значений темы
Необработанные объекты темы показывают, что определено на конкретном уровне. Эффективные значения показывают, что слайд или фигура действительно используют после наследования и локальных переопределений. Для слайда вызовите BaseOverrideThemeManager.createThemeEffective. Для фона используйте Background.getEffective, а для заливки – FillFormat.getEffective.
Следующий пример считывает эффективную тему, фон и первую заливку фигуры со слайда:
import com.aspose.slides.*;
import android.graphics.Color;
Presentation presentation = new Presentation("input.pptx");
try {
ISlide slide = presentation.getSlides().get_Item(0);
IThemeEffectiveData effectiveTheme = slide.getThemeManager().createThemeEffective();
IBackgroundEffectiveData effectiveBackground = slide.getBackground().getEffective();
System.out.println("Effective major Latin font: " + effectiveTheme.getFontScheme().getMajor().getLatinFont().getFontName());
System.out.println("Effective minor Latin font: " + effectiveTheme.getFontScheme().getMinor().getLatinFont().getFontName());
System.out.println("Effective background fill type: " + effectiveBackground.getFillFormat().getFillType());
if (slide.getShapes().size() > 0) {
IFillFormatEffectiveData effectiveFill = slide.getShapes().get_Item(0).getFillFormat().getEffective();
System.out.println("First shape effective fill type: " + effectiveFill.getFillType());
if (effectiveFill.getFillType() == FillType.Solid) {
int effectiveColor = effectiveFill.getSolidFillColor();
System.out.println(String.format("First shape effective fill color: Color [A=%d, R=%d, G=%d, B=%d]", Color.alpha(effectiveColor), Color.red(effectiveColor), Color.green(effectiveColor), Color.blue(effectiveColor)));
}
}
} finally {
presentation.dispose();
}
Используйте эффективные данные для диагностики рендеринга, проверки и сравнения. Если проверять только Presentation.getMasterTheme, можно пропустить переопределения мастера, макета, слайда или фигуры, которые меняют окончательный вид.
FAQ
Влияет ли применение внешней темы на каждый слайд в презентации?
Нет. IMasterSlide.applyExternalThemeToDependingSlides переназначает только слайды, зависимые от выбранного мастера. Слайды, использующие другие мастеры, сохраняют свои текущие темы.
Можно ли применить тему к отдельному слайду без изменения мастера?
Да. Используйте SlideThemeManager слайда и инициализируйте его переопределение темы. Изменение остаётся локальным для этого слайда; остальные слайды продолжают наследовать свои текущие темы.
Какой способ самый надёжный для переноса темы из одной презентации в другую?
При перемещении слайда и сохранении его оригинального оформления клонируйте исходный мастер в целевую презентацию и клонируйте слайд с этим мастером, используя IMasterSlideCollection.addClone и ISlideCollection.addClone. Это сохраняет мастер, макеты и тему вместе.
Как увидеть эффективные значения после наследования и переопределений?
Используйте BaseOverrideThemeManager.createThemeEffective для слайда или темы макета и соответствующие методы получения эффективных данных для форматных объектов, таких как Background.getEffective и FillFormat.getEffective. Эти API возвращают разрешённые значения после применения наследования и переопределений.