使用 TImage 时 Android 下的低质量 delphi 用户界面设计
Low quality delphi user interface design under Android when using TImage
由于 Android 手机以多种不同的屏幕分辨率发布并且我的用户界面是 "skinned" 使用多个 TImage 组件,我遇到了一个主要的开发问题,我必须缩放我的每个图像相对于设备的屏幕分辨率。
由于某些我无法理解的原因,在 Android 下,TImage 使用非常低质量的缩放器(可能是最近邻)进行插值,导致图像显示质量非常低(即使在考虑了屏幕比例并将表单的质量设置为高)。
因此,这意味着我可以预先缩放并包含同一图像的多个不同分辨率,希望它看起来 'close enough'(并使我的应用程序膨胀),或者我可以使用软件实时缩放图像然后缓存结果以供以后运行的算法。
我选择第二个选项,使用软件双三次缩放器,但问题是我的应用程序有太多图像资源,在高端移动设备上第一次加载可能需要 18 秒。
我知道可以使用 OpenGL 在硬件中完成我需要的操作,但我无法找到 clear/clean 如何在 [=30= 中完成此操作的示例] 对于 Android。即使无需为 OpenGL 重新编码整个 UI。
我在设计方面有什么遗漏吗?
来自 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;
由于 Android 手机以多种不同的屏幕分辨率发布并且我的用户界面是 "skinned" 使用多个 TImage 组件,我遇到了一个主要的开发问题,我必须缩放我的每个图像相对于设备的屏幕分辨率。
由于某些我无法理解的原因,在 Android 下,TImage 使用非常低质量的缩放器(可能是最近邻)进行插值,导致图像显示质量非常低(即使在考虑了屏幕比例并将表单的质量设置为高)。
因此,这意味着我可以预先缩放并包含同一图像的多个不同分辨率,希望它看起来 'close enough'(并使我的应用程序膨胀),或者我可以使用软件实时缩放图像然后缓存结果以供以后运行的算法。
我选择第二个选项,使用软件双三次缩放器,但问题是我的应用程序有太多图像资源,在高端移动设备上第一次加载可能需要 18 秒。
我知道可以使用 OpenGL 在硬件中完成我需要的操作,但我无法找到 clear/clean 如何在 [=30= 中完成此操作的示例] 对于 Android。即使无需为 OpenGL 重新编码整个 UI。
我在设计方面有什么遗漏吗? 来自 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;