Monday, December 18, 2017

Using of FireMonkey's Graphics on Linux Server

FmxLinux isn't only UI solution, it is a easy way to use graphics in your web script or server apps.

Installing dependencies to Server


To use graphical features on your server app some dependencies should be installed. You don't need to install whole X11 system to server. 

To install dependencies type this in terminal:
sudo apt install libgl1-mesa-glx libglu1-mesa libgtk-3-common libgstreamer1.0 libgstreamer-plugins-base1.0

Writing server script


Common web-server script application is just regular console app. Create new Console Application and then as usual right click on Project in Project Inspector and select "Add FmxLinux" item (only available since FmxLinux 1.17). Next we show full source of simple apache cgi-script which generate PNG image.

Source code


program FmxWebScript;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Types,
  System.Classes,
  System.UIConsts,
  FMX.Types,
  FMX.Graphics,
  FMX.Utils;

var
  B: TBitmap;
  Stream: TStream;
  Cur: PByte;
  I: Integer;
  Keys: TStrings;
  Text: string;
  W, H: Integer;
  Query: string;
begin
  Query := GetEnvironmentVariable('QUERY_STRING');
  if Query.IsEmpty then
  begin
    Writeln('This is CGI script app, which is run under web server');
    Exit;
  end;

  Keys := TStringList.Create;
  Keys.CommaText := Query.Replace('&', ',');

  if not TryStrToInt(Keys.Values['width'], W) then
    W := 400;
  if not TryStrToInt(Keys.Values['height'], H) then
    H := 300;

  B := TBitmap.Create(W, H);
  if Keys.Values['color'] <> '' then
  begin
    if Keys.Values['color'] = 'random' then
    begin
      Randomize;
      B.Canvas.Fill.Color := $FF000000 or random($FFFFFF);
    end
    else
      B.Canvas.Fill.Color := StringToAlphaColor(Keys.Values['color'])
  end
  else
    B.Canvas.Fill.Color := $FFFF0000;
  B.Canvas.FillEllipse(B.BoundsF, 1);
  B.Canvas.Stroke.Color := claBlack;
  B.Canvas.DrawEllipse(B.BoundsF, 1);

  B.Canvas.Fill.Color := $FF000000;
  Text := 'FmxLinux';
  if Keys.Values['text'] <> '' then
    Text := Keys.Values['text'].Replace('%20', ' ');
  B.Canvas.FillText(B.BoundsF, Text, False, 1, [], TTextAlign.Center);

  Stream := TMemoryStream.Create;
  B.SaveToStream(Stream);

  Writeln('Content-type: image/png');
  Writeln('Content-length: ' + Stream.Size.ToString);
  Writeln;

  Cur := TMemoryStream(Stream).Memory;
  for I := 0 to Stream.Size - 1 do
  begin
    Write(Utf8Char(Cur^));
    Inc(Cur);
  end;
end.

Test link

We already publish this script on our web site: