Skia4Delphi is a cross-platform 2D graphics API for Delphi platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
Skia4Delphi is an open-source, cross-platform 2D graphics library for Delphi, utilizing the esteemed Google's Skia library.
https://user-images.githubusercontent.com/1863024/175955980-f6c57253-aaa3-4617-90dc-b0d9bf25e21b.mp4
Skia is an exceptional open-source library dedicated to rendering 2D text, geometries and images, with a focus on precision, superior quality and high performance. It offers versatile APIs compatible with a wide range of hardware and software platforms.
Google's Skia Graphics Library functions as the graphics engine for numerous products, including Google Chrome, Chrome OS, Android, Flutter, Xamarin, Mozilla Firefox, Firefox OS, and more.
Using the Skia4Delphi library it is possible to override Firemonkey's graphic engine so that it can use Skia as its default Canvas. With that, your Firemonkey application will automatically:
You can install Skia4Delphi in 3 ways:
Setup (recommended)
Download the setup of latest release and install it.
Embarcadero's GetIt (RAD Studio > Tools > GetIt Package Manager...)
Chocolatey package manager
choco install skia4delphi
After install the Skia4Delphi, just right click in your application project and click Enable Skia.
To improve the quality and performance of FMX drawings, the replacement of the the FMX graphics engine with the Skia4Delphi render is automatically enabled. Learn more...
In this section you will find some examples of using Skia4Delphi, it works in Console, FMX, and VCL applications. The code below is common code among all the examples in this section:
uses
System.Skia;
type
TSkDrawExampleProc = reference to procedure(const ACanvas: ISkCanvas; const ADest: TRectF);
procedure DrawExample(const AWidth, AHeight: Integer; const ADrawProc: TSkDrawExampleProc);
begin
var LSurface := TSkSurface.MakeRaster(AWidth, AHeight);
LSurface.Canvas.Clear(TAlphaColors.Null);
ADrawProc(LSurface.Canvas, RectF(0, 0, AWidth, AHeight));
LSurface.MakeImageSnapshot.EncodeToFile('output.png');
end;
The code below demonstrate how to draw shapes:
DrawExample(256, 256,
procedure (const ACanvas: ISkCanvas; const ADest: TRectF)
begin
var LPaint: ISkPaint := TSkPaint.Create;
LPaint.AntiAlias := True;
LPaint.Color := $FF4285F4;
var LRect := TRectF.Create(PointF(10, 10), 100, 160);
ACanvas.DrawRect(LRect, LPaint);
var LOval: ISkRoundRect := TSkRoundRect.Create;
LOval.SetOval(LRect);
LOval.Offset(40, 80);
LPaint.Color := $FFDB4437;
ACanvas.DrawRoundRect(LOval, LPaint);
LPaint.Color := $FF0F9D58;
ACanvas.DrawCircle(180, 50, 25, LPaint);
LRect.Offset(80, 50);
LPaint.Color := $FFF4B400;
LPaint.Style := TSkPaintStyle.Stroke;
LPaint.StrokeWidth := 4;
ACanvas.DrawRoundRect(LRect, 10, 10, LPaint);
end);
This code results in the output below:
With Skia4Delphi it is possible to create PDF documents and draw anything on them, from text to images. The example below demonstrates how to create an PDF document and draw an SVG inside it:
var LSVGDOM := TSkSVGDOM.MakeFromFile('Samples\Demo\Assets\lion.svg');
var LSize := TSizeF.Create(600, 600);
LSVGDOM.SetContainerSize(LSize);
var LDocumentStream := TFileStream.Create('output.pdf', fmCreate);
try
var LDocument := TSkDocument.MakePDF(LDocumentStream);
try
var LCanvas := LDocument.BeginPage(LSize.Width, LSize.Height);
try
// Draw anything here with Skia canvas
LSVGDOM.Render(LCanvas);
finally
LDocument.EndPage;
end;
finally
LDocument.Close;
end;
finally
LDocumentStream.Free;
end;
This code results in the output below:
The Skia4Delphi library supports many image formats. See below the list:
Supported formats for decoding
Image Format | Extensions |
---|---|
Bitmap | .bmp |
GIF | .gif |
Icon | .ico |
JPEG | .jpg, .jpeg |
PNG | .png |
Raw Adobe DNG Digital Negative | .dng |
Raw Canon | .cr2 |
Raw Fujifilm RAF | .raf |
Raw Nikon | .nef, .nrw |
Raw Olympus ORF | .orf |
Raw Panasonic | .rw2 |
Raw Pentax PEF | .pef |
Raw Samsung SRW | .srw |
Raw Sony | .arw |
WBMP | .wbmp |
WebP | .webp |
Note: Raw images are limited to non-windows platforms
Supported formats for encoding
Image Format | Extensions |
---|---|
JPEG | .jpg, .jpeg |
PNG | .png |
WebP | .webp |
WebP is a modern image format that provides superior lossless and lossy compression for images. WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent quality.
The example below demonstrates how to encoder to WebP format:
var LImage := TSkImage.MakeFromEncodedFile('Samples\Demo\Assets\kung-fu-panda.png');
LImage.EncodeToFile('output.webp', TSkEncodedImageFormat.WEBP, 80);
LImage.EncodeToFile('output.jpg', TSkEncodedImageFormat.JPEG, 80);
This code results in the output below:
Format | Size |
---|---|
Png (100% quality) | 512 KB |
Jpeg (80% quality) | 65 KB |
WebP (80% quality) | 51 KB |
It is possible to edit TBitmap (VCL or FMX) with Skia's canvas using the code below:
uses
System.Skia, FMX.Skia {or Vcl.Skia};
...
var LBitmap := TBitmap.Create(100, 100);
try
LBitmap.SkiaDraw(
procedure (const ACanvas: ISkCanvas)
begin
// Draw with Skia canvas...
end);
The library registers the following codecs:
VCL: .svg, .webp, .wbmp and raw images (.arw, .cr2, .dng, .nef, .nrw, .orf, .raf, .rw2, .pef and .srw).
FMX: .bmp, .gif, .ico, .webp, .wbmp and raw images (.arw, .cr2, .dng, .nef, .nrw, .orf, .raf, .rw2, .pef and .srw).
As a result, any Delphi control, such as a TImage, can normally load these new formats automatically.
It is possible to replace the default Canvas from FMX to Skia based Canvas. Once this feature is enabled, all FMX controls will be painted internally using Skia4Delphi automatically. With that it is possible to improve the quality and performance of the drawings throughout the FMX app, as well as generating better integration with other library features.
Open the source of your Delphi Application Project (.dpr), include the FMX.Skia
unit right after the FMX.Forms
unit, and set the GlobalUseSkia
to True, as in the example below:
uses
System.StartUpCopy,
FMX.Forms,
FMX.Skia,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
GlobalUseSkia := True;
Application.Initialize;
...
FMX.Skia
unit must be included right after the FMX.Forms
;FMX.Types
unit right after the FMX.Forms
unit, and setting GlobalUseMetal
to True together with GlobalUseSkia
to improve the speed in iOS and macOS;FMX.Types
unit right after the FMX.Forms
unit, and setting GlobalUseVulkan
to True together with GlobalUseSkia
to improve the speed on Android and Windows. On Windows, Vulkan will only be used if you also add GlobalUseSkiaRasterWhenAvailable := False;
;GlobalUseSkia := True;
, as well as other variables of FMX itself, such as GlobalUseMetal
, can also be made in the initialization of some unit instead of .dpr. Sometimes this is really necessary because if in the initialization or in the class constructor of some unit, bitmaps are used, the GlobalUseXXX declarations of the .dpr will have no effect. In this case, just create a unit in the project like "Project.Startup.pas", place the GlobalUseXXX declarations in the initialization of this new unit, and declare this new unit before any other unit of yours in the .dpr, that is, right after FMX.Forms.The performance test is a simulation of a real application, with hundreds of controls, to measure the FPS rate when sliding a vertical scroll.
Device | Platform | FMX | Skia |
---|---|---|---|
Motorola Moto 3rd Generation | Android | 25 fps | 38 fps |
LG K40s | Android | 30 fps | 47 fps |
Samsung Galaxy A01 Core | Android | 20 fps | 26 fps |
Samsung Galaxy S7 Edge | Android64 | 53 fps | 56 fps |
Samsung Galaxy S8 Plus | Android64 | 50 fps | 55 fps |
Apple iPhone 11 | iOSDevice64 | 59 fps | 60 fps |
Apple iPhone 12 | iOSDevice64 | 59 fps | 59 fps |
Apple MacBook Air Model A2337 | OSXARM64 | 58 fps | 30 fps * |
Intel Core i7-8565U / Radeon 520 | Win32 | 82 fps | 92 fps |
Intel Core i7-8565U / Radeon 520 | Win64 | 83 fps | 91 fps |
Intel Core i7-4500U / GeForce GT 720M | Win32 | 85 fps | 92 fps |
Intel Core i7-4500U / GeForce GT 720M | Win64 | 86 fps | 93 fps |
Device | Platform | FMX | Skia |
---|---|---|---|
Apple iPhone 11 | iOSDevice64 | 59 fps | 60 fps |
Apple iPhone 12 | iOSDevice64 | 59 fps | 59 fps |
Apple MacBook Air Model A2337 | OSXARM64 | 60 fps | 60 fps |
Default FMX renderer does not use anti-aliasing on some platforms (like on mobile) while Skia Render uses it. That is, Skia has better performance and quality in the drawings than default FMX Render.
FMX default | FMX with Skia render |
---|---|
On macOS Skia4Delphi
's default renderer does not have GPU acceleration. Therefore, it is highly recommended to use Skia Metal (combining the activation of GlobalUseSkia
and GlobalUseMetal
), to get the full performance of the machine.
Tests made from virtual machines are inconsistent with reality.
Using Skia's Render, during the Scene of a Bitmap, Control or Form, it is possible to access the Skia canvas property as follows:
uses
System.Skia, FMX.Skia.Canvas;
begin
var LBitmap := TBitmap.Create(300, 300);
try
LBitmap.Canvas.BeginScene;
try
var LCanvas: ISkCanvas := TSkCanvasCustom(LBitmap.Canvas).Canvas;
// Draw using Skia canvas (LCanvas) directly to unlock new features...
finally
LBitmap.Canvas.EndScene;
end;
finally
LBitmap.Free;
end;
end;
type
TMyControl = class(TControl)
protected
procedure Paint; override;
end;
implementation
uses
System.Skia, FMX.Skia.Canvas;
procedure TMyControl.Paint;
begin
var LCanvas: ISkCanvas := TSkCanvasCustom(Canvas).Canvas;
// Draw using Skia canvas (LCanvas) directly to unlock new features...
end;
Canvas
property will only be available during Scene, that is, between the BeginScene
and EndScene
of the Bitmaps, and during paint events/methods for Controls and Forms (such as OnPaint, OnPainting, PaintChildren, among others);TBitmap
are thread safe.Using Skia's render, your application will now support Right-To-Left text rendering. But for that you will need to make 3 changes to your project:
Application.BiDiMode := TBiDiMode.bdRightToLeft;
, like below:program Project1;
uses
System.StartUpCopy,
FMX.Forms,
System.Classes,
FMX.Skia,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.BiDiMode := TBiDiMode.bdRightToLeft;
GlobalUseSkia := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
BiDiMode
of your forms to bdRightToLeft
;ControlType
property of these controls to Platform
.Using Skia's renderer, it is possible to use custom font in any FMX control, on any platform in a very simple way. Just register them in the app initialization:
program Project1;
uses
System.StartUpCopy,
FMX.Forms,
FMX.Skia,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
GlobalUseSkia := True;
TSkDefaultProviders.RegisterTypeface('Poppins.ttf');
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
On RAD Studio 12 Athens or newer it is recommended to use IFMXFontManagerService
:
program Project1;
uses
System.StartUpCopy,
FMX.Forms,
FMX.Platform,
FMX.FontManager,
FMX.Skia,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
GlobalUseSkia := True;
var LFontManager: IFMXFontManagerService;
if TPlatformServices.Current.SupportsPlatformService(IFMXFontManagerService, LFontManager) then
LFontManager.AddCustomFontFromFile('Poppins.ttf');
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
TSkAnimatedImage is the control that can load and render animated images, including vector animations, in a very simple way. The supported formats are:
Format | Extensions |
---|---|
Lottie file | .json, .lottie |
Telegram Sticker | .tgs |
Animated GIF | .gif |
Animated WebP | .webp |
The example below demonstrates how to play lottie files using TSkAnimatedImage:
var LAnimatedimage := TSkAnimatedImage.Create(Self);
LAnimatedimage.LoadFromFile('Samples\Demo\Assets\rocket.json');
LAnimatedimage.Parent := Self;
The example above results in the output below:
TSkLabel is the control that implements the SkParagraph internally, having several more features than the TLabel, such as:
TSkPaintBox is the ideal control for painting with Skia API directly on the canvas with the event OnDraw
:
procedure TForm1.SkPaintBox1Draw(ASender: TObject; const ACanvas: ISkCanvas;
const ADest: TRectF; const AOpacity: Single);
begin
var LPaint: ISkPaint := TSkPaint.Create;
LPaint.Shader := TSkShader.MakeGradientSweep(ADest.CenterPoint,
[$FFFCE68D, $FFF7CAA5, $FF2EBBC1, $FFFCE68D]);
ACanvas.DrawPaint(LPaint);
end;
The example above results in the output below:
Note: The TSkPaintBox has a drawing caching system. To force a drawing refresh, call TSkPaintBox.Redraw. However, this cache system does not exist in FMX apps that have enabled Skia4Delphi render for optimization reasons.
TSkSvg is the control to load and display SVG easily:
var LSvg := TSkSvg.Create(Self);
LSvg.Svg.Source := TFile.ReadAllText('Samples\Demo\Assets\panda.svg');
LSvg.Parent := Self;
The example above results in the output below:
RAD Studio | Platforms |
---|---|
RAD Studio 11 Alexandria or newer | All Platforms |
RAD Studio 10.3 Rio or newer | Windows, Android |
RAD Studio XE7 or newer | Windows |
For the platforms supported by Skia4Delphi (listed above), the OS versions supported by the library are the same OS versions that RAD Studio supports.
Due to certain constraints within the IDE, there are specific limitations and workarounds. This topic will be updated as soon as these limitations no longer exist
When the project settings are configured to generate a universal binary for macOS (also known as fat library), the internal process executed by MSBuild only applies the "lipo" tool to the application, without an option to merge files present in the deployment configurations. As a result, the binary for macOS ARM64 targets (known in the IDE as "OSXARM64") is universal, containing both x64 and ARM64 versions, even when the option to generate a universal project binary is disabled.
To submit a macOS application to the Apple Mac Store, it is necessary to sign all shared library files, and the deployment settings do not provide a method to sign files within them. In this case, follow the steps below for manual signing:
Transfer the Skia4Delphi shared library file to your macOS Desktop
(if the target is OSXARM64, use Binary\Shared\OSXARM64\libsk4d.dylib
. If it is OSX64, use Binary\Shared\OSX64\libsk4d.dylib
);
Access your macOS Desktop
via Terminal and run the following command:
security find-identity -v -p codesigning
The output will present information formatted roughly like XXXXX "Apple Development: YYYYY (ZZZZZ)". Use this information to execute the command below and sign the library:
codesign --force --timestamp --sign "Apple Development: YYYYY (ZZZZZ)" libsk4d.dylib
Replace the original Skia4Delphi file with the signed file, then perform the "Clean" and "Build" operation on your project.
The APIs are very similar to Skia's, few methods and functions have been renamed for readability, so the Skia documentation can be used.
Skia Version used: chrome/m107
Help us responding a small questionnaire about our users in this link