Поскольку телефоны Android выпускаются с различными разрешениями экрана, а мой пользовательский интерфейс "очищен" с помощью нескольких компонентов TImage, я столкнулся с серьезной проблемой разработки, поэтому я должен масштабировать каждое из моих изображений относительно разрешения экрана устройства.
По какой-то причине, которую я не могу понять, в Android TImage интерполируется с использованием действительно низкого качества скейлера (возможно, ближайшего соседа), что приводит к отображению изображения очень низкого качества (это происходит, даже если учитывается масштаб экрана и качество формы установлено на высоком уровне).
Из-за этого это означает, что я могу либо предварительно масштабировать и включать несколько разных разрешений одного и того же изображения, надеясь, что оно будет выглядеть "достаточно близко" (и раздувая мое приложение), либо я могу использовать программный алгоритм для масштабирования изображений в в режиме реального времени, а затем кэшировать результат для последующих запусков.
Я выбираю второй вариант, используя программный бикубический масштабатор, но проблема в том, что мое приложение имеет так много графических ресурсов, что может потребоваться 18 секунд для первой загрузки на мобильное устройство высокого класса.
Я знаю, что возможно сделать то, что мне нужно в аппаратном обеспечении, используя OpenGL, но я не смог найти ясный/чистый пример того, как это можно сделать в Delphi для Android. И даже если это можно сделать без перекодировки всего пользовательского интерфейса для OpenGL.
Есть что-то, чего мне не хватает в дизайне? Является ли починка от Embarcadero моим единственным шансом?
Мне потребовалось некоторое время, чтобы заблокировать это, но вот собственный код Android, который будет масштабировать изображение с высоким качеством намного быстрее, чем любое чистое программное решение, которое я мог найти и оптимизировать:
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;