Скриншот с дисплея устройства: модуль для генерации bmp Решил поделиться своим модулем, который облегчает мне жизнь.
Занимаясь разработкой различных устройств, я неоднократно сталкивался с типовой задачей: когда приходит время писать инструкцию по эксплуатации для пользователей, появляется необходимость делать скриншоты с дисплея устройства.
То есть, для составления красивой документации нужно иметь возможность "сфотографировать" содержимое дисплея в любой момент времени, и сохранить получившуюся картинку в файл. Ну и потом уже можно вставлять эту картинку в саму инструкцию по эксплуатации.
Например, вот такие скриншоты с дисплея зарядного устройства:


(Простите, я так и не смог уговорить сахару отобразить эти картинки просто в один ряд. Если кто-то знает, как это делается - подскажите, пожалуйста)
Для облегчения этой задачи в будущем, я написал универсальный модуль, который генерирует картинку в формате bmp, а данные изображения берет из пользовательской callback-функции (которая и должна вернуть цвет пикселя в определенной точке дисплея).
Отличительной особенностью этого модуля является то, что данные генерируются маленькими частями (максимум - 4 байта) и возвращаются по одному байту, а не сразу вся картинка целиком. Такой алгоритм работает несколько медленнее, но он обладает существенным преимуществом: он дает вам полную свободу выбора в том, что именно и как именно вы будете делать с этими данными.
То есть, для генерации изображения абсолютно любого размера и любой глубины цвета, в RAM будет выделено одно и то же количество памяти: 46 байт! (плюс еще около 20 байт стека)
Как эти 46 байт будут выделены (из кучи, из стека или статически) - также зависит от вас.
Конечно, если вы захотите поместить всю сгенерированную картинку в массив в RAM, то размер этого массива таки будет напрямую зависеть от размера изображения. Но в условиях ограниченных ресурсов микроконтроллера обычно имеет смысл, например, сразу передавать сгенерированные данные по UART (на ПК, или еще куда-нибудь), или, скажем, записывать во flash.
Короче, делайте с ними что хотите.
---
Размер кода: около 2 Кб в режиме оптимизации для наименьшего размера кода.
Поддерживаемая глубина цвета: 1, 4, 8, 16, 24, 32 бит на пиксель.
---
Вот, например, пользовательский код, генерирующий простенькую картинку. Здесь мы генерируем 24-битную картинку 256 x 50 пикселей, залитую градиентом из зеленого в синий: 
#include "bmp_writer/bmp_writer.h"
/**
 * Пользовательская callback-функция, возвращающая цвет в определенной точке.
 * В реале здесь должен быть код, возвращающий цвет пикселя на экране,
 * но в этом примере мы просто генерим градиент.
 */
static T_BmpWr_Color32 _bmp_pix_color_get_32(
      uintptr_t user_data,
      T_BmpWr_Coord x,
      T_BmpWr_Coord y
      )
{
   return BMP_WR__COL_RGB_32bit(0x00, 0xff - x, x);
}
int main(void)
{
   //-- Создаем структуру с параметрами для генератора картинки
   T_BmpWriter_CtorParams writer_ctor_params = {
      //-- Основные параметры изображения: глубина цвета, размер
      .color_depth = BMP_WR_COL_DEPTH__24,
      .width       = 256,
      .height      = 50,
      //-- Пользовательские callback-функции
      .callback = {
         //-- здесь нам нужна только одна пользовательская функция:
         //   возвращающая цвет для 24- и 32-битных изображений
         .func = {
            .bpp_24_32 = {
               .p_pix_color_get = _bmp_pix_color_get_32,
            },
         },
      },
   };
   //-- Создаем объект T_BmpWriter с нужными параметрами
   T_BmpWriter *p_bmp_writer = new_bmp_writer(&writer_ctor_params);
   //-- Теперь, байт за байтом, запрашиваем все данные!
   while (bmp_writer__available_data_len__get(p_bmp_writer) > 0){
      char cur_char = bmp_writer__next_byte__get(p_bmp_writer);
      //-- сейчас cur_char содержит очередной байт изображения.
      //   мы можем сделать с ним все, что захотим: или накапливать
      //   данные в буфер для записи во флеш (когда буфер будет
      //   заполнен, то произвести запись, а потом продолжить
      //   запрос данных изображения) или, может быть, передавать
      //   куда-нибудь по UART (например, на ПК, где он будет сохранен)
   }
   //-- Все, картинка сгенерирована.
   //   Удаляем объект
   delete_bmp_writer(p_bmp_writer);
   return 0;
}
 
Если интересно, вот тут            можно прочитать подробную инструкцию с примерами и скачать сам модуль.


(Простите, я так и не смог уговорить сахару отобразить эти картинки просто в один ряд. Если кто-то знает, как это делается - подскажите, пожалуйста)
Для облегчения этой задачи в будущем, я написал универсальный модуль, который генерирует картинку в формате bmp, а данные изображения берет из пользовательской callback-функции (которая и должна вернуть цвет пикселя в определенной точке дисплея).
Отличительной особенностью этого модуля является то, что данные генерируются маленькими частями (максимум - 4 байта) и возвращаются по одному байту, а не сразу вся картинка целиком. Такой алгоритм работает несколько медленнее, но он обладает существенным преимуществом: он дает вам полную свободу выбора в том, что именно и как именно вы будете делать с этими данными.
То есть, для генерации изображения абсолютно любого размера и любой глубины цвета, в RAM будет выделено одно и то же количество памяти: 46 байт! (плюс еще около 20 байт стека)
Как эти 46 байт будут выделены (из кучи, из стека или статически) - также зависит от вас.
Конечно, если вы захотите поместить всю сгенерированную картинку в массив в RAM, то размер этого массива таки будет напрямую зависеть от размера изображения. Но в условиях ограниченных ресурсов микроконтроллера обычно имеет смысл, например, сразу передавать сгенерированные данные по UART (на ПК, или еще куда-нибудь), или, скажем, записывать во flash.
Короче, делайте с ними что хотите.
---
Размер кода: около 2 Кб в режиме оптимизации для наименьшего размера кода.
Поддерживаемая глубина цвета: 1, 4, 8, 16, 24, 32 бит на пиксель.
---
Вот, например, пользовательский код, генерирующий простенькую картинку. Здесь мы генерируем 24-битную картинку 256 x 50 пикселей, залитую градиентом из зеленого в синий: 
- 
	
- Полезная приблуда, спасибо - MBedder(09.12.2012 16:47)