Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TImage and SKIA #197

Closed
kabiri opened this issue Jan 7, 2023 · 23 comments
Closed

TImage and SKIA #197

kabiri opened this issue Jan 7, 2023 · 23 comments

Comments

@kabiri
Copy link

kabiri commented Jan 7, 2023

I have three photos. My app displayed them correctly.
I used to download them from the internet as a stream and display them in TImage.
I just activated SKIA in Windows, there is no problem and it is displayed correctly. In Android and iPhone, the color of the photo changes.

Link to download photos :
https://cevahirsoft.com/flag/1.bmp
https://cevahirsoft.com/flag/3.bmp
https://cevahirsoft.com/flag/3.bmp

What the program displays:
photo_2023-01-07_18-15-02

@viniciusfbb
Copy link
Member

Are you using the latest version (4.0.2)? You can check your version in Skia.pas.

@kabiri
Copy link
Author

kabiri commented Jan 7, 2023

I download it today from getit

@viniciusfbb
Copy link
Member

@kabiri I tested here with Android64 + Delphi 11.2 + Skia Enabled, using the code:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects;

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses
  System.Net.HttpClient, System.Net.URLClient;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TURLStream.Create('https://cevahirsoft.com/flag/1.bmp',
    procedure (AStream: TStream)
    begin
      Image1.Bitmap.LoadFromStream(AStream);
    end);
end;

end.

And the result was correct:

image

Can you tell us more info, like your RAD Studio version. I really think that you are using an old version of the library. I'm not sure if Embarcadero continues to update the GetIt of RAD Studio versions prior to the lastest (Alexandria), so to be on the safe side, I recommend downloading the github setup instead of using the GetIt version, if you aren't in Delphi 11 Alexandria.
https://github.com/skia4delphi/skia4delphi/releases

@kabiri
Copy link
Author

kabiri commented Jan 10, 2023

i use Delphi 11 Alexandria.
i remove SKIA from getit and install it from your link,
But it is the same
I checked the SKIADIR variable and the path is correct.
Do I need to delete bpls manually?

@viniciusfbb
Copy link
Member

@kabiri Can you made a test? Just run the follow ShowMessage code:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses
  Skia;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowMessage(SkVersion);
end;

end.

@kabiri
Copy link
Author

kabiri commented Jan 10, 2023

OK
photo_2023-01-10_17-43-31

@viniciusfbb
Copy link
Member

@kabiri To help you I have to be able to simulate your problem, so I need more information. Your Alexandria is 11.2 or previous?Can you tell me the device model and OS version? Perhaps the problem is in the way you load the image, so it would be interesting for you to run the same code that I used to test it so that we can compare the results. #197 (comment)

@kabiri
Copy link
Author

kabiri commented Jan 10, 2023

I think I understand the problem.
when i create this file
`unit Project.Startup;

interface

implementation

end.

initialization
GlobalUseXXX;
GlobalUseSkia := True;`

and use it

uses
System.StartUpCopy,
FMX.Forms,
Skia.FMX,
Project.Startup in 'Project.Startup.pas',
....

Trouble happens

@viniciusfbb
Copy link
Member

@kabiri My test also set the GlobalUseSkia := True;, to enable the render replacement to the Skia, and it works here perfectly.
Can you test the simple project I created? TestBitmapColor.zip

@kabiri
Copy link
Author

kabiri commented Jan 10, 2023

@viniciusfbb this is my demo
Project.Startup.zip
skia1

@viniciusfbb
Copy link
Member

Again, it works fine here:

image

@viniciusfbb
Copy link
Member

Can you take a print of the entire Library Path of your IDE?

@kabiri
Copy link
Author

kabiri commented Jan 10, 2023

You mean that?
$(BDSLIB)$(PLATFORM)\Release;$(BDSCatalogRepository)\BossExperts-1.0\Source;$(BDSCatalogRepository)\DelphiEventBus-2.0\source;$(BDSCatalogRepository)\TFrameStand-1.8-11\Src\source;$(BASECMP)\UniDAC for RAD Studio 11\Lib\Android64;$(BASECMP)\Kastri\API;$(BASECMP)\Kastri\Controls;$(BASECMP)\Kastri\Core;$(BASECMP)\Kastri\Features\ADB;$(BASECMP)\Kastri\Features\AudioPlayer;$(BASECMP)\Kastri\Features\Barcode;$(BASECMP)\Kastri\Features\Biometric;$(BASECMP)\Kastri\Features\Camera;$(BASECMP)\Kastri\Features\Connectivity;$(BASECMP)\Kastri\Features\FilesSelector;$(BASECMP)\Kastri\Features\Firebase;$(BASECMP)\Kastri\Features\Geofence;$(BASECMP)\Kastri\Features\Location;$(BASECMP)\Kastri\Features\NFC;$(BASECMP)\Kastri\Features\Notifications;$(BASECMP)\Kastri\Features\Proximity;$(BASECMP)\Kastri\Features\ShareItems;$(BASECMP)\Kastri\Features\SMS;$(BASECMP)\Kastri\Features\SoundPlayer;$(BASECMP)\Kastri\Features\SpeechRecognition;$(BASECMP)\Kastri\Features\SymbolScanner;$(BASECMP)\Kastri\Features\UniversalLinks;$(BASECMP)\Kastri\Features\WebBroker;$(BASECMP)\Kastri\Include;$(BASECMP)\Playground\API;$(BASECMP)\Playground\Controls;$(BASECMP)\Playground\Core;$(BASECMP)\Playground\Features\AlertView;$(BASECMP)\Playground\Features\AppUpdate;$(BASECMP)\Playground\Features\Beacons;$(BASECMP)\Playground\Features\Location;$(BASECMP)\Playground\Features\MediaManager;$(BDSCatalogRepository)\BossExperts-1.0\Source;$(BASECMP)\RESTRequest4Delphi\src;$(BASECMP)\dataset-serialize\src;$(BASECMP)\RTLFixer\RTL-Packages\Source;$(BDSCatalogRepository)\GLibWMI-3.1\sources;$(BASECMP)\woll2woll\firepower\14.0\source;$(BASECMP)\GBg Shamsi date 2;$(BASECMP)\ZigShamsiPicker;$(BASECMP)\JVEsuite;$(BASECMP)\ZigControlAutoMover;$(BASECMP)\Kastri\Features\TextToSpeech;$(BDSCatalogRepository)\DelphiEventBus-2.0\source;$(BASECMP)\Kastri\Include;$(BASECMP)\UniDAC for RAD Studio 11\Lib\Android64;$(BASECMP)\alcinoe\source;$(BASECMP)\sgcWebSockets professional\libD11$(Platform);$(BASECMP)\Kastri\Features\AdMob;$(BDSCatalogRepository)\SVGIconImageList-11-3.9.3\source;$(BDSCatalogRepository)\SVGIconImageList-11-3.9.3\Image32\source;$(BDSCatalogRepository)\SynEdit-11\source;$(BDSCatalogRepository)\SynEdit-11\source\Highlighters;$(BDSCatalogRepository)\MobilePermissions\Source;$(BASECMP)\Steema TeeChart Pro VCL FMX Source Code 2021.33\Compiled\Delphi28.android64\Lib;$(SKIADIR)\Source;$(SKIADIR)\Source\FMX

when i use Project.Startup :
photo_2023-01-10_20-51-02

when i don't use Project.Startup :
photo_2023-01-10_20-50-55

@viniciusfbb
Copy link
Member

I finally simulate the problem.

image

It's occurs when you use the Skia but without it render (i.e, without the GlobalUseSkia := True;) and you use an image format provided by skia library (we only register image decoders that the FMX doesn't support, like bmp, gif, webp, ico...). Now, we will fix it, but as workaround, you can just enable our render (it will not work with alcinoe), or you can also replace the image format to PNG or JPG, to avoid the Skia codecs.

@Spelt
Copy link

Spelt commented Jan 11, 2023 via email

@viniciusfbb
Copy link
Member

viniciusfbb commented Jan 11, 2023

As a maybe related question. What do you mean it does not work with Alcinoe because: I'm using the Alicinoe vertical listbox with the Skia enabled and with the TSkAnimated image which works great.

@Spelt Alcinoe is one of the few libraries that are not compatible with Skia's renderer, that is, with GlobalUseSkia := True; on mobile, because in several units it makes TCanvas hardcasts, like TGPUCanvas(ACanvas).xxx , and since our renderer registers our own TCanvas, hardcasting it into the default canvas will give an AV. I reported this to them issue 235 (Compatible with custom Canvas) and from what I've seen in recent changes @Zeus64 is adapting the code to support custom canvas. Maybe you don't have a problem, because the part of the code you use doesn't do this hardcast, or you're only using it on Windows, or you're only using Skia4Delphi controls, without the renderer enabled.

@kabiri
Copy link
Author

kabiri commented Jan 11, 2023

Of course I use GlobalUseSkia := True; I have set it in the Project.Startup.pas file. Because in the main program (the demo I uploaded was not like that) it was saying that the canvas service was already running, that's why I used this method.
Unfortunately, I could not use alcinoe, and only its path was added to Delphi.

@Zeus64
Copy link

Zeus64 commented Jan 11, 2023

I think it's little more complicate than this. To be able to create bitmap in background thread, In alcinoe we use TTexture instead of TBitmap and we use directly the OS API (on Android/iOS) to create the bitmap. TTexture work under OpenGL and for this we must work with the TGPUCanvas. Of course we can maybe swap all of this to skia, but I doubt that in skia we can work with Tbitmap in background thread but need to check

@Spelt
Copy link

Spelt commented Jan 11, 2023 via email

@viniciusfbb
Copy link
Member

I think it's little more complicate than this. To be able to create bitmap in background thread, In alcinoe we use TTexture instead of TBitmap and we use directly the OS API (on Android/iOS) to create the bitmap. TTexture work under OpenGL and for this we must work with the TGPUCanvas. Of course we can maybe swap all of this to skia, but I doubt that in skia we can work with Tbitmap in background thread but need to check

@Zeus64 Thanks for considering this!

TBitmap with or without Skia already supports drawing in background thread normally (there is only one or two issue, related to the fact that System.Messaging is not thread safe and TCanvas.Destroy and TTextLayout use the same, but it is extremely rare this type of error occurs). TBitmap's limitation for background thread drawing is that it is not done in a really parallel way, as TCanvas has a lock that locks all others (including the UI) to make drawings between BeginScene and EndScene, and this is a limitation of FMX, and even enabling Skia, nothing changes about it.

However, it is possible to draw images in the background thread using only the Skia APIs, to don't lock the rendering, and then convert the resulting SkImage to a TBitmap, or even directly paint the resulting SkImage on the canvas, if it is of the TSkCanvasCustom type .

In case you choose to draw using the Skia APIs, we can make something that facilitates this (on the Skia4Delphi side). A TSkFMXCanvasWrapper class that would be a TCanvas that would encapsulate a desired SkCanvas, and then every part of the drawing would be done by drawing on a TCanvas, without Skia APIs.

There are several possibilities.

@viniciusfbb
Copy link
Member

@kabiri If you choose the 'replace .bmp format to .png or .jpg' workaround, it might only work if you add GlobalDisableSkiaCodecsReplacement := True;

@kabiri
Copy link
Author

kabiri commented Jan 11, 2023

@viniciusfbb i change bmp to png and set GlobalDisableSkiaCodecsReplacement := True;
The problem is solved for now.
Thanks

@viniciusfbb
Copy link
Member

Fixed in last release (v4.1.0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: Done
Development

No branches or pull requests

5 participants