На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: Romtek, volvo877
  
    > Работа с картинками, Обработка спрайтов, работа с BMP для TMT
      :wall: Спешл фо ТМТ.
      Выкладываю модуль для работы с картинками. Включает он в себя всякую бяку (вплоть до загрузки/сохранения BMP, вставки/выразки картинок и т.д.). И как всегда, за основу взят стандартный модуль Graph. Просьбы о таком модуле были неоднократно, поэтому и размещаю.

      И заодно, если будут какие недовольства, пожелания, а лучше быстрые алгоритмы и советы, то дополню. Пишите.
      Сообщение отредактировано: Romtek -

      Прикреплённый файлПрикреплённый файлImages.rar (9.79 Кбайт, скачиваний: 810)
      Эта волна мне по душе,
      Я люблю быть со всеми на ТЫ...
      (ЧайФ)

      Nokia 5800, S60v5
      mShell - как проще всего программировать для Symbian
      Все о Maemo (Nokia N900, Nokia N810...)
        Ну раз уж пошла такая пьянка, то и я выложу свой модуль. Для ТМТ Pascal.
        Загружает PCX картинки. Причём количество цветов может быть любым. От 1 бита на pxl до 32 бит на pxl.
        Возможно этот модуль не так сильно наворочен, как модуль коллеги ( :D ) однако он изначально нужен мне был для загрузки любых картинок. А выризанием кусков из них у меня занимался объект TImage, который я писал отдельно. Кстати его тоже выложить было бы неплохо, там много разных вкусностей, взять хотябы альфаканал по маске или по значению alpha.
        Вот модуль:

        размер 3.5 кб
        Сообщение отредактировано: Romtek -

        Прикреплённый файлПрикреплённый файлpicunit.zip (3.55 Кбайт, скачиваний: 349)
          Статья по модулю.

          Ну, во-первых, для чего он нужен.
          У многих, наверняка, возникают потребности в различных средствах для работы с картинками (об их содержании я догадываться не буду... ;) ) таких, как вращение, фильтрация и т.д. Ну и естественно, как и подобает включены загрузка и сохранение какого-то стандартного формата файлов. В данном случае этот формат - BMP (не так уж сложно, но все же...). Модуль поддерживает любую стандартную глубину цвета (8,16,24 и 32). На этом, я полагаю, вступление можно считать законченным.


          Едем дальше - формат данных.
          Поскольку за основу взят Graph, то вывод картинок осуществляется с помощью PutImage (Итак всё быстро работает, зачем что-то менять?!). Содержание буфера, хранящего картинку вот такое:
          ExpandedWrap disabled
            tBitmap = Record {растровая картинка (стандартное представление BitMap в модуле Graph)}
              xSize, {горизонтальный размер (- 1)}
              ySize: Word; {вертикальный размер (- 1)}
              data: Array[0..0] Of byte; {цвета точек}
            End;

          А кругом используемый модулем Images формат такой:
          ExpandedWrap disabled
            Sprite = ^tSprite; {спрайт}
            tSprite = Object {содержание спрайта}
            Private
              _memSize: DWord;       {размер памяти, зарезервированной для спрайта}
            Public
              offsetX, {относительное смещение по горизонтали}
              offsetY: Integer; {относительное смещение по вертикали}
              transpMode: Boolean; {режим наложения}
              transpColor: 0..16777215; {цвет для transpMode}
              bitmap: tBitmap; {картинка}
            End;

          Понятно, что для внемодулевого кода доступно так:
          ExpandedWrap disabled
            tSprite = Record
              offsetX,
              offsetY: Integer;
              transpMode: Boolean;
              transpColor: 0..16777215;
              bitmap: tBitmap;
            End;

          Подробнее по полям.
          offsetX, offsetY задают смещение изображения. Они используются при выводе, повороте, горизонтальном и вертикальном отображениях, вырезке и вставке(НЕ ЗАБЫВАЙТЕ, ЧТО ЭТО НЕ КООРДИНАТЫ ЦЕНТРА ИЗОБРАЖЕНИЯ ОТНОСИТЕЛЬНО САМОГО ИЗОБРАЖЕНИЯ, А ИХ ПРОТИВОПОЛОЖНЫЕ ЗНАЧЕНИЯ!!!).
          transpMode и transpColor задают режим вывода изображения. Используются как параметры для SetTranspMode.
          bitmap (он и в Африке битмап) - сама картинка.


          Процедуры и функции - подпрограммы, как ни странно.

          ExpandedWrap disabled
            FUNCTION  ImageResult :Byte;

          Возвращает код ошибки последней операции, которая может вызвать ошибку. Константы ошибок:
          ImageOK = $00 (нет ошибки)
          ImageMinXError = $01 (ошибка левой границы)
          ImageMinYError = $02 (ошибка верхней границы)
          ImageMaxXError = $04 (ошибка правой границы)
          ImageMaxYError = $08 (ошибка нижней границы)
          ImageMemoryError = $10 (ошибка памяти)
          BMPFileError = $20 (ошибка заголовка BMP-файла)
          BMPDataError = $40 (ошибка данных BMP-файла)

          Следующие подпрограммы созданы для 8-битного режима и работают с imagePalette (открытая переменная модуля). Во всех встроенных в модуль подпрограммах использующих эти imagePalette обновляется автоматически. В противном случае её придется заполнять самостоятельно.
          ExpandedWrap disabled
            PROCEDURE AnalizeRGB256(color :Byte; VAR r,g,b: Byte);
            // Аналог AnalizeRGB, но для 256-цветового режима.
             
            FUNCTION  RGBColor256(r,g,b :Byte) :Byte;
            // Аналог RGBColor, но для 256-цветового режима.
             
            PROCEDURE NotPaletteRGB(VAR r,g,b :Byte);
            // Возвращает RGB составляющие цвета, не находящегося в палитре.
             
            FUNCTION  NewSprite(xSize,ySize :Word) :Sprite;
            // Резервирует память для хранения спрайта размерами xSize на ySize.
             
            PROCEDURE DisposeSprite(VAR spr :Sprite);
            // Освобождает память, занятую спрайтом.
             
            PROCEDURE GetSprite(spr :Sprite; x,y :Integer; width,height :Word);
            // Загружает в спрайт прямоугольную область с левым верхним углом в точке (x,y) размерами width на  height.
             
            PROCEDURE DrawSprite(x,y :LongInt; spr :Sprite);
            // Выводит спрайт на экран из точки (x,y).
            // Не забывайте про offsetx и offsetY.
            // ВНИМАНИЕ! После вывода общий TranspMode изменится на TranspMode спрайта.
             
            FUNCTION  SpriteMemSize(spr :Sprite) :DWord;
            // Возвращает размер памяти, занимаемой спрайтом.
             
            FUNCTION  SpriteBitmapMemSize(spr :Sprite) :DWord;
            // Возвращает размер памяти, необходимой для хранения изображения спрайта.
             
            FUNCTION  SpriteWidth(spr :Sprite) :Word;
            // Возвращает горизонтальный размер спрайта.
             
            FUNCTION  SpriteHeight(spr :Sprite) :Word;
            // Возвращает вертикальный размер спрайта.
             
            FUNCTION  CopySprite(spr :Sprite) :Sprite;
            // Создает копию спрайта.
             
            PROCEDURE FillSprite(spr :Sprite; color :DWord);
            // Заполняет спрайт цветом с номером color.
             
            FUNCTION  GetBitmapPixel(VAR bitmap; x,y :Word) :DWord;
            // Возвращает цвет пиксела растровой картинки с координатами (x,y).
             
            PROCEDURE SetBitmapPixel(VAR bitmap; x,y :Word; color :DWord);
            // Устанавливает цвет пиксела растровой картинки с координатами (x,y) на цвет с номером color.
             
            FUNCTION  GetSpritePixel(spr :Sprite; x,y :LongInt) :DWord;
            // Возвращает цвет пиксела изображения спрайта. Не забывайте про offsetx и offsetY.
             
            PROCEDURE SetSpritePixel(spr :Sprite; x,y :LongInt; color :DWord);
            // Устанавливает цвет пиксела изображения спрайта. Не забывайте про offsetx и offsetY.
             
            PROCEDURE FlipSpriteOX(spr :Sprite);
            // Зеркально отражает спрайт вдоль горизонтали (относительно OY). offsetX задает центр отображения.
             
            PROCEDURE FlipSpriteOY(spr :Sprite);
            // Зеркально отражает спрайт вдоль вертикали (относительно OX). offsetY задает центр отображения.
             
            PROCEDURE InvertSprite(spr :Sprite);
            // Инвертирует цвета изображение спрайта и цвет его TranspMode, применяя к его цветам операцию not.
            // А вообще тут использована стандартная процедура InvertImage.
             
            FUNCTION  RotateSprite(spr :Sprite; direction :Integer) :Sprite;
            // Создает новый спрайт, образованный поворотом заданного на угол direction
            // (задается целым числом градусов). При этом центр разворота задают offsetX и offsetY.
             
            PROCEDURE ExtractFromSprite(source, dest: Sprite; x, y: LongInt; width, height: Word);
            // Копирует прямоугольную область с левым верхним углом (x,y)
            // (Не забывайте про offsetx и offsetY.) и размерами width на height из спрайта source в dest.
             
            PROCEDURE StampInSprite(source, dest:Sprite; x, y: LongInt);
            // Вставляет один спрайт source в dest из точки (x,y). Не забывайте про offsetx и offsetY.
             
            FUNCTION  FilterSprite(spr: Sprite; CONST rFilter, gFilter, bFilter: FilterCore): Sprite;
            // Создает новый спрайт, образованный фильтрацией заданного.
            Для каждой из трех цветовых плоскостей задается свой фильтр.

          Немного о фильтрации. Изображение спрайта рассматривается в 3 цветовых плоскостях (red, green и blue). Для каждого пикселя рассматриваются все соседние и он сам (квадратик 3X3). Составляющие яркости в цветовой плоскости домнажаются на соответствующие значения в ядре фильтрации, складываются, и получается знычение яркости соответствующей составляющей пиксела в новом (отфильтрованном изображении).
          Описание ядра фильтрации:
          ExpandedWrap disabled
            FilterCore = Array[-1..1,-1..1] Of Real;

          Константы:
          EmptyFilter пустой фильтр
          NormalFilter нормальный фильтр
          BrightnessFilter фильтр яркости
          DarknessFilter фильтр темноты
          PreciseFilter фильтр четкости
          BlurredFilter фильтр размытия

          Далее - работа с файлами.

          Для начала - специальный формат для спрайтов, который хранит все что нужно.
          Следующие две подпрограммы работают с файлами открытыми ReWrite(f,1) или Reset(f,1). Их можно использовать для обработки файлов, хранящих несколько спрайтов (ну, например анимированный курсорчик).
          ExpandedWrap disabled
            FUNCTION  ReadSprite(VAR f :File) :Sprite;
            // Считывает данные о спрайте из файла.
             
            PROCEDURE WriteSprite(VAR f :File; spr :Sprite);
            // Записывает данные о спрайте в файл.
             
            FUNCTION  LoadSprite(fileName :String) :Sprite;
            // Загружает спрайт из файла.
             
            PROCEDURE SaveSprite(spr :Sprite; fileName :String);
            // Сохраняет спрайт в файл.


          Теперь - BMP. Хотелось бы заметить, что этот модуль загружает BMP также с любым количеством бит на пиксел (1, 4, 8, 24), но, правда, без сжатия.

          Поскольку BMP не хранит всей нужной информации для спрайта, то offsetX, offsetY и transpColor устанавливаются в нуль, а transpMode в False.
          ExpandedWrap disabled
            PROCEDURE LoadBMPInfo(fileName :String; VAR info :BMPInfo);
            // Считывает информацию о BMP из файла.
             
            (* Обработка файлов с несколькими картинками *)
             
            FUNCTION  ReadBMP(VAR f :File; bitmapOffset :DWord) :Sprite;
            // Считывает BMP изображение из файла.
             
            PROCEDURE WriteBMP(VAR f :File; spr :Sprite; xResolution,yResolution :DWord);
            // Записывает BMP изображение в файл.
             
            FUNCTION  LoadBMP(fileName :String) :Sprite;
            // Загружает спрайт из BMP-файла.
             
            PROCEDURE SaveBMP(spr :Sprite; fileName :String; xResolution,yResolution :DWord);
            // Сохраняет спрайт в BMP-файл. Отдельно задаются горизонтальное и вертикальное разрешения (в пикселах на метр).


          Ну вот, вроде, и все. Как всегда: вопросы и предложения пишите. Остальная необходимая правка на милость модераторам, эх...
          Эта волна мне по душе,
          Я люблю быть со всеми на ТЫ...
          (ЧайФ)

          Nokia 5800, S60v5
          mShell - как проще всего программировать для Symbian
          Все о Maemo (Nokia N900, Nokia N810...)
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script Execution time: 0,0934 ]   [ 17 queries used ]   [ Generated: 17.06.19, 07:20 GMT ]