Rollo62 536 Posted August 9, 2023 (edited) Hi there, recently I've got some insights, about the internal TBitmap magic in FMX, for the following code snippet, under Android: procedure TTestForm.SaveImageToTemporaryStore( const AImage : TBitmap; const AArrayList : JArrayList; const AIndex : Integer ); var LImageFile : JFile; LImageUri : Jnet_Uri; LOutputDir : JFile; LPath : String; begin // Retrieves the apps cache, temporary file storage folder LOutputDir := TAndroidHelper.Context.getExternalCacheDir(); // Creates a temporary file in that cache folder LImageFile := TJFile.JavaClass.createTempFile( StringToJString( 'attachment' + AIndex.ToString ), StringToJString( '.png' ), //<== This is the only palce where png comes into play LOutputDir ); // Get that file as URI LImageUri := TAndroidHelper.JFileToJURI( LImageFile ); // Retrieve that path, for testing purposes, it looks like this: // '/storage/emulated/0/Android/data/com.embarcadero.APPNAMEHERE/cache/attachment05833119307942135994.png' LPath := JStringToString( LImageFile.getAbsolutePath ); // Save the TBitmap to that IRI file Path, works pretty well AImage.SaveToFile( LPath ); That works well and all as expected. When I send that file via sharesheet then after, also that works fine. // If we use ACTION_SEND_MULTIPLE action of Intent, we should put image throught Parcelable Array List. // Because in this case other application read EXTRA_STREAM like a ArrayList<Uri> // Created externally by LArrayList := TJArrayList.Create; AArrayList.add( LImageUri ); end; Then finally this is added to an Intent, to share to other apps. That works well, put it as below into the Intent as EXTRA_STREAM, it sends the .png file via different apps: LIntent.putParcelableArrayListExtra( TJIntent.JavaClass.EXTRA_STREAM, LArrayList ); So all works well and I should not complain. But it struck my, when I asked myself: Why does the source TBitmap converts to a *.png file in the first place ? Why didn't I had to fumble around with TBitmapCodecManager or something else, to get this conversion coded ? After some investigation, looking into the TBitmap.SaveToFile( LPath ); I found that the trick, by hidden conversion, depending on the file extension: procedure TBitmap.SaveToFile(const AFileName: string; const SaveParams: PBitmapCodecSaveParams = nil); var Surf: TBitmapSurface; begin TMonitor.Enter(Self); try Surf := TBitmapSurface.Create; try Surf.Assign(Self); if not TBitmapCodecManager.SaveToFile(AFileName, Surf, SaveParams) then raise EBitmapSavingFailed.CreateFMT(SBitmapSavingFailedNamed, [AFileName]); finally Surf.Free; end; finally TMonitor.Exit(Self); end; end; Sometimes, I'm still surprised by the hidden convenience that Firemonkey provides for us. Under VCL I would have to convert this image the hard way by myself, for example with TPNGImage, like PeterBelow pointer out here. I'm always happy when FMX made me forget such nasty details Edited August 9, 2023 by Rollo62 Share this post Link to post