для потомков.
Итак, есть bmp файл, sd карта, дисплей с библиотекой и bascom-avr. описываю для дислпея от nokia 3510i, но в принципе в случаем с баскомом дисплей особого значения не имеет.
Нулевой этап - проверка аппаратных вохможностей. в данном случае критичны скорость считывания с карточки и соответственно записи в дислпей. я тестировал на миниботе, это mega32+hardware spi sd card+software spi display+7.3728Mhz. отброшу нетрадиционную методику выяснения параметров (лишь упомяну, что использовался слух и вав-файл
![Smile :)](http://roboforum.ru/images/smilies/smile.gif)
) и сразу приведу данные: ~12-13кбайт/сек = канал данных с карточки. для дисплея верхний предел не находил, ибо сразу ясно, что считывание, к сожалению, тормозит. прикидываем приверную скорость работы, учитывая 8мибитный цвет и 98*67 пикселей: 12,5*1024/98/67 = 1.9 кадра/сек. с видео получается заморочка (но если использовать чересстрочную развертку и снизить количество цветов, то может что-нибудь да получится). заодним я обнаружил в библиотеке баг - при использовании функции pset сетка координат сдвинута на 1 и 1 пиксель вниз и влево соотвественно. решение - минусовать координаты на эти самые единички.
Первый этап - разбор bmp формата. подготовим в пейнте картинку 98*67 (разрешение дисплея) и сохраним в 256-тицветном формате. далее смотрим на спецификацию:
- Код: Выделить всё • Развернуть
Смещение Длина поля Описание поля (что тут находится)
Заголовок файла
0 2 Код 4D42h - Буквы 'BM'
2 4 Размер файла в байтах
6 2 0 (Резервное поле)
8 2 0 (Резервное поле)
10 4 Смещение, с которого начинается само изображение (растр).
Заголовок BITMAP (Информация об изображении)
14 4 Размер заголовка BITMAP (в байтах) равно 40
18 4 Ширина изображения в пикселях
22 4 Высота изображения в пикселях
26 2 Число плоскостей, должно быть 1
28 2 Бит/пиксел: 1, 4, 8 или 24
30 4 Тип сжатия
34 4 0 или размер сжатого изображения в байтах.
38 4 Горизонтальное разрешение, пиксел/м
42 4 Вертикальное разрешение, пиксел/м
46 4 Количество используемых цветов
50 4 Количество "важных" цветов.
Палитра (Карта цветов для N цветов), если используется
54 4*N Палитра
Формат цвета
R8G8B8RESERVED8
и пред нашими очами предстанут ровно две подставы: во-первых, использование индексированных цветов (каждый байт-пиксель задает смещение в таблице) - это потребует скакать по файлу после для извлечения каждого пикселя, что очень накладно в баскоме из-за буферизации ф.с. (при считывании данных в память загружается весь сектор=512 байт).
во-вторых, 256цветный режим совсем не означет 256 градаций от черного к белому. в интерпретации корпорации зла это всего лишь ограничение на максимальное количество 24битных цветов в файле.
поскольку суммарно эти два факта жестко снижают производительность (преобразование палитр та ещё штука), то переносим анализ bmpшки на пк.
между прочим, как мне стало известно, в формате предусмотрена ширина строки только кратная четырем, что при разрешениии 98*67 дает 134 мусорных байта
ещё одно неудобство - строки хранятся от последней к первой, если читать файл сверху.
Этап второй, придумываем свой формат для хранения имаги. здесь все просто - аппаратная платформа в наших проектах неизменная, поэтому просто сохраняем массив пикселей с разверткой по горизонтали.
Третий этап. пишем обертку вывода для вновь созданного формата на девайсе, в моем конкретном случае это:
- Код: Выделить всё • Развернуть
Dim Color As Byte
Dim I As Integer
Dim K As Integer
Const Filename1 = "lb.bmp"
Open Filename1 For Binary As #4
Cls
Do
For I = -1 To 65 '-1 связано со смещением
For K = -1 To 96 'сетки координат
Get #4 , Color
Pset K , I , Color 'pset X,Y, Color
Next
Next
Loop Until Eof(#4) <> 0
Close #4
по скорости получается примерно 1,5 кадра/сек. проявилась небольшая неприятность - обновление на картинке видно на дислпее. учитывая его низкую скорость, создается невинное ощущение того, что держишь в руках китайскую девайсину. фикс пока не известен мне.
Ну и последний этап, он же самый сложный - анализ bmp на пк. разобьем решение на две подзадачи - преобразование файла в структуру пиксель-цвет и преобразование 24битного цвета в 8мибитный.
начнем с наброска преобразоватора (самое первое что пришло в голову, простое усреднение):
- Код: Выделить всё • Развернуть
function convert(r: byte; g: byte; b: byte): byte;
begin
result := r*r + g*g + b*b;
result := sqrt(result/3)
result := trunc(result);
end;
вот набросок на делфи для решения первой задачи (писался методом перманентного хакинга, потому чрезвычайно некрасив, но тем не менее работает
![Smile :)](http://roboforum.ru/images/smilies/smile.gif)
):
- Код: Выделить всё • Развернуть
const
filename = 'linux.bmp';
fileout = 'output.bmp';
var
i,k: byte;
old: word;
f, f2, f3: TFileStream;
c: array[1..3] of byte;
buf: byte;
header: BITMAPFILEHEADER;
info: BITMAPINFOHEADER;
pos_palette: word;
pos_data: word;
begin
f := TFileStream.Create(filename, fmOpenRead);
f.ReadBuffer(header, sizeof(header)); // читаю заголовки
f.ReadBuffer(info, sizeof(info));
pos_palette := f.Position;
pos_data := header.bfOffBits;
f.Position := pos_data; // устанавливаю указатель на данных
// подготавливаю буффер файл для записи строк
f2 := TFileStream.Create('buf', fmCreate);
for i := 0 to 66 do // для сименса будут другие значения
begin
for k := 0 to 97 do
begin
f.ReadBuffer(buf, 1);
old := f.Position;
f.Position := pos_palette + buf;
f.ReadBuffer(c, 3); // считываю и преобразовываю цвет
f2.WriteBuffer(convert(c[1],c[2],c[3]), 1);
f.Position := old;
end;
f.Position := f.Position + 2;
end;
// разворачиваю строки
f3 := TFileStream.Create(fileout, fmCreate);
f2.Seek(-98, soFromEnd);
for i := 0 to 66 do
begin
for k := 0 to 97 do
begin
f2.ReadBuffer(buf, 1);
f3.WriteBuffer(buf, 1);
end;
f2.Seek(-196, soFromCurrent);
end;
end;
на выходе получаем файл *.bmp, хотя на самом деле от bmp в нем ничего и не осталось
закидываем на карточку, проверяем и ужасаемся цветопередаче
![Very Happy :D](http://roboforum.ru/images/smilies/biggrin.gif)
естетвенно, метод усреднения ничего хорошего и не мог дать, лишь бы показывал различие между соседними областями пикселей.
вообще, пример интересного преобразования показан в
этой статье, так что ждите продолжения
![Very Happy :D](http://roboforum.ru/images/smilies/biggrin.gif)
.