---
metadata:
  - name: generator
    content: Diplodoc Platform v5.70.0
alternate:
  - https://divkit.tech/docs/en/quickstart/resources.md
  - https://divkit.tech/docs/ru/quickstart/resources.md
  - href: https://divkit.tech/docs/ru/quickstart/resources.md
    type: text/markdown
    title: Markdown version
  - href: https://divkit.tech/docs/ru/llms.txt?revision=r22102947
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://divkit.tech/docs/ru/llms.txt?revision=r22102947

# Ресурсы: шрифты, изображения и видео

Карточка только ссылается на шрифты, изображения и видео, а загружает и показывает их приложение. На этой странице описано, что для этого нужно подключить на каждой платформе. Свойства элементов описаны на страницах [Пользовательские шрифты](https://divkit.tech/docs/ru/concepts/custom-fonts.md), [Изображения](https://divkit.tech/docs/ru/concepts/image.md) и [Видео](https://divkit.tech/docs/ru/concepts/video.md).

## Шрифты {#fonts}

Имя шрифта из параметра `font_family` приложение сопоставляет с конкретным шрифтом. Для этого на каждой платформе реализуется провайдер шрифтов, который передается в DivKit при инициализации.

### Android {#fonts-android}

На платформе Android для использования пользовательских шрифтов необходимо реализовать интерфейс `DivTypefaceProvider`.

#### Пример реализации DivTypefaceProvider

```java
import android.content.Context;
import android.graphics.Typeface;
import androidx.annotation.Nullable;
import com.yandex.div.core.font.DivTypefaceProvider;

public class CustomTypefaceProvider implements DivTypefaceProvider {
    private final Context context;

    // Кэшируем шрифты для повышения производительности
    private Typeface regularTypeface;
    private Typeface mediumTypeface;
    private Typeface lightTypeface;
    private Typeface boldTypeface;

    public CustomTypefaceProvider(Context context) {
        this.context = context;
    }

    @Nullable
    @Override
    public Typeface getRegular() {
        if (regularTypeface == null) {
            regularTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Regular.ttf");
        }
        return regularTypeface;
    }

    @Nullable
    @Override
    public Typeface getMedium() {
        if (mediumTypeface == null) {
            mediumTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Medium.ttf");
        }
        return mediumTypeface;
    }

    @Nullable
    @Override
    public Typeface getLight() {
        if (lightTypeface == null) {
            lightTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Light.ttf");
        }
        return lightTypeface;
    }

    @Nullable
    @Override
    public Typeface getBold() {
        if (boldTypeface == null) {
            boldTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Bold.ttf");
        }
        return boldTypeface;
    }

    // Опционально: переопределите метод getTypefaceFor для более точного контроля
    // над соответствием весов шрифтов
    @Nullable
    @Override
    public Typeface getTypefaceFor(int weight) {
        if (weight >= 0 && weight < 350) {
            return getLight();
        } else if (weight >= 350 && weight < 450) {
            return getRegular();
        } else if (weight >= 450 && weight < 650) {
            return getMedium();
        } else {
            return getBold();
        }
    }
}
```

#### Интеграция в приложение

```java
import com.yandex.div.core.Div2Context;
import com.yandex.div.core.DivConfiguration;
import java.util.Collections;

// При инициализации DivKit: activity — ваша Activity, imageLoader — реализация DivImageLoader
DivConfiguration configuration = new DivConfiguration.Builder(imageLoader)
    // Шрифт по умолчанию: для текста без font_family и для неизвестных имен
    .typefaceProvider(new CustomTypefaceProvider(activity))
    // Шрифты, которые выбираются по имени из font_family
    .additionalTypefaceProviders(
        Collections.singletonMap("MyCustomFont", new CustomTypefaceProvider(activity))
    )
    // другие настройки
    .build();

Div2Context div2Context = new Div2Context(
    activity,
    configuration
);
```

### iOS {#fonts-ios}

На платформе iOS для использования пользовательских шрифтов необходимо реализовать протокол `DivFontProvider`.

#### Добавление шрифтов в проект

1. Добавьте файлы шрифтов (.ttf или .otf) в ваш проект
2. Убедитесь, что шрифты включены в ресурсы приложения (Bundle Resources)
3. Добавьте информацию о шрифтах в Info.plist в раздел `Fonts provided by application`:

```xml
<key>UIAppFonts</key>
<array>
    <string>MyFont-Regular.ttf</string>
    <string>MyFont-Medium.ttf</string>
    <string>MyFont-Light.ttf</string>
    <string>MyFont-Bold.ttf</string>
</array>
```

#### Пример реализации DivFontProvider

```swift
import UIKit
import DivKit
import VGSL

class CustomFontProvider: DivFontProvider {
    func font(family: String, weight: DivFontWeight, size: CGFloat) -> Font {
        // Если указано конкретное семейство шрифтов
        if family == "MyCustomFont" {
            let fontName: String
            switch weight {
            case .light:
                fontName = "MyFont-Light"
            case .regular:
                fontName = "MyFont-Regular"
            case .medium:
                fontName = "MyFont-Medium"
            case .bold:
                fontName = "MyFont-Bold"
            }

            if let font = UIFont(name: fontName, size: size) {
                return Font(uiFont: font)
            }
        }

        // Возвращаем системный шрифт, если пользовательский не найден
        let uiFont: UIFont
        switch weight {
        case .light:
            uiFont = UIFont.systemFont(ofSize: size, weight: .light)
        case .regular:
            uiFont = UIFont.systemFont(ofSize: size, weight: .regular)
        case .medium:
            uiFont = UIFont.systemFont(ofSize: size, weight: .medium)
        case .bold:
            uiFont = UIFont.systemFont(ofSize: size, weight: .bold)
        }

        return Font(uiFont: uiFont)
    }

    // Метод для получения шрифта по числовому весу уже реализован в расширении протокола
}
```

#### Интеграция в приложение

```swift
import DivKit

// При инициализации DivKit
let components = DivKitComponents(
    divCustomBlockFactory: nil,
    fontProvider: CustomFontProvider(),
    // другие параметры
)
```

### Web {#fonts-web}

На платформе Web для использования пользовательских шрифтов необходимо:

1. Подключить шрифты стандартными способами CSS (через `@font-face` или внешние сервисы)
2. Использовать параметр `typefaceProvider` при инициализации DivKit

#### Подключение шрифтов через CSS

Имя шрифта в CSS не обязательно должно совпадать с именем в JSON.

Не забудьте предоставить все варианты начертаний и насыщенности, которые понадобятся в вашей разметке (в данном примере добавлены 400, 500 и 700). Ещё один вариант - использовать вариативные шрифты.

```css
@font-face {
  font-family: 'MyCustomFont';
  src: url('fonts/MyFont-Regular.woff2') format('woff2'),
       url('fonts/MyFont-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
}

@font-face {
  font-family: 'MyCustomFont';
  src: url('fonts/MyFont-Medium.woff2') format('woff2'),
       url('fonts/MyFont-Medium.woff') format('woff');
  font-weight: 500;
  font-style: normal;
}

@font-face {
  font-family: 'MyCustomFont';
  src: url('fonts/MyFont-Bold.woff2') format('woff2'),
       url('fonts/MyFont-Bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
}
```

#### Использование typefaceProvider

```javascript
import { render } from '@divkitframework/divkit/client';

render({
    id: 'my-divkit-container',
    target: document.querySelector('#root'),
    json: {
        card: {
            log_id: 'custom_fonts_example',
            states: [{
                state_id: 0,
                div: {
                    type: 'text',
                    font_family: 'MyCustomFont',
                    font_weight_value: 500,
                    text: 'Текст с пользовательским шрифтом'
                }
            }]
        }
    },
    typefaceProvider: (fontFamily, opts) => {
        // Можно реализовать сопоставление имен шрифтов из JSON с CSS
        if (fontFamily === 'MyCustomFont') {
            return 'MyCustomFont, sans-serif';
        }

        // Для варианта по умолчанию можно вернуть пустую строку
        return '';
    }
});
```

### Рекомендации {#fonts-recommendations}

1. **Оптимизация производительности**: кэшируйте экземпляры шрифтов, чтобы не загружать их повторно.
2. **Поддержка разных начертаний**: реализуйте поддержку разной толщины шрифта, чтобы дизайн оставался гибким.
3. **Запасные варианты**: всегда предусматривайте запасной шрифт на случай, если пользовательский шрифт не загрузится.
4. **Предзагрузка шрифтов**: на платформе Web рекомендуется предзагружать шрифты, чтобы текст не мерцал при загрузке страницы.
5. **Тестирование**: проверяйте отображение шрифтов на разных устройствах и в разных условиях.

## Изображения {#images}

Изображения загружает приложение: на Android для этого подключается загрузчик изображений, на iOS локальные изображения берутся из bundle приложения.

### iOS {#images-ios}

На iOS, для ограничения доступа к ресурсам, все изображения ассетов divkit должны начинаться с префикса 'divkit.'. Например, если вы используете `"image_url": "divkit-asset://image.png"`, изображение должно иметь имя `divkit.image.png` в main bundle вашего приложения.

#### Поддержка нескольких bundle

iOS поддерживает указание конкретного bundle для загрузки изображений через параметр `bundle` в URL:

```json
{
  "type": "image",
  "image_url": "divkit-asset://image.png?bundle=com.example.app"
}
```

Эта функция полезна в модульных архитектурах или при использовании нескольких bundle в приложении. На Android параметр `bundle` игнорируется.

### Android {#images-android}

#### Поддержка загрузчиков изображений

DivKit для Android поддерживает популярные библиотеки загрузки изображений:

- **Coil** - современный загрузчик изображений на Kotlin
- **Glide** - традиционный загрузчик изображений

Оба загрузчика поддерживают все форматы изображений и эффекты, включая анимированные WebP и GIF.

#### Ограничение размера изображений {#bitmap-size-limit}

Для предотвращения крашей при загрузке больших изображений и GIF-файлов, DivKit автоматически ограничивает размер bitmap. Эта функция включена по умолчанию и помогает избежать проблем с памятью на устройствах.

**Как работает ограничение:**

- Максимальный размер bitmap определяется как максимальное разрешение экрана устройства
- Изображения, превышающие этот размер, автоматически масштабируются вниз
- Для SVG изображений применяется отдельный механизм ограничения
- Функция поддерживается загрузчиками `CoilDivImageLoader` и `GlideDivImageLoader`

**Настройка ограничения:**

Ограничение размера bitmap включено по умолчанию. Если вам нужно отключить эту функцию (например, для работы с очень большими изображениями), вы можете настроить это в реализации загрузчика изображений:

```kotlin
// Пример для CoilDivImageLoader
val imageLoader = CoilDivImageLoader(
    context = context,
    limitImageBitmapSizeEnabled = false // Отключить ограничение
)
```

{% note warning %}

Отключение ограничения размера bitmap может привести к крашам приложения при работе с очень большими изображениями. Используйте эту настройку с осторожностью.

{% endnote %}

## Видео {#video}

DivKit позволяет использовать стандартный плеер или собственный, например для воспроизведения роликов не поддерживаемого стандартным плеером формата или для реализации других необходимых функций.

### Стандартный плеер {#video-default}

По умолчанию DivKit использует стандартный плеер для всех платформ за исключением Android, где требуется подключить плеер явно.

#### Android

В качестве стандартного плеера для Android в DivKit используется ExoPlayer.

Так как инициализация ExoPlayer <q>тяжелая</q> операция, плеер подключается только при явном указании его необходимости в классе `DivConfiguration`. Если вы не планируете использовать видеоплеер в своем приложении, не вызывайте метод `.divPlayerFactory` в билдере (строителе) класса `DivConfiguration`.

Для работы со стандартным плеером передайте `ExoDivPlayerFactory` из пакета `com.yandex.div.video.m3` (модуль `div-video-m3`) в билдер `DivConfiguration` как аргумент метода `.divPlayerFactory()`.

В общем случае класс `DivConfiguration` для работы с поддержкой видео будет выглядеть следующим образом:

```translate=no
DivConfiguration.Builder(imageLoader)
     .divPlayerFactory(ExoDivPlayerFactory(context))
     .build()
```

Если в классе `DivConfiguration` не будет подключен плеер, то при рендеринге экрана с элементом `video` на его месте будет находиться пустой блок соответствующих размеров.

#### Остальные платформы

На iOS и в Web подключать стандартный плеер не нужно: при создании элемента `video` используется стандартный для платформы видеоплеер.

### Поддержка кастомного плеера {#video-custom}

Собственный видеоплеер подключается на каждой платформе по-своему:

- Android: фабрика, реализующая интерфейс `DivPlayerFactory`, передается в метод `.divPlayerFactory()` билдера `DivConfiguration`. Подробности приведены ниже.
- iOS: фабрика, реализующая протокол `PlayerFactory`, передается в `DivKitComponents` в параметре `playerFactory`.
- Web: провайдер плеера передается в функцию `render` в параметре `videoPlayerProvider`, см. [Параметры функции render](https://divkit.tech/docs/ru/quickstart/web.md#render-params).

#### Android {#video-custom-android}

Чтобы подключить в DivKit собственный видеоплеер, необходимо создать фабрику, которая будет по запросу DivKit-приложения предоставлять плеер и представление (view) для него. Для этого фабрика должна реализовывать интерфейс `DivPlayerFactory`.

Видеоплеер, создаваемый фабрикой, должен реализовывать интерфейс `DivPlayer` и таким образом являться прокси для вызовов из DivKit. При реализации кастомного плеера учитывайте, что свойства типа JSON-объект (например, `player_settings_payload`) могут содержать [выражения](https://divkit.tech/docs/ru/concepts/expressions.md), которые необходимо обрабатывать с помощью `expressionResolver`.

{% note info %}

Когда `player_settings_payload` изменяется во время работы приложения, DivKit автоматически вызывает метод `setSource` с обновленными настройками. Убедитесь, что ваш плеер корректно обрабатывает динамическое обновление настроек воспроизведения.

{% endnote %}

Например, для `ExoPlayer` реализация методов `DivPlayer` на языке Kotlin выглядит следующим образом.

{% cut "Посмотреть пример кода" %}


```kotlin translate=no
val player: ExoPlayer by lazy {
     ExoPlayer.Builder(context).build()
     }

     override fun play() {
     player.play()
     }

     override fun pause() {
     player.pause()
     }

     override fun seek(toMs: Long) {
     player.seekTo(toMs)
     }

     override fun setSource(sourceVariants: List<DivVideoSource>, config: DivPlayerPlaybackConfig) {
     val mediaSource = sourceVariants.toMediaSource()

     player.setMediaSource(mediaSource)
     player.prepare()
     }

     override fun release() {
     player.release()
     }
```


{% endcut %}

<!-- source: ru/_includes/index/troubleshooting.md -->
## Узнать больше {#troubleshooting}

Вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: [https://t.me/divkit_community_ru](https://t.me/divkit_community_ru).



[Репозиторий DivKit](https://github.com/divkit/divkit)




<!-- endsource: ru/_includes/index/troubleshooting.md -->
