Jump to content
View in the app

A better way to browse. Learn more.

FGX Native

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Здравствуйте.

Еще одним нововведением в релизе 1.11.2.0, помимо TfgPopup, является работа с пикселями ("сырыми данными") TfgBitmap. Доступ к пикселям открывает практически неограниченные возможности для обработки и анализа изображений. Так же в новом релизе будет добавлена возможность поворота изображения.

 

Воможность работы с пикселями TfgBitmap.

Общие сведения.

Обращение к сырым данным возможно только между парными вызовами TfgBitmap.MapData и TfgBitmap.UnmapData, которые могут быть знакомы пользователям FMX. Однако, важным отличием от FMX, является отсутствие уровня доступа (только чтение/только запись/чтение и запись). Это сделано с целью ускорения доступа, т. к. работа осуществляется непосредственно с данными нативного изображения без создания промежуточного буфера.

В результате вызова TfgBitmap.MapData вы получаете интерфейс IFGXBitmapData (более подробно рассмотрен ниже), который предоставляет доступ к пикселям изображения.

Важно! Актуальность объекта IFGXBitmapData гарантирована только между вызовами TfgBitmap.MapData и TfgBitmap.UnmapData, т.к. используется "натуральный" интерфейс без подсчета ссылок.

Важно! Во время доступа к сырым данным операции по изменению TfgBitmap запрещены (например загрузка из различных источников, изменение размера, масштаба, поворота и тд).

Типичный пример работы с сырыми данными изображения:

var
  LBitmapData: IFGXBitmapData;
begin  
  if LBitmap.MapData(LBitmapData) then
    try
      // Работа с пикселями изображения.
    finally
      LBitmap.UnmapData;
    end;
end;

Важно! Всегда проверяйте результат выполнения TfgBitmap.MapData во избежание непредвиденных последствий. Повторный вызов TfgBitmap.MapData для уже спроецированных данных вернет ложь.

Интерфейс IFGXBitmapData.

Интерфейс IFGXBitmapData предоставляет информацию об изображении (Info, Width, Height), а так же позволяет манипулировать пикселями изображения (RawData, Scanlines, Pixels, Colors).

Информация о битмапе TfgBitmapInfo:

  1. BitsPerPixel — количество бит на один пиксель изображения. К примеру, для одного из самых распространенных вариантов ARGB, этот параметр будет равен 32-ум битам.
  2. BytesPerRow — количество байт на одну строку изображения. Обычно это Width * BitsPerPixel, но, в случае применения выравнивания для ускорения доступа к данным, значение может быть иным.
  3. PixelFormat — формат пикселя изображения. В отличии от фиксированного формата ARGB присущего стандартному типу TAlphaColor, нативные изображения могут иметь различный состав и порядок следования цветовых компонентов. Возможные комбинации этих параметров отражает тип  TfgBitmapPixelFormat.
    TfgBitmapPixelFormat = (Unknown, Alpha, Gray, ARGB, RGBA, RGB, RGB24);
  4. IsAlphaPremultiplied — флаг, показывающий являются ли компоненты пикселя предварительно помноженными на компоненту прозрачности.

Интерфейс IFGXBitmapData содержит несколько вариантов доступа к самим данным, которые отличаются по степени абстракции:

  1. RawData — самый низкий уровень. Возвращает указатель на начало данных. Размер данных можно узнать из свойства RawDataSize.
  2. Scanlines — указатель на переданную в аргументе строку. Размер данных строки в байтах можно получить из Info.BytesPerRow, количество пикселей в строке — Width.
  3. Pixels — указатель на пиксель. В аргументах передаются координаты пикселя. Размер пикселя в битах можно получить из Info.BitsPerPixel.
  4. Colors — цвет пикселя в стандартном формате TAlphaColor. В аргументах передаются координаты пикселя.

Как правило, для достижения максимальной скорости при последовательном сканировании пикселей изображения, вместо индексного доступа (Pixels, Colors) используют инкрементный перебор начиная с некой точки отсчёта (начало изображения RawData, начало определенной строки Scanlines[Y], определенный пиксель Pixelsх[X, Y]) . В этом случае вы получаете указатель, вместо привычного TAlphaColor.  Для преобразования данных по указателю в тип TAlphaColor вам могут пригодиться готовые варианты для конвератции, которые находятся в хэлпере TAlphaColorHelper из модуля FGX.Types.Color.

Для формирования TAlphaColor из сырых данных используйте перегруженный конструктор:

constructor Create(const APixel: PByte; const APixelFormat: TfgBitmapPixelFormat; const AIsAlphaPremultiplied: Boolean); overload;

Для обратной операции подойдет метод:

/// <summary>Записывает текущий цвет по адресу <c>APixel</c> с учетом опций <c>APixelFormat</c> и <c>AIsAlphaPremultiplied</c>.</summary>
procedure ToPixel(const APixel: PByte; const APixelFormat: TfgBitmapPixelFormat; const AIsAlphaPremultiplied: Boolean);

Реальный пример работы с сырыми данными.

Ниже приведен кусок кода из нового демонстрационного примера "Графика" -> "TfgBitmap - работа с "сырыми" данными" в котором изображение преобразуется из цветного в оттенки серого.

uses
  FGX.Types.Color, FGX.Canvas.Types, FGX.Canvas.Types, FGX.Assets, FGX.Assets.BitmapSet;

procedure TFormMain.fgButton1Tap(Sender: TObject);
var
  LBitmapSet: TfgAssetBitmapSet;
  LBitmap: TfgBitmap;
  LBitmapData: IFGXBitmapData;
  I, J: Integer;
begin
  if not TfgAssetsManager.Current.Find<TfgAssetBitmapSet>('Image', LBitmapSet) then
    Exit;
  LBitmap := LBitmapSet.GetBitmap;
  if LBitmap.MapData(TfgBitmapDataAccessMode.ReadWrite, LBitmapData) then
    try
      for J := 0 to LBitmap.Height - 1 do
        for I := 0 to LBitmap.Width - 1 do
          LBitmapData.Colors[I, J] := LBitmapData.Colors[I, J].ToGrayscale;
    finally
      LBitmap.UnmapData;
    end;
  fgPaintBox1.Invalidate;
end;

Повороты изображения.

Благодаря добавлению работы с сырыми данными появилась возможность с легкостью вращать изображения.

Поворот осуществляется с помощью метода TfgBitmap.Rotate:

/// <summary>Поворачивает изображение на указанный угол.</summary>
procedure Rotate(const AAngle: TfgRotation);

В качестве аргумента передается одно из предустановленных значений угла поворота.

TfgRotation = (Rotation0 = 0, Rotation90 = 90, Rotation180 = 180, Rotation270 = 270);

Поворот осуществляется по часовой стрелке.

 

Благодарим за внимание и приятного коддинга 🙂.

0 Comments

Recommended Comments

There are no comments to display.

Recently Browsing 0

  • No registered users viewing this page.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.