I have an issue with FMX on Android not showing images correctly.
My app, which is my first ever for Android, has a background and a splash image that are shown upon app start. The splash shows on top of everything, and then a timer makes it go away, and show the background.
Screenshot from Memu emulator:
Screenshot from my phone:
Source from replicated issue:
http://anbech.me/bgtest/bg_test.zip
I've been coding Pascal since Delphi 6, and I never asked about any coding related issues before this, but this is very new to me.
So far, I've been trying for 3 days to get it working, but without luck.
Currently I'm using RCDATA resources and loading images from there. I tried to even have the images on a different form, as other TImage components, and load from there. I also notice that if the images are set to Align=Client, and WrapMode=Center, then they all get misplaced on the MainForm, but work great on other forms. So now, I tried cropping the images, which are squares, so they'll have the same aspect ratio as the device it runs on.
I could go on, because what I've tried so far is a long talk.
procedure TForm1.FormShow(Sender: TObject);
var
Bmp, BmpSplash: TBitmap;
iRect: TRect;
begin
Load_image_from_resource(Form1.Image_bg, '0_bg');
Load_image_from_resource(Form1.Image_splash, '0_splash');
Bmp := TBitmap.Create;
try
Bmp.Width := round(Form1.Image_bg.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
Bmp.Height := round(Form1.Image_bg.Bitmap.Height);
iRect.Width := round(Form1.Image_bg.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
iRect.Height := Bmp.Height;
iRect.Left := round((iRect.Height - iRect.Width) / 2);
iRect.Top := 0;
Bmp.CopyFromBitmap(Form1.Image_bg.Bitmap, iRect, 0, 0);
//Form1.Image_bg.Bitmap := nil;
Form1.Image_bg.Bitmap.Assign(Bmp);
Form1.Image_bg.Align := TAlignLayout.Client;
Form1.Image_bg.WrapMode := TImageWrapMode.Stretch;
finally
Bmp.DisposeOf;
Bmp := nil;
end;
BmpSplash := TBitmap.Create;
try
BmpSplash.Width := round(Form1.Image_splash.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
BmpSplash.Height := round(Form1.Image_splash.Bitmap.Height);
iRect.Width := round(Form1.Image_splash.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
iRect.Height := Bmp.Height;
iRect.Left := round((iRect.Height - iRect.Width) / 2);
iRect.Top := 0;
BmpSplash.CopyFromBitmap(Form1.Image_splash.Bitmap, iRect, 0, 0);
//Form1.Image_splash.Bitmap := nil;
Form1.Image_splash.Bitmap.Assign(BmpSplash);
Form1.Image_splash.Align := TAlignLayout.Client;
Form1.Image_splash.WrapMode := TImageWrapMode.Stretch;
finally
BmpSplash.DisposeOf;
BmpSplash := nil;
end;
Form1.Image_bg.SendToBack;
Form1.Image_bg.Visible := False;
Form1.Image_splash.BringToFront;
Form1.Image_splash.Visible := True;
Form1.Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Form1.Timer1.Enabled := False;
Form1.Image_bg.Visible := True;
Form1.Image_splash.Visible := False;
end;


You were quite close, I think the following peculiarity in the Delphi code probably gave you most headache:
In your code you have something like this:
A
TRect(orTRectF) is determined by its four properties:Left, Top, Right, Bottom. When you change the dimensions usingwidth(andheight), you call this setter procedure:SetHeightis very similar.When you change
LeftorTopthe corresponding fields are simply changed, but notRightnorBottom. The result is that thewidthorheightalso changes.Imagine a local uninitialized variable
iRect, that might have whatever values forLeftandRight. Your code above may end up with very strangeTRectrectangles. The fix is to setLeftandTopproperties first, then eitherRightandToporWidthandHeight.To show the image, you required it to follow aspect ratio, which means that slices need to be cut away from the sides of the image when showing it vertically (and from top and bottom when showing it horizontally). I made this with
iRectso that it is initialized to the size of the screen, and then offset with half the difference between screen size and image size.Here is code to show the image according to screen size. Here is only vertical display, but horizontal would follow same scheme. For brevity I also did not include the splash image, use the same code and your own change logic. The comments in the code should explain my toughts. As you see it is largely very similar as yours, your calculations of
iRect.WidthandiRect.Leftwere not right, probably because of theTRectpeculiarity.