2017-05-09 1 views
2

J'essaie d'afficher 1px lignes fines dans une application Android, mais le cadre FMX se comporte étrangement: Les lignes sont souvent dessinées un peu flou, ce qui peut être vu sur l'écran. Même sur un écran à haute résolution (testé sur un Ascend Mate 7, qui a un FullHD 1080x1920 sur un écran de 16 pouces), il est perceptible. Peu importe si j'utilise un composant, comme un TLine ou TRectangle (sans côtés - juste Height = 1) ou si je dessine une ligne moi-même sur un canevas (par exemple avec Canvas.Stroke.Thickness := 1.0 et Canvas.DrawLine()). La compilation en tant qu'application Windows montre correctement les lignes 1px, mais sur Android, les lignes sont dessinées en 2px ou parfois en 3px. Parfois quelque chose entre, comme une ligne pleine et une seconde ligne transparente.FireMonkey dessine des lignes floues

Il est également étrange que l'épaisseur de ligne tracée semble changer lors du défilement de la vue (au moment de l'exécution) qui contient les lignes. La définition de l'épaisseur en dessous de la valeur 1.0 permet de dessiner des lignes comme 1px, mais les lignes elles-mêmes deviennent transparentes. Peu importe ce que j'essaie - je ne peux pas créer une solide ligne noire complètement opaque de 1px. Et les problèmes ci-dessus (par exemple lors du défilement) persistent toujours. Changement TForm.Quality n'aide pas non plus. Les applications Android natives ne semblent pas avoir de problèmes pour tracer des lignes fines.

Voici un natif des captures d'écran (zoom pour mesurer l'épaisseur de ligne):

enter image description here

J'ai essayé quelques suggestions, comme "en mouvement" les lignes: http://sourceoddity.com/blog/2013/10/using-tcanvas-in-delphi-for-android/. Cela aide un peu à enlever le flou, mais les lignes sont toujours dessinées avec plus de 1px et je voudrais résoudre le problème en un seul endroit (je ne peux pas réécrire/redessiner toutes les centaines de composants dans le cadre).

Voici l'exemple de projet de la capture d'écran ci-dessus: https://www.dropbox.com/s/le70jf601axd1xf/example.zip?dl=1

Je l'ai testé cela avec la version 10.1 (Berlin), mais ce comportement étrange est survenue dans les versions précédentes aussi (aussi longtemps que je me souviens).

+0

[Cette question/réponse] (http: // stackoverflow.com/a/35113937/2292722) parle de 1 px de large pointillé, mais je rappelle qu'il en est de même pour les lignes continues de 1 px, compensant la fin de la ligne avec 0.5 px conduisant à un rendu de lignes horizontales et verticales de 1 px . –

+0

J'ai déjà essayé cette approche (le lien vers le blog dans mon texte ci-dessus). Cela aide à éliminer le flou, mais il y a toujours le problème de mise à l'échelle. Je commence à réaliser, que firemonkey semble appliquer la mise à l'échelle du système Android. Sur mon Huawei Ascend Mate 7, j'ai dans les paramètres d'affichage la possibilité de changer le mode d'affichage (mise à l'échelle): petit, moyen (par défaut), grand. 'GetWindowScale()' de 'TPlatformServices.Current.GetPlatformService (IFMXWindowService) comme IFMXWindowService' me donne les valeurs suivantes: 2.5 (petit), 2.75 (milieu), 3 (grand). Je peux me tromper avec cela, mais je pense que cela pourrait être le problème ... – StanE

+0

... ce qui signifie que le problème réside plus profondément dans le cadre FMX. Il est logique d'adapter l'application en fonction de la mise à l'échelle du système. Mais si chaque appareil a une échelle différente et surtout utilise des fractions, alors je pense que je comprends pourquoi cela pourrait arriver. Le framework FMX pourrait-il avoir un problème avec le rendu/antialiasing, s'il utilise des échelles comme 2.75 pour mettre à l'échelle l'application entière? Est-il possible de désactiver la mise à l'échelle (si c'est vraiment le problème)? – StanE

Répondre

0

Sur android, vous devez prendre plusieurs penser en compte. D'abord leur pixel réel et pixel virtuel (pixel réel = pixel x échelle virtuelle). Cela signifie que lorsque vous demandez de dessiner une ligne 1px sur un périphérique XXhdpi (avec échelle = 3), vous aurez une ligne de 3px qui sera dessinée. Bien sûr, cela ne résulte en ligne blured, sauf si l'échelle est par exemple 1,5

La deuxième chose, connecté à la première, si c'est vous ne commencez pas à vous tracer une ligne sur un vrai pixel. sur Android pos est un seul, de sorte que vous pouvez dessiner une ligne partout, même au milieu d'un vrai pixel. de cette façon, bien sûr, le système commencera à brouiller la ligne pour l'amener du milieu d'un pixel au milieu d'un autre pixel (car il ne peut pas dessiner seulement la moitié d'un pixel). pour éviter cela, utilisez toujours la fonction Canvas alignToPixel.

l'autre pense que vous devez prendre en compte est que le cadre firemonkey utilise un paramètre laid: form.quality. Lorsque vous l'installez à haute qualité, l'opengl utilisé par Firemonkey sera configuré pour tout filtrer (y compris la ligne simple), entraînant un flou. pour l'enlever, vous pouvez le configurer à la normale, mais de cette façon ronde coin/cercle sera absolument moche sur l'appareil avec un rapport d'échelle de 1.

l'option que je choisis personnellement est de rester sur la forme.quality = faible (non anti aliasé) et dessine tout (y compris la ligne, rectangle, etc) moi-même en utilisant l'api android. Vous pouvez jeter un oeil à ce svn: https://svn.code.sf.net/p/alcinoe/code/ ou si vous voulez voir directement charger dans Android cette démo: https://svn.code.sf.net/p/alcinoe/code/demos/ALFmxControls/Android/Release/ALFmxControls/bin/ALFmxControls.apk