Программирование ARM Разработка GUI с помощью Excel Mon, February 27 2017  

Поделиться

нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Разработка GUI с помощью Excel Печать
Добавил(а) microsin   

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

[Создание пиксельных изображений]

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

1. Подготовка листа для рисования точек. По умолчанию лист Excel имеет вытянутые по горизонтали ячейки.

Excel-default-worksheet

Прямоугольные ячейки хороши для ввода текста и формул, но для графики они неудобны. Нужно поменять размер ячеек так, чтобы они стали квадратными - тогда каждая ячейка будет соответствовать одной точке графического индикатора разрабатываемого устройства. Предположим, что Ваш графический индикатор LCD имеет размер экрана 240 по горизонтали на 128 точек по вертикали (индикатор WG240128A).

Winstar-LCD-WG240128A

Выделите все ячейки листа целиком (для этого нужно щелкнуть мышью в левом верхнем углу рабочего пространства, где начинаются заголовки строк и столбцов). Затем в меню Формат -> Строка -> Высота установите высоту 9, и в меню Формат -> Столбец -> Ширина установите ширину 1. Получится лист с мелкими квадратными ячейками.

Excel-worksheet-with-square-cells

2. Рисование графики. Теперь в области 240x128 ячеек можно с помощью инструмента Fill (Цвет заливки) рисовать по точкам графические изображения для организации GUI.

Excel-BMP-editor

Для упрощения работы можно записать макросы для заполнения выделенной области нужным цветом, и для очистки области. Макросы записываются через меню Сервис -> Макрос -> Начать запись... Привяжите к записываемому макросу удобную горячую комбинацию клавиш.

Excel-record-macro-fill-selection

Просмотреть текст записанных макросов и отредактировать их можно через меню Сервис -> Макрос -> Макросы... -> Изменить.

Excel-macro-menu

Sub Заполнение_области_черным_цветом()
'
' Заполнение_области_черным_цветом Макрос
' Макрос записан 04.12.2014
'
' Сочетание клавиш: Ctrl+f
'
    With Selection.Interior
        .ColorIndex = 1
        .Pattern = xlSolid
    End With
End Sub
 
Sub Очистка_области()
'
' Очистка_области Макрос
' Макрос записан 04.12.2014
'
' Сочетание клавиш: Ctrl+g
'
    Selection.Interior.ColorIndex = xlNone
End Sub

3. Экспортирование графики файл BMP. Для этой цели можно воспользоваться мощным инструментом - встроенным в Office языком программирования VBasic (VBA, Visual Basic for Applications). В интернете я нашел готовый скрипт для сохранения области листа Excel в растровый файл BMP без сжатия в формате RGB (24 бита на точку). Это на мой взгляд самый удобный и универсальный формат для представления графики встраиваемой микроконтроллерной техники. Его потом можно легко преобразовать и в монохромный формат. Скрипт я немного переделал так, чтобы он сохранял в файл выделенную область, и чтобы BMP-файлу автоматически давалось имя на основе текущей даты и времени.

Attribute VB_Name = "Module1"
Option Explicit
Option Base 1
Private Type typHEADER
    strType As String * 2  ' Сигнатура BMP-формата = "BM"
    lngSize As Long        ' Размер файла
    intRes1 As Integer     ' зарезервировано = 0
    intRes2 As Integer     ' зарезервировано = 0
    lngOffset As Long      ' смещение до данных растра (биты картинки)
End Type
Private Type typINFOHEADER
    lngSize As Long        ' Размер
    lngWidth As Long       ' Высота
    lngHeight As Long      ' Длина
    intPlanes As Integer   ' Количество слоев в файле
    intBits As Integer     ' Количество бит на пиксел (у нас RGB 24 бита)
    lngCompression As Long ' Тип компрессии (установлено в 0)
    lngImageSize As Long   ' Размер картинки (в байтах, установлено в 0)
    lngxResolution As Long ' Разрешение устройства по X (установлено в 0)
    lngyResolution As Long ' Разрешение устройства по Y (установлено в 0)
    lngColorCount As Long  ' Количество цветов (для 24 установлено в 0)
    lngImportantColors As Long ' "Важные" цвета (установлено в 0)
End Type
Private Type typPIXEL
    bytB As Byte    ' Blue, канал синего
    bytG As Byte    ' Green, канал зеленого
    bytR As Byte    ' Red, канал красного
End Type
Private Type typBITMAPFILE
    bmfh As typHEADER
    bmfi As typINFOHEADER
    bmbits() As Byte
End Type
'
' Генерирование имени файла из даты и времени.'
'
Function FileName() As String
    Dim currentTimeDate As Variant
    Dim iYear, iMonth, iDay As Integer
    Dim iHour, iMinute, iSec As Integer
    
    currentTimeDate = Now()
    iYear = Year(currentTimeDate)
    iMonth = Month(currentTimeDate)
    iDay = Day(currentTimeDate)
    iHour = Hour(currentTimeDate)
    iMinute = Minute(currentTimeDate)
    iSec = Second(currentTimeDate)
    FileName = Format(currentTimeDate, "yymmdd") _
             + Format(currentTimeDate, "hhmmss") + ".bmp"
End Function
'
' Этот макрос на входе получает диапазон ячеек листа
' Excel и создает по ним картинку - файл BMP по цветам
' ячеек. Формат файла BMP 24 бита, несжатый.
'
Sub subCellsToBMP(rngPicture As Range)
    Dim i As Long, j As Long, k As Long, l As Long
'
    Dim bmpFile As typBITMAPFILE
    Dim lngRowSize As Long
    Dim lngPixelArraySize As Long
    Dim lngFileSize As Long
'
    Dim bytRed As Integer, bytGreen As Integer, bytBlue As Integer
    Dim lngRGBColor() As Long
'
    Dim strBMP As String
'
' Сначала проверим на допустимый размер картинки - есть некоторые
' разумные ограничения
'
    If (rngPicture Is Nothing) Then Exit Sub
    If (rngPicture.Cells.Count < 4) Then
        MsgBox "Tried to export a BMP with less than 4 pixels!", _
        vbOKOnly + vbCritical, "BMP Export Error"
        Exit Sub
    End If
'
' Создание данных BMP, основываясь на выбранных ячейках.
'
    With bmpFile
' BMP Header
        With .bmfh
            .strType = "BM"      ' Базовый тип файла BMP
            .lngSize = 0         ' Определим позже (размер в байтах)
            .intRes1 = 0         ' Установлено в 0
            .intRes2 = 0         ' Установлено в 0
            .lngOffset = 54      ' Место, откуда начинается растр bitmap
        End With
' DIB Header
        With .bmfi
            .lngSize = 40        ' Это версия Version 3 BMP
            ' Количество пикселей по ширине:
            .lngWidth = rngPicture.Columns.Count
            ' Количество пикселей по высоте:
            .lngHeight = rngPicture.Rows.Count
            .intPlanes = 1       ' 1 слой
            .intBits = 24        ' 24 бита на точку (RGB)
            .lngCompression = 0  ' Без сжатия
            .lngImageSize = 0    ' Может быть установлено в 0
            .lngxResolution = 0  ' Установлено в 0
            .lngyResolution = 0  ' Установлено в 0
            .lngColorCount = 0   ' Установлено в 0 (нет цветовой палитры)
            .lngImportantColors = 0 ' Установлено в 0
        End With
        ' Размер 32-битного массива растра в байтах (нужно обеспечить
        ' выравнивание массива по 32 битной границе!).
        'Здесь была ошибка, на самом деле нужно использовать округление сверху:
        'lngRowSize = Round(.bmfi.intBits * .bmfi.lngWidth / 32) * 4
        'Начиная с версии Excel 2010 для выравнивания можно использовать это:
        'lngRowSize = WorksheetFunction.Ceiling_Precise _
        ' ((.bmfi.intBits * .bmfi.lngWidth / 32) * 4)
        'В версии Excel 2003 надо так:
        Dim rounded, unrounded As Double
        unrounded = .bmfi.intBits * .bmfi.lngWidth / 32
        rounded = Round(.bmfi.intBits * .bmfi.lngWidth / 32)
        If rounded < unrounded Then
            lngRowSize = (rounded + 1) * 4
        Else
            lngRowSize = rounded * 4
        End If
        lngPixelArraySize = lngRowSize * .bmfi.lngHeight
        ' Общее количество байт для сохранения выровненного массива пикселей
        ReDim .bmbits(lngPixelArraySize)
'
' Чтение данных цвета из ячеек (если цвета нет, то считается что
' это белый). Сканирование начинается снизу и продолжается вверх.
' Необходимо выравнивание каждой строки по границе 4 байта.
' ПРИМЕЧАНИЕ: вместо чтения цветов Вы можете читать числа,
' и получать значение "bytBlue", "bytGreen", "bytRed" напрямую
' из этих чисел.
'
        k = 0
        ReDim lngRGBColor(rngPicture.Rows.Count, rngPicture.Columns.Count)
        ' Цикл по строкам:
        For j = rngPicture.Rows.Count To 1 Step -1
            ' Цикл по столбцам:
            For i = 1 To rngPicture.Columns.Count
                If (LongToRGB(rngPicture.Cells(j, i).Interior.Color, _
                    bytRed, bytGreen, bytBlue)) Then
                    k = k + 1
                    .bmbits(k) = bytBlue
                    k = k + 1
                    .bmbits(k) = bytGreen
                    k = k + 1
                    .bmbits(k) = bytRed
                Else
                    k = k + 1
                    .bmbits(k) = 255
                    k = k + 1
                    .bmbits(k) = 255
                    k = k + 1
                    .bmbits(k) = 255
                End If
            Next i ' Для каждого столбца...
            If (rngPicture.Columns.Count * .bmfi.intBits / 8 < lngRowSize) Then
                ' Добавим выравнивание, если это необходимо
                For l = rngPicture.Columns.Count * .bmfi.intBits / 8 + 1 To lngRowSize
                    k = k + 1
                    .bmbits(k) = 0
                Next l
            End If
        Next j ' Цикл по строкам, начиная снизу...
'
' Все структуры загружены. Вычисляется размер файла и
' в него сохраняются данные растра.
'
        .bmfh.lngSize = 14 + 40 + lngPixelArraySize
'
    End With ' Определение bmpFile
'
    'Присвоим имя файлу и полный путь
    strBMP = ThisWorkbook.Path & "\" & FileName()
'
    Open strBMP For Binary Access Write As 1 Len = 1
'
    Put 1, 1, bmpFile.bmfh
    Put 1, , bmpFile.bmfi
    Put 1, , bmpFile.bmbits
'
    Close
'
End Sub
'
' Преобразование числа long integer, представляющего цвет,
' в значения каналов red, green, blue.
'
Public Function LongToRGB(theColor As Long, _
                          iRed As Integer, _
                          iGreen As Integer, _
                          iBlue As Integer) As Boolean
'
    iRed = theColor Mod 256                 'канал R
    iGreen = (theColor \ 256) Mod 256       'канал G
    iBlue = (theColor \ 256 \ 256) Mod 256  'канал B
'
    LongToRGB = True
End Function
'
' Эта подпрограмма тестирует макрос subCellsToBMP.
' Выделенный диапазон ячеек будет сохранен в файл
' как картинка BMP.
'
Sub Преобразовать_в_картинку()
Attribute Преобразовать_в_картинку.VB_Description = "Макрос записан 04.12.2014"
Attribute Преобразовать_в_картинку.VB_ProcData.VB_Invoke_Func = "b\n14"
    'Dim shtBMP As String имя листа, у меня не используется
    'Dim rngBMP As Range
    'shtBMP = "BMP Cells"
    'Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("A1:AN11")
    Call subCellsToBMP(Selection)
End Sub

4. Загрузка картинки из файла BMP.

Этот скрипт позволяет загрузить в ячейки листа Excel несжатую картинку BMP в формате цвета 24 бита на пиксел. Картинка будет вставлена в то место, где выделена текущая ячейка (это будет левый верхний угол загружаемой картинки).

Sub Загрузить_картинку()
Attribute Загрузить_картинку.VB_ProcData.VB_Invoke_Func = "l\n14"
    Dim BmpFileName As String
    Dim bmpHeader As typHeader
    Dim bmpInfoHeader As typInfoHeader
    Dim nRow As Integer, nCol As Integer
    Dim nRowBytes As Long
    Dim bmpPixel As typePixel
    
    'Запуск диалога выбора файла:
    With Application.FileDialog(msoFileDialogOpen)
        .InitialFileName = Application.ActiveWorkbook.Path
        .AllowMultiSelect = False
        .Filters.Add "Bitmap", "*.bmp", 1
        If .Show = -1 Then
            BmpFileName = .SelectedItems(1)
        Else
            Exit Sub
        End If
    End With
    'Файл успешно выбран, откроем его:
    Open BmpFileName For Binary Access Read As 1 Len = 1
        Get 1, 1, bmpHeader
        'Проверка типа файла
        If bmpHeader.strType < > "BM" Then
            MsgBox "Not a bitmap file.", vbCritical, "Error"
            End
        End If
        'Проверка формата BMP
        Get 1, , bmpInfoHeader
        If bmpInfoHeader.intBits <> 24 Then
            MsgBox "Sorry, only 24-bits BMP files can be converted.", vbCritical, "Error"
            End
        End If
        If bmpInfoHeader.lngCompression <> 0 Then
            MsgBox "Sorry, only uncompressed BMP files can be converted.", vbCritical, "Error"
            End
        End If
        'Получение количества байт на строку, с дополнением до 4 байт
        nRowBytes = bmpInfoHeader.lngWidth * 3   '3 байта на точку
        If nRowBytes Mod 4 < > 0 Then
            nRowBytes = nRowBytes + (4 - nRowBytes Mod 4)
        End If
        'Чтение картинки попиксельно
        Dim x, y As Integer
        x = Selection.Column - 1
        y = Selection.Row - 1
        For nRow = 0 To bmpInfoHeader.lngHeight - 1
            For nCol = 0 To bmpInfoHeader.lngWidth - 1
                Get 1, bmpHeader.lngOffset + 1 + nRow * nRowBytes + nCol * 3, bmpPixel
                Cells(y + bmpInfoHeader.lngHeight - nRow, x + nCol + 1).Interior.Color _
                       = RGB(bmpPixel.r, bmpPixel.g, bmpPixel.b)
            Next
        Next
    Close
End Sub

Excel-loaded-BMP

[Ссылки]

1. How can I create a bitmap image with VBA? site:answers.microsoft.com.
2. VBasic, краткий справочник.
3. Как делать шрифты для устройств на микроконтроллерах.

 

Добавить комментарий


Защитный код
Обновить

Top of Page