1
votes

Since Android phones are released in many different screen resolutions and my user interface is "skinned" using multiple TImage components, I've hit a major development issue, I must scale each of my images relative to the device's screen resolution.

For some reason which I can not understand, under Android, TImage is interpolated using a really low quality scaler (possibly nearest-neighbor), resulting in a very low quality image display (this happens even when the screen scale is taken into consideration and the form's quality is set the high).

Due to this, it means I can either pre-scale and include multiple different resolutions of the same image, hoping that it will look 'close enough' (and bloating my app), or I can use a software algorithm to scale the images in real-time and then cache the result for later runs.

I choose the second option, using a software bicubic scaler, but the problem is that my app has so many image resources, it can take 18 seconds to load the first time on a high end mobile device.

I'm aware it may be possible to do what I need in hardware using OpenGL, but I haven't been able to find a clear/clean example of how this can be done in Delphi for Android. And even if it can be done without having to re-code the entire UI for OpenGL.

Is there something I'm missing design wise? Is a fix from Embarcadero my only chance?

1
Scale the images on demand so that you don't take that 18s hit in one go. And look for more efficient scaling code.David Heffernan
The standard way to go is to provide images of different sizes. I think you should use TImageList, load the images and then use Glyph or TImage with manual assignment of the imageJohn Kouraklis
I would not be at all surprised if there weren't software libraries that were much more efficient that the code you wrote. I mean, it's possible to write efficient code without resorting to assembler. Often algo choice and implementation are very important. Perhaps you have written optimal code, but perhaps not.David Heffernan
"under Android, TImage is interpolated using a really low quality scaler" I cannot reproduce that. There is almost zero information here that could help us in giving you some answers. How large images you have, how are you scaling them from which size to which size, code you use, Android API, do you see problem on multiple devices... anything. No matter what the real issue here is, writing your own scaling algorithm on Android is completely wrong solution.Dalija Prasnikar
This question is basically the duplicate of your last one. And has even less information. Your last question is also bad one, because there is also no information about what exactly are you doing. That is also why you didn't get appropriate answers. This is also why you will not get appropriate answer on this question.Dalija Prasnikar

1 Answers

1
votes

It took me a while to lock this down, but here is Android native code that will scale the image in high quality much faster than any pure software solution I could find and optimize:

uses Androidapi.JNI.Media, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNIBridge, FMX.Surfaces, FMX.Helpers.Android;

procedure AndroidResizeBitmap(srcBitmap,dstBitmap : TBitmap);
var
  sJBitmap     : JBitmap;
  ScaledBitmap : JBitmap;
  sSurface     : TBitmapSurface;
begin
  sSurface     := TBitmapSurface.Create;
  sSurface.Assign(srcBitmap);
  sJBitmap     := TJBitmap.JavaClass.createBitmap(sSurface.Width,   sSurface.Height,TJBitmap_Config.JavaClass.ARGB_8888);
  SurfaceToJBitmap(sSurface, sJBitmap);
  ScaledBitmap := TJBitmap.JavaClass.createScaledBitmap(sJBitmap,   dstBitmap.Width, dstBitmap.Height, True);
  sJBitmap     := nil;
  JBitmapToSurface(ScaledBitmap,sSurface);
  ScaledBitmap := nil;
  dstBitmap.Assign(sSurface);
  sSurface.Free;
  sSurface     := nil;
end;