404 Страница не найдена — Turbo Pascal
Главная / Справочник / Примеры программ
| ||||
список операторов языка Turbo Pascal
Математические функции Функции управления программой Функции работы с указателями Функции работы с памятью Функции работы с файлами Функции работы с графикой и курсором Функции работы со строками и вводом/выводом на экран Функции работы со множествами Функции работы с оверлеями Другие функции |
Епанешниковы.
Программирование в среде TURBO PASCAL 7.0. Оглавление
А.Епанешников, В.Епанешников. Программирование в среде Turbo Pascal 7.0.
— 3-е изд., стер. — М.: «ДИАЛОГ-МИФИ», 1995. ISBN 5-86404-029-0
В данном пособии описна версия 7.0 широко распространенного пакета программирования
Turbo Pascal, разработанного фирмой Borland International. Приведены основные характеристики языка и среды программирования. Пособие может быть полезно как при изучении языка
Turbo Pascal, так и при создании программ на этом языке. Учебно-справочное издание.
Планирую постепенно выложить на сайте содержание этого пособия полностью. Пункты оглавления, для которых есть содержание будут выделены цветом и шрифтом.
ВВЕДЕНИЕ 1. АЛФАВИТ ЯЗЫКА 1.1. Символы, используемые в идентификаторах. 1.2. Разделители 1.3.Специальные символы 1.3.1. Знаки пунктуации 1. 3.2. Знаки операций 1.3.3. Зарезервированные слова 1.4. Неиспользуемые символы 2. СТРУКТУРА ПРОГРАММЫ 3. ТИПЫ ДАННЫХ 3.1. Классификация типов данных. 3.2. Простые типы данных 3.2.1. Целые типы 3.2.2. Логический тип 3.2.3. Символьный тип. 3.2.4. Перечисляемый тип 3.2.5. Тип-диапазон 3.2.6. Вещественные типы 4. ВЫРАЖЕНИЯ Ч.1 4.1. Переменные 4.2. Константы 4.2.1. Целые константы 4.2.2. Вещественные константы 4.2.3. Строковые и символьные константы 4.2.4. Константные выражения 4.2.5. Типизированные константы 4.3. Стандартные функции 4.3.1. Арифметические функции 4.3.2. Функции преобразования типа 4.3.3. Функции для величин порядкового типа ВЫРАЖЕНИЯ Ч.2 4.4. Знаки операций 4.4.1. Арифметические операции 4.4.2. Логические операции 4.4.3. Операции с битами информации 4. 4.4. Операции отношения 4.5. Круглые скобки 4.6. Порядок вычисления выражений 5. ОПЕРАТОРЫ ЯЗЫКА 5.1. Простые операторы 5.1.1. Оператор присваивания 5.1.2. Оператор безусловного перехода GOTO. Использование меток 5.1.3. Пустой оператор 5.2. Структурированные операторы 5.2.1. Составной оператор 5.2.2. Условный оператор IF 5.2.3. Условный оператор CASE 5.2.4. Оператор цикла REPEAT 5.2.5. Оператор цикла WHILE 5.2.6. Оператор цикла FOR 5.2.7. Использование стандартных процедур Break и Continue в операторах циклов REPEAT, WHILE и FOR 6. СТРУКТУРИРОВАННЫЕ ТИПЫ ДАННЫХ 6.1. Массив 6.2. Строка типа string 6.3. ASCIIZ-строка 6.4. Запись 6.5. Множество 6.6. Файл 7. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ 7.1. Указатель 7.2. Работа с динамической памятью 7.3. Работа со структурами данных 8. ПРОЦЕДУРНЫЕ ТИПЫ 9. СОВМЕСТИМОСТЬ И ПРЕОБРАЗОВАНИЕ ТИПОВ ДАННЫХ 9.1. Идентичность типов 9.2. Совместимость типов 9.3. Совместимость для присваивания 9.4. Преобразование типов 10. ПРОЦЕДУРЫ И ФУНКЦИИ 10.1. Процедура 10.2. Функция 10.3. Формальные и фактические параметры. 10.3.1. Параметры-значения 10.3.2. Параметры-переменные 10.3.3. Параметры-константы 10.3.4. Параметры без типа 10.3.5. Массивы и строки открытого типа 10.3.6. Параметры-процедуры и параметры-функции 10.4. Процедура EXIT 10.5. Директивы подпрограмм 10.5.1. Директива FORWARD 10.5.2. Директивы FAR я NEAR 10.5.3. Директива EXTERNAL 10.5.4. Директива ASSEMBLER 10.5.5. Директива INLINE 10.5.6. Директива INTERRUPT 10.6. Рекурсивные процедуры и функции 11. ОРГАНИЗАЦИЯ ВВОДА-ВЫВОДА 11.1. Стандартные процедуры и функции для всех файлов 11. 2. Стандартные процедуры и функции для текстовых файлов 11.3. Стандартные процедуры и функции для типизированных файлов 11.4. Стандартные процедуры и функции для файлов без типа 11.5. Внешние устройства в качестве файлов 12. ИСПОЛЬЗОВАНИЕ ЯЗЫКА АССЕМБЛЕРА В ПРОГРАММАХ НА TURBO PASCAL 7.0 12.1. Использование компилятора TASM 12.2. Использование встроенного ассемблера 12.3. Использование директивы ASSEMBLER 12.4. Использование оператора или директивы INLINE 13. ПРОГРАММИРОВАНИЕ НА ФИЗИЧЕСКОМ УРОВНЕ 14. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В TURBO PASCAL 7.0 14.1. Пример использования ООП 14.2. Понятие объекта 14.2.1. Инкапсуляция 14.2.2. Наследование 14.2.3. Полиморфизм 14.3. Виртуальные методы 14.3.1. Объявление виртуальных методов 14.3.2. Конструкторы и деструкторы 14.3.3. Возможности модификации программы при использовании виртуальных методов 15. МОДУЛИ 15.1. Заголовок модуля 15.2. Интерфейс модуля 15.3. Исполнительная часть модуля 15.4. Секция инициализации 15.5. Использование модуля в основной программе 15.6. Использование идентификаторов элементов модуля 16. СТАНДАРТНЫЕ МОДУЛИ 16.1. Модуль System Процедура Append. Процедура Assign. Процедура BlockRead. Процедура Block Write. Процедура Break. Процедура ChDir. Процедура Close. Процедура Continue. Процедура Dec. Процедура Delete. Процедура Dispose. Процедура Erase. Процедура Exclude. Процедура Exit. Процедура FillChar. Процедура Flush. Процедура FreeMem. Процедура GetDir. Процедура GetMem. Процедура Halt. Процедура Inc. Процедура Include. Процедура Insert. Процедура Mark. Процедура MkDir. Процедура Move. Процедура New. Процедура Randomize. Процедура Read (текстовые файлы). Процедура Read. Процедура ReadLn. Процедура Release. Процедура Rename. Процедура Reset. Процедура Rewrite. Процедура RmDir. Процедура RunError. Процедура Seek. Процедура SetTextBuf. Процедура Str. Процедура Truncate. Процедура Val. Процедура Write (текстовые файлы). Процедура Write (типизированные файлы). Процедура WriteLn. Функция Abs. Функция Addr. Функция АгсТап. Функция Assigned. Функция Chr. Функция Concat. Функция Сору. функция Cos. функция CSeg. Функций DSeg. Функция Eof. Функция Eoln. Функция Ехр. Функция FilePos. Функция FileSize. Функция Frac. Функция Hi. Функция High. Функция Int. Функция lOResulf. Функция Length. Функция Ln. Функция Lo. Функция Low. Функция MaxAvail. Функция MemAvail. Функция New. функция Odd. Функция Ofs. Функция Ord. Функция ParamCount. Функция ParamStr. Функция Pi. Функция Pos. Функция Pred. Функция Ptr. Функция Random. Функция Round. Функция SeekEof. Функция SeekEoln. Функция Seg. Функция Sin. Функция SizeOf. Функция SPtr. Функция Sqr. Функция Sqrt. Функция SSeg. Функция Succ. Функция Swap. Функция Trunc. Функция UpCase 16.2. Модуль Strings Процедура StrDispose. функция StrCat. Функция StrComp. Функция StrCopy. Функция StrECopy. Функция StrEnd. Функция StrIComp. Функция StrLCat. функция StrLComp. Функция StrLCopy. Функция StrLen. Функция StrLIComp. Функция StrLower. Функция StrMove. Функция StrNew. Функция StrPas. Функция StrPCopy. Функция StrPos. Функция StrRScan. Функция StrScan. Функция StrUpper 16.3. Модуль Crt Процедура AssignCrt. Процедура ClrEol. Процедура ClrScr. Процедура Delay. Процедура DelLine. Процедура GotoXY. Процедура HighVideo. Процедура InsLine. Процедура LowVideo. Процедура NormVideo. Процедура NoSound. Процедура Sound. Процедура TextBackground. Процедура TextColor. Процедура TextMode. Процедура Window. Функция KeyPressed. Функция ReadKey. функция WhereX. Функция WhereY. Пример использования подпрограмм модуля CRT 16.4. Модуль Graph Процедура Arc. Процедура Ваr. Процедура Bar3D. Процедура Circle. Процедура ClearDevice. Процедура ClearViewPort. Процедура CloseGraph. Процедура DetectGraph. Процедура DrawPoly. Процедура Ellipse. Процедура FillEllipse. Процедура FillPoly. Процедура FloodFill. Процедура GetArcCoords. Процедура GetAspectRatio. Процедура GetDefaultPalette. Процедура GetFillPattern. Процедура GetFillSettings. Процедура GetImage. Процедура GetLineSettings. Процедура GetModeRange. Процедура GetPalette. Процедура GetTextSettings. Процедура GetViewSettings. Процедура GraphDefaults. Процедура InitGraph. Процедура Line. Процедура LineRel. Процедура LineTo. Процедура MoveRel. Процедура MoveTo. Процедура OutText. Процедура OutTextXY. Процедура PieSlice. Процедура PutImage. Процедура PutPixel. Процедура Rectangle. Процедура RestoreCrtMode. Процедура Sector. Процедура SetActivePage. Процедура SetAllPalette. Процедура SetAspectRatio. Процедуpa SetBkColor. Процедура SetColor. Процедура SetFillPattern. Процедура SetFillStyle. Процедура SetGraphBufSize. Процедура SetGraphMode. Процедура SetLineStyle. Процедура SetPalette. Процедура SetRGBPalette. Процедура SetTextJustify. Процедура SetTextStyle. Процедура SetUserCharSize. Процедура SetViewPort. Процедура SetVisualPage. Процедура SetWriteMode. Функция GetBKColor. Функция GetColor. Функция GetDriverName. Функция GetGraphMode. Функция GetMaxColor. Функция GelMaxMode. Функция GetMaxX. Функция GetMaxY. Функция GelModeName. Функция GetPaletteSize. Функция GetPixel. Функция GetX. Функция GetY. Функция GraphErrorMsg. Функция GraphResult. Функция ImageSize. Функция InstallUserDriver. Функция InstallUserFont. Функция RegisterBGIdriver. Функция RegisterBGlfont. Функция TextHeight. Функция TextWidth. Пример использования подпрограмм модуля Graph 16.5 Модуль Dos Процедура Exec. Процедура FindFirst. Процедура FindNext. Процедура FSplit. Процедура GetCBreak. Процедура GetDate. Процедура GetFAttr. Процедура GetFTime. Процедура GetlntVec. Процедура GetTime. Процедура GetVerify. Процедура Intr. Процедура Keep. Процедура MsDos. Процедура PackTime. Процедура SetCBreak. Процедура SetDate. Процедура SetFAttr. Процедура SetFTime. Процедура SetIntVec. Процедура SetTime. Процедура SetVerify. Процедура SwapVectors. Процедура UnpackTime. Функция DiskFree. Функция DiskSize. Функция DosExitCode. Функция DosVersion. Функция EnvCount. Функция EnvStr. Функция FExpand. Функция FSearch. Функция GetEnv. Пример использования подпрограмм модуля Dos 16.6. Модуль WinDos Процедура CreateDir. Процедура FindFirst. Процедура FindNext. Процедура GetCBreak. Процедура GetDate. Процедура GetFAttr. Процедура GetFTime. Процедура GetIntVec. Процедура GetTime. Процедура GetVerify. Процедура Intr. Процедура MsDos. Процедура PackTime. Процедура RemoveDir. Процедура SetCBreak. Процедура SetCurDir. Процедура SetDate. Процедура SetFAttr. Процедура SetFTime. Процедура SetlntVec. Процедура SetTime. Процедура SetVerify. Процедура UnpackTime. Функция DiskFree. Функция DiskSize. Функция DosVersion. Функция FileExpand. Функция FileSearch. Функция FileSplit. Функция GetArgCount. Функция GetArgStr. Функция GetCurDir. Функция GetEnvVar 16.7. Модуль Overlay Процедура OvrClearBuf. Процедура OvrInit. Процедура OvrInitEMS. Процедура OvrSetBuf. Процедура OvrSetRetry. Функция OvrGetBuf. Функция OvrGetRetry 16.8. Модуль Printer 17. ИНТЕГРИРОВАННАЯ СРЕДА ПРОГРАММИРОВАНИЯ 17.1. Вход в интегрированную среду 17. 2. Строка состояния 17.3. Система окон среды 17.3.1. Окна редактирования 17.3.2. Окна диалога 17.3.3. Информационные окна 17.3.4. Окна меню 17.4. Разработка программ в интегрированной среде 17.5. Система меню среды Turbo Pascal 7.0 17.5.1. Меню работы с файлами (File) 17.5.2. Меню редактирования (Edit) 17.5.3. Меню поиска информации (Searh) 17.5.4. Меню выполнения программы (Run) 17.5.5. Меню компиляции (Compile) 17.5.6. Меню отладки (Debug) 17.5.7. Меню инструментальных средств (Tools) 17.5.8. Меню параметров среды (Options) 17.5.9. Меню окон (Window) 17.5.10. Меню информационной помощи (Help) 17.5.11. Локальное меню 17.5.12. Клавиши быстрого управления 17.6. Экранный редактор 17.6.1. Некоторые рекомендации по созданию исходных текстов программ 17.6.2. Команды перемещения курсора 17. 6.3. Команды поиска фрагментов 17.6.4. Команды вставки и удаления информации 17.6.5. Команды работы с блоками информации 17.6.6. Команды разнообразного назначения 17.7. Компиляция программы 17.7.1. Переключающие ключи 17.7.2. Ключи параметров 17.7.3. Ключи условной компиляции 17.8. Отладка программы в интегрированной среде 17.8.1. Получение значений параметров, модификация параметров 17.8.2. Приостановка работы программы 17.8.3. Работа с подпрограммами 17.9. Система информационной помощи 17.10. Оптимизация программы Зарезервированные слова Turbo Pascal 7.0 Клавиши быстрого управления среды Turbo Pascal 7.0 Зарезервированные слова встроенного ассемблера Пример использования ООП Список литературы
Как получить значение цвета пикселя в IBitmap?
васян
#1
Если у вас есть объект IBitmap, как получить значение цвета пикселя из координат X и Y?
Вы никак не можете получить указатель на массив пикселей?
Желательно иметь в классе IBitmap следующую функцию: IColor GetPixel(int x, int y)
vasyan
#2
В этом случае я хотел бы спросить, как загрузить данные в объект IBitmap из двумерного массива байтов ARGB?
олиларкин
#3
мы еще не добавили это
некоторые обсуждения:
github. com/iPlug2/iPlug2Отрисовка пиксельного буфера на экране
У меня есть простой пиксельный буфер RGBA, который я хочу отображать в своем пользовательском интерфейсе каждый кадр. Моя первая мысль была…
улучшение графика
и эксперименты:
GitHubолиларкин/iPlug2
C++ Audio Plug-in Framework для настольных компьютеров, мобильных устройств и Интернета [ПРЕДВАРИТЕЛЬНАЯ ВЕРСИЯ] — olilarkin/iPlug2
васян
#4
Спасибо, но к сожалению в моем случае проще создать дубликат изображения в виде массива IColor, учитывая его небольшой размер.
Я просто хотел бы иметь больше возможностей в IBitmap. Долгое время программировал на Object Pascal в Delphi и Lazarus, был встроенный класс TBitmap и TBitmap32 из библиотеки Graphics32, порадовало обилие различных полезных функций для работы с растровым изображением. Однако при работе с IBitmap я стал чувствовать себя кастрированным котом, извините за каламбур.
олиларкин
#5
Если вам действительно нужно что-то в iplug2, и вы считаете себя опытным разработчиком,
лучше всего сделать действительно хороший запрос на включение.
1 Нравится
васян
#6
К сожалению я не такой сильный знаток C++, так как большую часть жизни я программировал на Object Pascal, продолжал бы, однако, несколько лет назад перешел на C++ и понял, что с намазанным им плагины работают быстрее. Тем не менее, у меня все еще есть трудности с графическим интерфейсом IPlug2, чтобы делать некоторые вещи, такие как редактор конвертов, его синтезатор VSTi PolyGAS, со временем я разберусь с этим.
656×531 144 КБ
олиларкин
#7
Графические интерфейсы выглядят великолепно
Так есть ли PolyGAS в iPlug2? Я скоро добавлю виджет IVEnvelopeEditor, который может помочь, но он не будет таким сложным, как на скриншоте
vasyan
#8
Благодарю! Со временем смогу разобраться со всеми нюансами IPlug2.
Редактор огибающих, используемый в PolyGAS, очень сложен, он редактирует 18 огибающих, а также масштабирование и прокрутку и множество других возможностей. Этот элемент управления также имеет режим KeyScale. В PolyGAS каждый параметр синтеза имеет свою огибающую и зависимость Note Key, редактируемую в режиме KeyScale, как показано на скриншоте.
полигаз655×530 118 КБ
1 Нравится
васян
#9
Я не нашел никаких функций IGraphics, которые позволяли бы измерять текст, например функции WinApi GetTextExtentPoint32. Эта функция очень необходима для создания профессионального графического интерфейса на основе IGraphics.
404 — СТРАНИЦА НЕ НАЙДЕНА
Почему я вижу эту страницу?
404 означает, что файл не найден. Если вы уже загрузили файл, имя может быть написано с ошибкой или файл находится в другой папке.
Другие возможные причиныВы можете получить ошибку 404 для изображений, поскольку у вас включена защита от горячих ссылок, а домен отсутствует в списке авторизованных доменов.
Если вы перейдете по временному URL-адресу (http://ip/~username/) и получите эту ошибку, возможно, проблема связана с набором правил, хранящимся в файле .htaccess. Вы можете попробовать переименовать этот файл в .htaccess-backup и обновить сайт, чтобы посмотреть, решит ли это проблему.
Также возможно, что вы непреднамеренно удалили корневой каталог документов или вам может потребоваться повторное создание вашей учетной записи. В любом случае, пожалуйста, немедленно свяжитесь с вашим веб-хостингом.
Вы используете WordPress? См. Раздел об ошибках 404 после перехода по ссылке в WordPress.
Как найти правильное написание и папку
Отсутствующие или поврежденные файлыКогда вы получаете ошибку 404, обязательно проверьте URL-адрес, который вы пытаетесь использовать в своем браузере. Это сообщает серверу, какой ресурс он должен использовать попытка запроса.
http://example.com/example/Example/help.html
В этом примере файл должен находиться в папке public_html/example/Example/
Обратите внимание, что в этом примере важен CaSe . На платформах с учетом регистра e xample и E xample не совпадают.
Для дополнительных доменов файл должен находиться в папке public_html/addondomain.com/example/Example/, а имена чувствительны к регистру.
Неработающее изображениеЕсли на вашем сайте отсутствует изображение, вы можете увидеть на своей странице поле с красным размером X , где отсутствует изображение. Щелкните правой кнопкой мыши на X и выберите «Свойства». Свойства сообщат вам путь и имя файла, который не может быть найден.
Это зависит от браузера. Если вы не видите на своей странице поле с красным X , попробуйте щелкнуть правой кнопкой мыши страницу, затем выберите «Просмотр информации о странице» и перейдите на вкладку «Мультимедиа».
http://example.com/cgi-sys/images/banner.PNG
В этом примере файл изображения должен находиться в папке public_html/cgi-sys/images/
Обратите внимание, что в этом пример. На платформах, которые обеспечивают чувствительность к регистру PNG и png — это разные местоположения.
Ошибки 404 после перехода по ссылкам WordPress
При работе с WordPress ошибки 404 Page Not Found часто могут возникать при активации новой темы или изменении правил перезаписи в файле .htaccess.
Когда вы сталкиваетесь с ошибкой 404 в WordPress, у вас есть два варианта ее исправления.
Вариант 1. Исправьте постоянные ссылки- Войдите в WordPress.
- В меню навигации слева в WordPress нажмите Настройки > Постоянные ссылки (Обратите внимание на текущую настройку. Если вы используете пользовательскую структуру, скопируйте или сохраните ее где-нибудь.)
- Выберите По умолчанию .
- Нажмите Сохранить настройки .
- Верните настройки к предыдущей конфигурации (до того, как вы выбрали «По умолчанию»). Верните пользовательскую структуру, если она у вас была.
- Нажмите Сохранить настройки .
Это приведет к сбросу постоянных ссылок и устранению проблемы во многих случаях. Если это не сработает, вам может потребоваться отредактировать файл .htaccess напрямую.
Вариант 2. Измените файл .htaccessДобавьте следующий фрагмент кода в начало файла .htaccess:
# НАЧАЛО WordPress
RewriteEngine On
RewriteBase / 9index.php$ — [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# Конец WordPress
Если ваш блог показывает неправильное доменное имя в ссылках, перенаправляет на другой сайт или отсутствуют изображения и стиль, все это обычно связано с одной и той же проблемой: в вашем блоге WordPress настроено неправильное доменное имя.
Как изменить файл .
htaccessФайл .htaccess содержит директивы (инструкции), которые сообщают серверу, как вести себя в определенных сценариях, и напрямую влияют на работу вашего веб-сайта.
Перенаправление и перезапись URL-адресов — это две очень распространенные директивы, которые можно найти в файле .htaccess, и многие скрипты, такие как WordPress, Drupal, Joomla и Magento, добавляют директивы в .htaccess, чтобы эти скрипты могли работать.
Возможно, вам потребуется отредактировать файл .htaccess в какой-то момент по разным причинам. В этом разделе рассказывается, как редактировать файл в cPanel, но не о том, что нужно изменить. статьи и ресурсы для этой информации.)
Существует множество способов редактирования файла .htaccess- Отредактируйте файл на своем компьютере и загрузите его на сервер через FTP
- Использовать режим редактирования программы FTP
- Используйте SSH и текстовый редактор
- Используйте файловый менеджер в cPanel
Самый простой способ редактирования файла . htaccess для большинства людей — через диспетчер файлов в cPanel.
Как редактировать файлы .htaccess в файловом менеджере cPanelПрежде чем что-либо делать, рекомендуется сделать резервную копию вашего веб-сайта, чтобы вы могли вернуться к предыдущей версии, если что-то пойдет не так.
Откройте файловый менеджер- Войдите в cPanel.
- В разделе «Файлы» щелкните значок File Manager .
- Установите флажок для Корень документа для и выберите доменное имя, к которому вы хотите получить доступ, в раскрывающемся меню.
- Убедитесь, что установлен флажок Показать скрытые файлы (dotfiles) «.
- Нажмите Перейти . Файловый менеджер откроется в новой вкладке или окне.
- Найдите файл .htaccess в списке файлов. Возможно, вам придется прокрутить, чтобы найти его.
- Щелкните правой кнопкой мыши файл . htaccess и выберите Редактировать код в меню. Кроме того, вы можете щелкнуть значок файла .htaccess, а затем Редактор кода значок вверху страницы.
- Может появиться диалоговое окно с вопросом о кодировании. Просто нажмите Изменить , чтобы продолжить. Редактор откроется в новом окне.
- При необходимости отредактируйте файл.
- Когда закончите, нажмите Сохранить изменения в правом верхнем углу. Изменения будут сохранены.
- Протестируйте свой веб-сайт, чтобы убедиться, что ваши изменения были успешно сохранены. Если нет, исправьте ошибку или вернитесь к предыдущей версии, пока ваш сайт снова не заработает.
- После завершения нажмите Закрыть , чтобы закрыть окно диспетчера файлов.
Заметки доктора Билла на VGA 320×200, 256-цветный режим
Заметки доктора Билла о режиме VGA 320×200, 256 цветов Copyright Dr. William T. Verts 28 апреля 1996 г.Этот документ содержит некоторые примечания для тех из вас, кто использует VGA на ПК совместим. Большую часть времени в Turbo Pascal или Turbo C, Borland .BGI достаточно для работы с графикой, но когда вам нужно 256 цветов, на самом деле не существует «стандартного» .BGI файл для режима 320×200. В сети есть несколько версий, но оказывается, что если вы делаете простую графику, которая не обязательно должен быть совместим со всеми графическими адаптерами, тогда действительно довольно легко написать свой собственный код для этого графический режим.
В режиме 320х200 256 цветов экран представляет собой массив из 64000 смежные байты, расположенные в виде 200 строк по 320 байтов, с одним байтом на пиксель, расположенным в памяти в абсолютном адрес $A000:$0000. Итак, если вы можете убедить адаптер чтобы перейти в этот режим, прорисовка материала на экране выглядит как просто, как тыкать байты в память по соответствующему смещению от $A000:$0000.
Если мы можем войти в графический режим, мы также должны иметь возможность чтобы выйти из графического режима и вернуться в текстовый режим.
Другая проблема, с которой нужно иметь дело, — это палитра, или таблица поиска цветов. Это список из 256 байтовых троек, хранится на карте VGA. Мы должны быть в состоянии получить текущую палитру с карты VGA, а также указать VGA карточка для использования созданной нами палитры.
Эти пять проблем, изложенных выше, требуют детального рассмотрения. знание адаптера VGA в этом режиме. Эти случаи требуют, чтобы мы либо использовали какой-либо язык ассемблера, либо некоторые нестандартные вызовы процедур или и то, и другое. В итоге, эти проблемы:
- Переход в графический режим 320×200 256 цветов.
- Выход из графического режима, возврат в текстовый режим.
- Получение текущей палитры с адаптера VGA.
- Обновление палитры в адаптере VGA на новую.
- Знание расположения графического экрана в памяти.
Вход в графический режим
Специального вызова для входа в этот графический режим нет, но мы можем вызвать код на ассемблере для переключения адаптера. Есть два основных метода. На прямом языке ассемблера 8088 (или используя директиву ASM в Turbo Pascal), вы используете следующие инструкции: ДВИГАТЕЛЬ AX, 13H Целое 10 ч. Другой способ — использовать вспомогательные процедуры для языка ассемблера. предоставляется в Turbo Pascal, который фактически делает то же самое. Тип «Регистры» объявлен в модуле DOS. «ЗаполнитьЧар» может быстро заполнить блок памяти одним и тем же значением, т.к. пока вы знаете адрес блока, количество байтов для изменения и значение, на которое их нужно изменить. Код такой следует: Процедура InitGraph ; Var R : Регистры ; Начинать FillChar (R, SizeOf(R), 0) ; R.AX := $0013 ; Intr ($10, R) ; Конец ;Выход из графического режима
Вернуться в текстовый режим так же просто, как и в графику. режим. Первый способ — использовать язык ассемблера: ТОПОР ДВИГАТЕЛЯ, 03H Целое 10 ч. Вы также можете использовать тип «Регистры» и сделать то же самое из Паскаля, как в следующем коде: Процедура CloseGraph ; Var R : Регистры ; Начинать FillChar (R, SizeOf(R), 0) ; R. AX := $0003 ; Intr ($10, R) ; Конец ;Палитра VGA Тип
Работать с палитрами немного сложнее. Прежде всего, вам нужно объявить тип, который совместим с назначением с палитрой записывается на карту VGA. Это можно сделать с типом Color_Table следующим образом (тип записи Color_Type такой же, как и в предыдущих обсуждениях): Color_Type = Запись Красный: Байт; Зеленый: Байт; Синий: Байт; Конец ; Color_Table = Массив [байт] Color_Type ; Обратите внимание, что это не совсем то же самое, что и палитра. тип, обсуждаемый в «Заметках доктора Билла» о Палитры, но конструктивно совместимы с массивом компонент типа Палитра. Если ты умный, вы можете использовать определение Color_Table в Тип палитры.При работе с VGA есть еще одна проблема. Хотя запись Color_Type содержит три байта, VGA использует только младшие шесть бит каждого байта для цвета ценность. Это дает 64 вариации на цвет вместо 256. (64x64x64=262144 возможных цвета) и означает, что значения следует сдвинуть влево на 2 бита (умножить на 4) после они извлекаются из VGA, чтобы получилось примерно правильно байтовые значения для истинного цвета RGB со сдвигом вправо на 2 бита (деленное на 4), прежде чем они будут помещены в VGA.
Получение текущей палитры VGA
Это немного сложнее, чем просто войти в или вне графического режима, так как регистров намного больше установить. Конечно, это можно сделать очень просто в языке ассемблера, но в Паскале это делается так же просто, как показано ниже: Процедура Get_Palette (Var P:Color_Table) ; Var R : Регистры ; я: байт; Начинать FillChar(R, SizeOf(R), Ноль) ; (* Инициализировать запись *) С Р До Начинать AX := $1017; (* Команда для получения палитры *) БХ := 0 ; (* Начальный ввод палитры *) СХ := 256 ; (* Число входов *) ES := Seg(P) ; (* Адрес палитры *) DX := Ofs(P) ; (* Адрес палитры *) Конец ; Intr ($10, R) ; (*Выполнить команду*) (*———————————————— ———*) (* Превратите 6-битные записи палитры VGA в 8-битные байты RGB *) Для I := 0 до 255 Сделать С P[I] Do Начинать Красный := Красный SHL 2 ; Зеленый := Зеленый SHL 2 ; Синий := Синий SHL 2 ; Конец ; Конец ;Создание новой палитры VGA
Идем в другом направлении и помещаем новую палитру в VGA почти идентичен извлечению текущей палитры от ВГА. Команда языка ассемблера очень похожа, и значения байтов цвета должны быть сдвинуты вправо на 2 бита для преобразования их в 6-битные значения VGA перед сохранением их в VGA. Процедура Put_Palette (P:Color_Table) ; Var R : Регистры ; я: байт; Начинать (*———————————————— ———*) (* Превратите 8-битные значения RGB в 6-битные элементы палитры VGA *) Для I := 0 до 255 Сделать С P[I] Do Начинать Красный := Красный SHR 2 ; Зеленый := Зеленый SHR 2 ; Синий := Синий SHR 2 ; Конец ; (*———————————————— ———*) FillChar(R, SizeOf(R), Ноль) ; (* Инициализировать запись *) С Р До Начинать AX := $1012; (*Команда поставить палитру*) БХ := 0 ; (* Начальный ввод палитры *) СХ := 256 ; (* Число входов *) ES := Seg(P) ; (* Адрес палитры *) DX := Ofs(P) ; (* Адрес палитры *) Конец ; Intr ($10, R) ; (*Выполнить команду*) Конец ;Схема памяти
К счастью для нас, режим экрана 320х200 меньше 65536 байт. предел одной структуры данных на машине Intel. Это означает что мы можем легко рассматривать 64000 байт экрана как один массив, без необходимости делать какие-либо причудливые методы подкачки. С тех пор, как мы знать размер, макет и базовый адрес в памяти экрана, наш дополнительные объявления констант, типов и переменных становятся довольно просто: Постоянная ноль = 0; GetMaxX = 319; GetMaxY = 199; Тип VGA_Linear = Массив [0..63999] байтов; VGA_Array = Массив [Zero..GetMaxY, Zero..GetMaxX] байтов; Вар Screen_Linear : VGA_Linear Абсолют $A000:$0000 ; Screen_Array : VGA_Array Абсолют $A000:$0000 ; Обратите внимание, что у нас есть два разных расположения массивов в местоположение $A000:$0000. Первый из них простой одномерный массив, а второй — двумерный множество. Первый можно использовать для заливки всего экрана с одним значением (как при очистке экрана), а второй позволяет нам обращаться к отдельным пикселям. 9; (*Восстановить экран*) Утилизировать (Сохранить_Экран) ; (* Освободить хранилище *) Тогда, конечно, файл экранов означает, что простая форма анимации можно добиться, читая кадры по одному из файла и вставить их прямо в видео буфер: Тип Screen_File = Файл VGA_Array ; Var Infile : Screen_File ; Температура: VGA_Pointer; (*——*) Новый (Временный) ; Назначить (Infile, ‘INFILE. ; Конец ; Закрыть (В файле) ; Распоряжаться (Температура) ;Подпрограммы PutPixel и GetPixel
Это две самые важные процедуры для графики, и они оба эффективно «отсекают + индексируют массив». я думаю они говорят сами за себя (обратите внимание, что индексирование массива с местоположениями X и Y требует, чтобы значение Y было первым индекс): Процедура PutPixel (X,Y:LongInt ; Color:Byte) ; Начинать Если (X >= ноль) и (X = ноль) и (Y GetMaxX) или (Y GetMaxY) Затем GetPixel := Zero Иначе GetPixel := Screen_Array[Y, X] ; Конец ;Очистка экрана
Теперь мы можем использовать тип VGA_Linear и Определение Screen_Linear, чтобы настроить весь экран на один цвет. Конечно, мы можем использовать цикл FOR, как в код: FOR I := 0 To 63999 Do Screen_Linear[I] := Color ; но мы можем использовать чрезвычайно быструю процедуру FillChar Turbo Pascal, чтобы совершить тот же подвиг: Процедура Fill_Screen (Color:Byte) ; Начинать FillChar(Screen_Linear, SizeOf(Screen_Linear), Color) ; Конец ; Процедура ClearDevice ; Начинать Заполнить_Экран (Ноль) ; Конец ;Горизонтальные и вертикальные линии
Поскольку мы знаем раскладку экрана в памяти, эти специализированные типы линий могут работать очень быстро (опять же использование процедуры FillChar в горизонтальной строке рутина). Медленный способ выполнения этих подпрограмм состоит в том, чтобы используйте цикл FOR, как в случае рисования горизонтальной строка от (X1,Y) до (X2,Y): Для X := X1 To X2 Do PutPixel (X, Y, Color); Когда известно, что значения находятся в пределах границ массива, тогда подпрограмма может избежать наказания за отсечение внутри каждый вызов PutPixel, например: FOR X := X1 To X2 Do Screen_Array[Y, X] := Color ; Конечно, самый быстрый способ — выполнить все отсечение в процедурах горизонтальной и вертикальной линии, затем используйте FillChar, если это возможно (Lswap — это утилита рутина, необходимая для отсечения, и Выход команда немедленно возвращается из процедуры, в которой такое случается): Процедура Lswap (Var N1,N2:LongInt) ; Вар Темп: LongInt; Начинать Темп := N1 ; N1 := N2 ; N2 := Темп ; Конец ; Процедура Horizontal_Line (X1,X2,Y:LongInt ; Color:Byte) ; Начинать Если Y GetMaxY, то Выход ; Если X1 > X2, то Lswap (X1, X2) ; Если X1 GetMaxX Тогда X2 := GetMaxX ; Если X1 GetMaxX, то Выход ; Если Y1 > Y2, то Lswap (Y1, Y2) ; Если Y1 GetMaxY, то Y2 := GetMaxY ; Для Y := Y1 To Y2 Сделайте Screen_Array[Y, X] := Color ; Конец ;На этом этапе все остальное важное может быть реализовано с точки зрения процедур, приведенных выше. Брезенхэм общего назначения подпрограмма линии вызывает PutPixel (или Horizontal_Line или Vertical_Line если эти особые условия соблюдены), нормальные круги и эллипсы вызов подпрограмм PutPixel, закрашенный круг и закрашенный прямоугольник Horizontal_Line и так далее. Настроить конечно можно эти подпрограммы к оборудованию VGA, и если скорость является проблемой (это всегда так) тюнинг надо делать. Если, с другой стороны, правильность важнее настройки (она всегда есть), то прямоугольник, круг и другие специальные процедуры могут и должны быть записаны в терминах перечисленных здесь примитивов. Если при необходимости их можно настроить на скорость позже.
VGA_320.ZIP (15K)
Это ссылка на файл, содержащий:
- (13K) Рабочий модуль Turbo Pascal со всеми перечисленными выше подпрограммами.
- (11K) Источник тестовой программы и
- (14K) Исполняемый файл MS-DOS.
Вернуться на страницу CS 32
Вернуться на страницу доктора Билла
программирование – brionv
Перейти к содержимому
До того, как я начал зарабатывать на жизнь написанием кода, это было моим хобби. Моим любимым проектом из юности, до того, как интернет стал массовым, была библиотека поддержки для других моих программ (маленькие виджеты, игры и утилиты для себя): загружаемая система графических драйверов для карт VGA и SVGA, *просто * до того, как Windows стала популярной и предоставила вам всю эту инфраструктуру. 😉
Основы
Я использовал комбинацию Pascal, C и языка ассемблера для создания хост-программ (в основном на Pascal) и загружаемых модулей (связанных вместе из C и ассемблерного кода). Я использовал C для более высокоуровневых частей драйверов, таких как рисование линий и кругов, потому что мне было проще выразить код, чем на ассемблере, но я все же мог создать крошечный фрагмент кода, который можно было связать, который был самодостаточным и не нуждался в коде. библиотека времени исполнения.
Высокопроизводительные циклы оптимизации и вызовы BIOS были выполнены на языке ассемблера, с прямым вызовом функций процессора, таких как вызовы прерываний, и ручным развертыванием и оптимизацией узких циклов для блитов, заливок и горизонтальных линий.
Модель драйвера
Драйвер должен быть скомпилирован с «крошечной» моделью памяти C и кодом C и ассемблера, связанным вместе в исполняемый файл DOS «.com», который был простейшим из возможных форматов исполняемого файла — он просто загружается в память в момент начало «сегмента» размером 64 КБ с небольшим пространством вверху для аргументов командной строки. Ваш код может безопасно принять значение указателя начала исполняемого файла в этом сегменте, поэтому вы можете использовать абсолютные указатели для ветвей и хранилища в локальной памяти.
Я сохранил ту же модель, но загрузил ее в память хост-программы и добавил еще одно соглашение: таблицу адресов в начале драйвера, указывающую на начало различных стандартных функций, список которых был примерно таким:
- установить режим
- очистить экран
- установить палитру
- установить пиксель
- получить пиксель
- нарисовать горизонтальную линию
- нарисовать вертикальную линию
- нарисовать2 круг 183
- blit/copy
Оптимизация
IIRC, драйвер может решить реализовать только несколько базовых функций, таких как установка режима и установка/получение пикселей, а остальные будут эмулироваться в общем коде C или Pascal, который может быть медленнее, чем оптимизированная версия.
Основные пользовательские оптимизации (вместо общего «заставить код работать быстрее») касались горизонтальных линий и заливок, где иногда можно было использовать функцию видеокарты — например, в вариантах «Mode X» VGA 256. -цветной режим, используемый во многих играх той эпохи, «плоский» режим памяти VGA можно было активировать для одновременной записи четырех пикселей одного цвета в горизонтальную линию или сплошную рамку. Вам нужно было пройти попиксельно только по левому и правому краям, если они не заканчивались на границе 4 пикселей!
Материалы SVGA иногда также имели специальные возможности, которые вы могли вызывать, хотя я не уверен, как далеко я когда-либо продвинулся в этом. (В основном я помню, как использовал настройку режима VESA и немного возился с разрешениями 640×480, 800×600 и, возможно, даже с экзотическим обещанием 1024×768!)
Графический интерфейс высокого уровня
уровень Pascal GUI поверх этого драйвера, который может выполнять очень простое рисование окон и виджетов и реагировать на события мыши и клавиатуры, используя низкоуровневый графический драйвер для выбора подходящего 256-цветного режима и рисования. Если это тот же проект, о котором я думаю, то мой отец фактически заплатил мне символическую сумму в качестве «субподрядчика» за использование моей библиотеки графического интерфейса в небольшой программе для дополнительного консультационного мероприятия.
Вот такая история моей первой оплачиваемой работы программистом! 🙂
Еще больше ностальгии
Ничего из этого не было новым или новаторским, когда я это делал; Я уверен, что большая часть этого была бы старой шляпой для любого, кто работает в индустрии графических библиотек и библиотек программ GUI! Но мне было очень интересно выяснить, как эти части сочетаются с инструментами, доступными мне в то время, имея всего лишь комнату, полную байт! Журнал и Журнал доктора Добба , чтобы соединить меня с внешним миром программирования.
Я очень рад, что дети (и взрослые!) изучающие программирование сегодня имеют доступ к большему количеству людей и большему количеству ресурсов, но я беспокоюсь, что они также наводнены миром «все уже сделано, так зачем делать что-то с нуля». ?» Что ж, испечь торт с нуля тоже весело, даже если у вас нет *необходимости*, потому что вы можете просто купить целый торт или смесь для торта!
Загружаемые драйверы и асимметричное использование языков программирования для конкретных областей работы *полезны*. В старом Portland Pattern Repository Wiki это называлось «чередование жестких и мягких слоев». 8-битные программисты называли это «делать потрясающие вещи с помощью машинного языка, встроенного в мои программы на Бейсике». Встроенный машинный код в программах на Бейсике, которые вы набирали из журналов? Так я жил в конце 1980-е/начало 1990-х, мои дорогие!
Будущее
У меня *возможно* все еще есть исходный код для некоторых из них на старом резервном CD-ROM. Если я найду его, я выложу этот материал на GitHub для развлечения моих коллег-программистов. 🙂
Опубликовано Автор brionCategories UncategorizedTags ProgrammingМетаграфика История изменений MetaWINDOW, 4.
4A-5.0B Метаграфика История изменений MetaWINDOW, 4.4A-5.0BИсправлено в версии 5.0B
- Исправлены ошибки с CopyBlit из S3 в память.
- Исправлены ошибки с отслеживанием курсора S3, когда курсор частично выходит за пределы растрового изображения.
- Исправлены ошибки, из-за которых S3 GetPixel и FloodFill не получали правильное значение пикселя.
- Добавлен режим S3 1280×1024 256.
- Добавлены (недокументированные) коды InitGraphics() для S3, использующих набор режимов VESA (просто добавьте 1).
- Исправлена ошибка AlignPattern() GP в PowerPack DPMI32.
- Исправлена ошибка DestroyBitmap() для 286 PM.
- Исправлена ошибка CloseBitmap() до 386 PM, когда не удалось выполнить InitBitmap().
- Исправлена ошибка, связанная с переходом в текстовый режим и возвратом для устройств из банка.
Исправлено в версии 5.0A
- ResrcQuery() игнорировал argCount и выполнял только 1 файл.
- Сделано Watcom с Rational или Pharlap для сохранения EBX при вызовах.
- Универсальная библиотека TNT (Borland-Ms-watcom) сохраняет EBX.
- Увеличен размер блокировки страницы для частей кода отслеживания курсора.
- Добавлена поддержка в GetPixel() и ReadImage() для чипов S3 Vision64.
- Добавлена поддержка SetBitmap( GrafPgAll ) для режимов S3.
- Добавлена поддержка перелистывания страниц для S3.
- Добавлена поддержка функции WaitRetrace() для режимов S3.
- SetFont(NULL) больше не вызывает QueryError() для публикации сообщения о неверном шрифте.
- ResrcQuery сбрасывал бы куски, если бы давал указатель NULL.
- Исправлена ошибка с CreateBitmap(cDISK) и Power Pack.
- Исправлена ошибка с круглым пером и линией рисования локальных координат в неправильных координатах.
- Исправлена ошибка с режимами SetBitmap( GrafPgAll..) и VESA в 32-битном режиме.
Исправлено в версии 4.
4C- 1280×1024 256-цветный режим VESA заглушался 16-битным кодом в библиотеках, не имеющих 16-битных драйверов.
- Visual C 32 и Borland C с Phar Lap TNT аварийно завершали работу при отслеживании курсора с драйверами 256 цветов.
- Удалено сохранение/восстановление es в DestroyBitmap().
- Фиксированный банк-менеджер для Paradise/Western digital 1024×768 16 цветов
- Исправлена ошибка с драйвером hicolor и изображениями, которые охватывают 64 КБ в реальном или 16-битном защищенном режиме (вылетал, если диапазон банка и диапазон сегментов).
- RectRegion()/SetRegion() не поддерживали ds для вызовов alloc. Ошибка появилась в 4.4A.
- Сделано перелистывание страницы VESA, попробуйте перевернуть, даже если VESA говорит, что у него есть только 1 страница из-за ошибки драйвера VESA
- Исправлена ошибка с синтетическим текстом TextFace() для блока питания borland 386
- Исправлена ошибка с вылетом Tseng 4000 800×600 16 цветов при инициализации. Ошибка, появившаяся в 4.4A
Исправлено в версии 4.4B
- Имя сегмента кода в сборках watcom изменено на _TEXT.
Исправлено в версии 4.4A
- FrameOval() с широким пером давал сбой, когда овал был настолько мал, что отверстие в середине закрывалось (только в некоторых случаях координат).
- FrameOval() с PenDash() и очень маленький овал вылетит при делении на ноль.
- Пропорциональный текст с прозрачной заменой на 8 бит на пиксель 386 выпавших частей символов.
- RectRegion() и SetRegion() не преобразовали координаты в глобальные.
- Паскаль TPU имел SetBitmap() только с одним аргументом.
- EmptyRect() сообщит о пустом, только если и x, и y равны нулю.
- Phar Lap 286 выдаст ошибку GP, если драйвер не может быть загружен из-за нехватки памяти.
- Добавлена поддержка 8-битных ЦАП через mapFlag mfDac8
- Добавлена поддержка мыши-джойстика
- Добавлена 24-битная поддержка XlateImage, включая 8-битный/3-плоскостной формат файлов PCX, а также 16->24- и 24->16-цветные xlates.
- Исправлена ошибка в многоплоскостном драйвере WriteImage() при использовании фрагмента области.
- StringWidth26() интерпретировал строку как символы, а не целые числа.
- CharWidth26() был объявлен как принимающий целое число, должен был сказать слово.
- MapPoly() в Pascal не использовал правильные параметры в стеке
- GrafPool(), вызванный после InitGraphics(), не использовал правильный сегмент при вызове free() в 16-битных библиотеках.
- ATI Graphics Ultra Pro SetDisplay() для 1280×1024 не устанавливала аппаратное отсечение. Если когда-либо было установлено значение 1024, то все, что выходит за пределы 1024, будет обрезано в режиме 1280.
- SetBitmap() теперь «запоминает», на какую страницу установлена grafMap, и может допускать вызов дважды подряд для одной и той же страницы, а также может обрабатывать до 8 страниц (320×200).
- SetDisplay() теперь определяет, находится ли grafMap уже в графическом режиме, и если да, то просто переворачивает страницу с помощью инструкции OUT.
- Поместить (назад) в заполненную прямоугольную опору для штриховых шрифтов
- Увеличен стек прерываний до 1024 байт для реального режима из-за дополнительных накладных расходов при использовании драйверов VESA.
- Добавлена новая функция GrafPgAll в SetBitmap().
- Добавлена поддержка запросов для ATI Wonder.
- Добавлена новая функция WaitRetrace()
- Добавлены новые функции CreateBitmap(), DestroyBitmap().
- TextFace() синтезированные облицовки и TextPath() с pathUp или pathDown отрисовывали бы все символы в одно и то же место (отображая только последний).
- Добавлены флаги формата hicolor 5:6:5 для grafMaps и изображений.
- Добавлена поддержка формата Hicolor 5:6:5 в XlateImage().
- Добавлена поддержка исполняемых файлов Phar Lap TNT NtStyle с использованием библиотек DLL.
- Добавлена поддержка расширителя dos Borland 386.
- Добавлен FindClosestRGB()
- Добавлен BitmapToRegion()
- Добавлен DestroyRegion()
- Удалена поддержка запросов для режимов Hicolor Tseng 4000. Был конфликт с платами Viper, что приводило к сбою системы.
- Добавлены GrafAlloc() и GrafFree() по умолчанию в библиотеку Watcom, которая использует передачу регистров.
- Выделение и освобождение виртуализированного сегмента памяти для библиотеки драйверов Phar Lap 286.
- Добавлена поддержка расширителя dos Borland DPMI 286.
- Поддержка Rational 16M преобразована в универсальную библиотеку DPMI.
- Добавлено исправление клавиатуры Phar Lap 286 для Windows.
- Добавлен переключатель cntrl-sysreq для событий клавиатуры.
- Добавлена поддержка перелистывания страниц VESA.
- Исправлена ошибка, связанная с драйверами VESA, которые возвращали атрибуты winA, установленные на r/w, и атрибуты winB только для записи.
- Удален вызов TextMode внутри RasterOp, поскольку он конфликтует с Borland RTL.
- Добавлена поддержка Безье.
- Исправлена ошибка с ReadImage() для монохромных, многоплоскостных, EGA, VGA при чтении изображений, исходящих из верхней части растрового изображения.
История изменений MetaWINDOW — версии с 4.1A по 4.3D
Вернуться на главную страницу Metagraphics
Metagraphics Software CorporationPO Box 225
Woodinville, WA 98072 U.S.A.
Copyright © 1995-1998 Metagraphics Software Corporation
Расширение ограничивающих рамок для обнаружения объектов
Различные форматы аннотаций
Ограничивающие рамки — это прямоугольники, которые отмечают объекты на изображении. Существует несколько форматов аннотаций ограничительных рамок. Каждый формат использует свое конкретное представление координат прыгающих боксов. Альбументации поддерживает четыре формата: pascal_voc
, альбументации
, кокос
и йоло
.
Давайте рассмотрим каждый из этих форматов и то, как они представляют координаты ограничивающих рамок.
В качестве примера мы будем использовать изображение из набора данных Common Objects in Context. Он содержит одну ограничивающую рамку, которая отмечает кошку. Ширина изображения составляет 640 пикселей, а высота — 480 пикселей. Ширина ограничивающего прямоугольника составляет 322 пикселя, а высота — 117 пикселов.
Ограничивающая рамка имеет следующие (x, y)
координаты углов: верхний левый — (x_min, y_min)
или (98px, 345px)
, верхний правый — (x_max, y_min)
или (420 пикселей, 345 пикселей)
, нижний левый — (x_min, y_max)
или (98px, 462px)
, нижний правый — (x_max, y_max)
или (420px, 462px)
. Как видите, координаты углов ограничивающей рамки вычисляются относительно верхнего левого угла изображения, имеющего (x, y)
координат (0, 0)
.
Пример изображения с ограничивающей рамкой из набора данных COCO
паскаль_voc
pascal_voc
— это формат, используемый набором данных Pascal VOC. Координаты ограничивающей рамки закодированы четырьмя значениями в пикселях: [x_min, y_min, x_max, y_max]
. x_min
и y_min
— это координаты верхнего левого угла ограничивающей рамки. x_max
и y_max
— координаты правого нижнего угла ограничивающей рамки.
Координаты ограничивающего прямоугольника примера в этом формате: [98, 345, 420, 462]
.
альбументаций
альбументации
похож на pascal_voc
, потому что он также использует четыре значения [x_min, y_min, x_max, y_max]
для представления ограничивающей рамки. Но в отличие от pascal_voc
, альбументаций
использует нормализованные значения. Чтобы нормализовать значения, мы делим координаты в пикселях по осям x и y на ширину и высоту изображения.
Координаты ограничивающей рамки примера в этом формате: [98/640, 345/480, 420/640, 462/480]
, которые равны [0,153125, 0,71875, 0,65625, 0,9625]
.
Albumentations использует этот формат для работы с ограничивающими прямоугольниками и их дополнения.
кокос
coco
— это формат, используемый набором данных Common Objects in Context COCO.
В coco
ограничивающая рамка определяется четырьмя значениями в пикселях [x_min, y_min, ширина, высота]
. Это координаты верхнего левого угла, а также ширина и высота ограничивающей рамки.
Координаты ограничивающего прямоугольника примера в этом формате: [98, 345, 322, 117]
.
йоло
В Йоло
ограничивающая рамка представлена четырьмя значениями [x_center, y_center, width, height]
. x_center
и y_center
— нормализованные координаты центра ограничивающей рамки. Чтобы нормализовать координаты, мы берем значения x и y в пикселях, которые отмечают центр ограничивающей рамки по осям x и y. Затем мы делим значение x на ширину изображения и значение y на высоту изображения. ширина
и высота
представляют собой ширину и высоту ограничивающей рамки. Они также нормализованы.
Координаты ограничивающего прямоугольника примера в этом формате: [((420 + 98) / 2) / 640, ((462 + 345) / 2) / 480, 322 / 640, 117 / 480]
, которые равны [ 0,4046875, 0,840625, 0,503125, 0,24375]
.
Как разные форматы представляют координаты ограничивающей рамки
Расширение ограничивающих рамок
Как и в случае с увеличением изображений и масок, процесс увеличения ограничивающих рамок состоит из 4 шагов.
- Вы импортируете необходимые библиотеки.
- Вы определяете конвейер расширения.
- Вы читаете изображения и ограничивающие рамки с диска.
- Вы передаете изображение и ограничивающие рамки конвейеру дополнений и получаете дополненные изображения и поля.
Примечание
Некоторые преобразования в Альбументации не поддерживают ограничивающие рамки. Если вы попытаетесь использовать их, вы получите исключение. Пожалуйста, обратитесь к этой статье, чтобы проверить, может ли преобразование увеличивать ограничивающие рамки.
Шаг 1. Импортируйте необходимые библиотеки.
импортировать альбументы как A импорт cv2
Шаг 2. Определите конвейер расширения.
Вот пример минимального объявления конвейера расширения, который работает с ограничивающими прямоугольниками.
преобразование = A.Compose([ A.RandomCrop(ширина=450, высота=450), A.Горизонтальное отражение (p=0,5), A. Случайный контраст яркости (p = 0,2), ], bbox_params=A.BboxParams(format='coco'))
Обратите внимание, что в отличие от увеличения изображений и масок, Compose
теперь имеет дополнительный параметр bbox_params
. Вам нужно передать экземпляр A.BboxParams
этому аргументу. A.BboxParams
указывает параметры для работы с ограничивающими рамками. Формат
задает формат координат ограничивающих рамок.
Это может быть pascal_voc
, альбументации
, кокос
или йоло
. Это значение является обязательным, так как Альбументация должна знать исходный формат координат для ограничительных рамок, чтобы правильно применять дополнения.
Помимо формата
, A.BboxParams
поддерживает еще несколько настроек.
Вот пример Compose
, который показывает все доступные настройки с A.BboxParams
:
преобразование = A.Compose([ A.RandomCrop(ширина=450, высота=450), A.Горизонтальное отражение (p=0,5), A. Случайный контраст яркости (p = 0,2), ], bbox_params=A.BboxParams(format='coco', min_area=1024, min_visibility=0.1, label_fields=['class_labels']))
мин_область
и min_visibility
Параметры min_area
и min_visibility
управляют тем, что Альбументации должны делать с расширенными ограничивающими рамками, если их размер изменился после увеличения. Размер ограничивающих рамок может измениться, если вы применяете пространственные дополнения, например, когда вы обрезаете часть изображения или когда вы изменяете размер изображения.
min_area
— значение в пикселях. Если площадь ограничивающей рамки после аугментации становится меньше min_area
, Альбументация уберет это поле. Таким образом, возвращенный список расширенных ограничивающих рамок не будет содержать эту ограничивающую рамку.
min_visibility
— это значение от 0 до 1. Если отношение площади ограничивающей рамки после увеличения к площади ограничивающей рамки до увеличения
становится меньше, чем min_visibility
, Альбументации отбрасывают эту рамку. Таким образом, если процесс расширения обрезает большую часть ограничивающей рамки, эта рамка не будет присутствовать в возвращаемом списке расширенных ограничивающих рамок.
Вот пример изображения, содержащего две ограничивающие рамки. Координаты ограничивающих рамок объявляются в формате coco
.
Пример изображения с двумя ограничивающими рамками
Сначала применяем аугментацию CenterCrop
без объявления параметров min_area
и min_visibility
. Увеличенное изображение содержит две ограничивающие рамки.
Пример изображения с двумя ограничивающими рамками после применения аугментации
Далее мы применяем то же расширение CenterCrop
, но теперь мы также используем параметр min_area
. Теперь увеличенное изображение содержит только одну ограничивающую рамку, потому что область другой ограничивающей рамки после увеличения стала меньше, чем min_area
, поэтому Альбументации удалили эту ограничивающую рамку.
Пример изображения с одной ограничительной рамкой после применения увеличения с помощью min_area
Наконец, мы применяем CenterCrop
дополнение с min_visibility
. После этого увеличения результирующее изображение не содержит ограничивающей рамки, потому что видимость всех ограничивающих рамок после увеличения ниже порога, установленного min_visibility
.
Пример изображения с нулевыми ограничивающими рамками после применения расширения с помощью min_visibility
Ярлыки классов для ограничительных рамок
Помимо координат, каждый ограничивающий прямоугольник должен иметь ассоциированную метку класса, указывающую, какой объект находится внутри ограничивающего прямоугольника. Есть два способа передать метку ограничивающей рамки.
Допустим, у вас есть пример изображения с тремя объектами: собака
, кошка
и спортивный мяч
. Координаты ограничивающих рамок в формате coco
для этих объектов: [23, 74, 295, 388]
, [377, 294, 252, 161]
и [333, 421, 49, 49]
.
Пример изображения с 3 ограничивающими рамками из набора данных COCO
1.
Вы можете передавать метки вместе с координатами ограничивающих рамок, добавляя их как дополнительные значения в список координат. Для изображения выше ограничивающие прямоугольники с метками классов станут [23, 74, 295, 388, 'собака']
, [377, 294, 252, 161, 'кошка']
и [333, 421, 49, 49, «спортивный мяч»]
.
Метки класса могут быть любого типа: целое число, строка или любой другой тип данных Python. Например, целочисленные значения в качестве меток классов будут выглядеть следующим образом: [23, 74, 295, 388, 18]
, [377, 294, 252, 161, 17]
и [333, 421, 49, 49, 37].
Кроме того, вы можете использовать несколько значений класса для каждой ограничивающей рамки, например, [23, 74, 295, 388, 'собака', 'животное']
, [377, 294, 252, 161, 'кошка', 'животное']
и [333, 421, 49, 49, 'спортивный мяч', 'предмет']
.
2. Метки для ограничивающих рамок можно передавать отдельным списком (предпочтительный способ).
Например, если у вас есть три ограничивающих прямоугольника, такие как [23, 74, 295, 388]
, [377, 294, 252, 161]
и [333, 421, 49, 49]
, вы можете создать отдельный список со значениями, такими как ['кошка', 'собака', 'спортивный мяч']
или [18, 17, 37]
, который содержит метки классов для этих ограничивающих прямоугольников. Затем вы передаете этот список с метками классов в качестве отдельного аргумента функции преобразования
. Альбументациям необходимо знать имена всех этих списков с метками классов, чтобы правильно соединить их с расширенными ограничивающими рамками. Затем, если ограничивающая рамка отбрасывается после увеличения, потому что она больше не видна, Альбументации также отбрасывает метку класса для этой рамки. Используйте 9Параметр 0011 label_fields для задания имен для всех аргументов в преобразовании
, которое будет содержать описания меток для ограничивающих рамок (подробнее об этом в шаге 4).
Шаг 3. Считайте изображения и ограничивающие рамки с диска.
Прочитать образ с диска.
изображение = cv2.imread("/path/to/image.jpg") изображение = cv2.cvtColor (изображение, cv2.COLOR_BGR2RGB)
Ограничивающие рамки могут храниться на диске в различных форматах сериализации: JSON, XML, YAML, CSV и т. д. Таким образом, код для чтения ограничивающих рамок зависит от фактического формата данных на диске.
После считывания данных с диска необходимо подготовить ограничивающие рамки для альбументации.
Альбументации предполагает, что ограничивающие рамки будут представлены в виде списка списков. Каждый список содержит информацию об одной ограничивающей рамке. Определение ограничивающего прямоугольника должно иметь в списке четыре элемента, которые представляют координаты этого ограничивающего прямоугольника. Фактическое значение этих четырех значений зависит от формата ограничивающих рамок (либо pascal_voc
, либо альбументаций
, кокос
или йоло
). Помимо четырех координат, каждое определение ограничивающей рамки может содержать одно или несколько дополнительных значений. Вы можете использовать эти дополнительные значения для хранения дополнительной информации об ограничительной рамке, такой как метка класса объекта внутри рамки. Во время дополнения Альбументации не будут обрабатывать эти дополнительные значения. Библиотека вернет их как есть вместе с обновленными координатами расширенной ограничивающей рамки.
Шаг 4. Передайте изображение и ограничивающие рамки конвейеру расширения и получите дополненные изображения и поля.
Как обсуждалось на шаге 2, существует два способа передачи меток классов вместе с координатами ограничивающих рамок:
1. Передайте метки классов вместе с координатами.
Итак, если у вас есть координаты трех ограничивающих прямоугольников, которые выглядят так:
коробки = [ [23, 74, 295, 388], [377, 294, 252, 161], [333, 421, 49, 49], ]вы можете добавить метку класса для каждой ограничивающей рамки в качестве дополнительного элемента списка вместе с четырьмя координатами. Итак, теперь список с ограничивающими прямоугольниками и их координатами будет выглядеть следующим образом:
коробки = [ [23, 74, 295, 388, 'собака'], [377, 294, 252, 161, 'кошка'], [333, 421, 49, 49, 'спортивный мяч'], ]
или с несколькими метками на каждую ограничивающую рамку:
коробки = [ [23, 74, 295, 388, 'собака', 'животное'], [377, 294, 252, 161, 'кошка', 'животное'], [333, 421, 49, 49, 'спортивный мяч', 'предмет'], ]
Вы можете использовать любой тип данных для объявления меток классов. Это может быть строка, целое число или любой другой тип данных Python.
Затем вы передаете изображение и ограничивающие рамки для него в преобразует функцию
и получает увеличенное изображение и ограничивающие рамки.
преобразовано = преобразование (изображение = изображение, bboxes = bboxes) преобразованное_изображение = преобразованное ['изображение'] преобразованные_ббоксы = преобразованные['ббоксы']
Пример входных и выходных данных для расширения ограничивающих рамок
2.
Передать метки классов отдельным аргументом в, преобразовать
(предпочтительный способ).Допустим, у вас есть координаты трех ограничивающих прямоугольников.
коробки = [ [23, 74, 295, 388], [377, 294, 252, 161], [333, 421, 49, 49], ]
Вы можете создать отдельный список, содержащий метки классов для этих ограничительных рамок:
class_labels = ['кошка', 'собака', 'попугай']
Затем вы передаете ограничивающие рамки и метки классов в transform
. Обратите внимание, что для передачи меток класса вам нужно использовать имя аргумента, которое вы объявили в label_fields
при создании экземпляра Compose на шаге 2. В нашем случае мы устанавливаем имя аргумента на class_labels
.
преобразовано = преобразование (изображение = изображение, bboxes = bboxes, class_labels = class_labels) преобразованное_изображение = преобразованное ['изображение'] преобразованные_ббоксы = преобразованные['ббоксы'] преобразованный_класс_метки = преобразованный['класс_метки']
Пример входных и выходных данных для расширения ограничивающих рамок с отдельным аргументом для меток классов
Обратите внимание, что label_fields
ожидает список, поэтому вы можете установить несколько полей, содержащих метки для ограничивающих рамок.