gifts2017

Программное создание картинки

Опубликовал Павел Драгунов ([AdepT]) в раздел Программирование - Практика программирования

В статье приводится алгоритм программного создания однотонной картинки на основе переданного цвета.

Как-то мне понадобилось сделать однотонные цветные закладки, чтобы пользователь мог сам выбирать цвет. Стандартный функционал 1С страниц панели, поддерживает только присвоение объекта типа Картинка для закладок. Возможно, есть решение в объектах ActiveX, но моя душа к такому способу не лежала. Но как говорится, если гора идет к Магомету, то Магомет идет к горе. Поэтому решил создать объект типа Картинка программно.

Для этого идеально подошел формат BMP (как самый простейший из форматов хранения изображений). Чтобы не заморачиваться с палитрой, выбрал 24-битную глубину изображения (байты цвета каждого пикселя хранятся в порядке Blue,Green,Red). Затем, не мудрствуя лукаво, создал однотонную картинку 16x16 в паинте и вооружившись HEX-редактором перенес оттуда заполненные поля заголовка файла в код 1С, который заполняет массив данных. Чтобы записать массив в бинарный файл, запихиваем его в COMSafeArray, который уже с помощью потока COMОбъекта "ADODB.Stream" сохраняем в файл.

Таким образом, путем нехитрых манипуляций родилась небольшая функция:

Функция СоздатьКартинку(Цвет)

    Данные = Новый Массив(822);

    // Заполняем заголовок файла служебной информацией

    Данные[0] = 66; Данные[1] = 77;
    Данные[2] = 54; Данные[3] = 03;
    Данные[10] = 54; Данные[14] = 40;
    Данные[18] = 16; Данные[22] = 16;
    Данные[26] = 01; Данные[28] = 24;
    Данные[38] = 195; Данные[39] = 14;
    Данные[42] = 195; Данные[43] = 14;

    // Заполняем всю картинку выбранным цветом
    // Единственный косяк в том, что нельзя выбрать ни WebЦвета, ни Windows
    // Как вариант, можно выбрать цвет на вкладке WevЦвета или Windows, затем перейдя на вкладку "из стиля"
    // поменять значение любого компонента цвета (красный, зеленый, синий) и вернуть его обратно
    Для Счетчик = 0 По 255 Цикл
        Данные[54 + Счетчик * 3] = Цвет.Синий;
        Данные[54 + Счетчик * 3 + 1] = Цвет.Зеленый;
        Данные[54 + Счетчик * 3 + 2] = Цвет.Красный;
    КонецЦикла;

    // Обводим рамочкой и не забываем, что строки в bmp-файле хранятся снизу-вверх
    Для Счетчик = 0 По 15 Цикл
        // рамка снизу
        Данные[54 + Счетчик * 3] = 0; Данные[55 + Счетчик * 3] = 0; Данные[56 + Счетчик * 3] = 0;
        // рамка сверху
        Данные[773 + Счетчик * 3] = 0; Данные[774 + Счетчик * 3] = 0; Данные[775 + Счетчик * 3] = 0;
        // рамка слева
        Данные[54 + Счетчик * 48] = 0; Данные[55 + Счетчик * 48] = 0; Данные[56 + Счетчик * 48] = 0;
        // рамка справа
        Данные[ 99 + Счетчик * 48] = 0; Данные[100 + Счетчик * 48] = 0; Данные[101 + Счетчик * 48] = 0;
    КонецЦикла;

    // Создаем bmp-файл
    ИмяФайла = ПолучитьИмяВременногоФайла("bmp");
    Поток = Новый COMОбъект("ADODB.Stream");
    Поток.Type = 1;
    Поток.Mode = 3;
    Поток.Open();
    Поток.Write(Новый COMSafeArray(Данные, "VT_UI1", Данные.Количество()));
    Поток.SaveToFile(ИмяФайла);
    Поток.Close();

    Возврат Новый Картинка(Новый ДвоичныеДанные(ИмяФайла));

КонецФункции

 Вот и все. Только пришлось добавить рамочку вокруг рисунка для красоты :)

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Serj (Serj1C) 31.05.12 12:29
очень интересно. я делал обработку для создания не только монотонных рисунков http://infostart.ru/public/77713/
проще было бы, конечно, использовать ком объект потока, но хотелось все чисто внутренними методами 1С
а так, беру на заметку
2. Павел Драгунов ([AdepT]) 31.05.12 12:44
Там же целый минипаинт :) А тут маленькая функция для создания иконки. Но, как говорится, на вкус и цвет... :)
4. Олег Шалимов (CaSH_2004) 10.06.12 02:15
Хорошая и полезная тема с отличными комментариями. Как-то недавно пришлось столкнуться как можно из библиотеки картинок извлечь таким-же макаром отдельные картинки - перепахал весь код и ускорил в 10 раз, хотя помучаться прищлось, необычные методики для 1С. Вот все никак на статью не разрожусь.
6. Мельнов Александр (dragonbridge) 14.08.12 12:12
C COMSafeArray неплохо придумал, надо будет взять на вооружение.
7. Павел Драгунов (softservice14) 22.10.16 06:35
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа