Fresco: Faible qualité d'image en utilisant<image/> composante sur RN &gt; = 0.57 (Fresque &gt;= 1.10.0)

Créé le 22 août 2019  ·  57Commentaires  ·  Source: facebook/fresco

La description

Problème RN :

La qualité est faible lors du chargement de grandes images groupées (PNG, GIF et peut-être plus de formats, PAS JPEG ) uniquement sur Android :

Sur la capture d'écran de gauche, nous voyons exactement le même code exécuté avec RN 0.56.0 et sur la capture d'écran de droite, nous voyons RN 0.57.1 . Le code est juste une simple image <Image source={require('./assets/ELHall1.png')} resizeMethod="resize" /> et la taille de l'image est 2111 x 4645 pixels . Les deux projets sont fraîchement installés à l'aide de react-native init RN057ImageTest et react-native init --version="0.56.0" RN056ImageTest . Cela continue de se produire à partir de 0.56 et de toutes les versions postérieures à la dernière RN 0.60.x.

Il est confirmé que cela est causé par le changement de la bibliothèque RN Fresco entre 0,56 et 0,57 de 1.9.0 à 1.10.0 https://github.com/facebook/react-native/commit/b6f2aad9c0119d11e52978ff3fa9c6f269f04a14. Vérifiez le commentaire https://github.com/facebook/react-native/issues/21301#issuecomment-520155609.

Après quelques recherches sur les problèmes de Fresco, je peux voir des problèmes connexes selon lesquels il est suggéré que les grandes images doivent être divisées et recomposées pièce par pièce, ce qui résout de nombreux cas (la plupart des grandes images liées à la carte) mais cela peut être très gênant, en particulier pour les charges dynamiques /créé des images. Cela fonctionnait jusqu'à la RN 0.56 et à partir de 0.57 et après cela ne fonctionne plus.

la reproduction

RN : C'est le App.js initial avec un composant <Image/> ajouté.

...
type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Image source={require('./assets/ELHall1.png')} resizeMethod="resize" />
      </View>
    );
  }
}
...

Information additionnelle

Dans ce commentaire https://github.com/facebook/react-native/issues/21301#issuecomment-520418832, lambdapioneer écrit que cela est peut-être lié à la réduction (sous-échantillonnage) des grandes images :

Je suppose que cela est lié à la façon dont Fresco réduit (sous-échantillonnage) les grandes images (ce qui est une caractéristique importante pour les problèmes de mémoire et de performances). Il y a eu quelques changements dans ces domaines au cours de cette période, principalement pour supprimer les dépendances du code natif afin de réduire les erreurs de lien .so insatisfaites également pressantes. Pour ainsi dire : cela pourrait être un effet secondaire d'une autre grande amélioration.

  • Version fresque : >= 1.10.0
  • Version de la plate-forme : RN >= 0,57, toutes les versions d'Android
enhancement

Commentaire le plus utile

@CaptainN ce n'est pas impoli. Le fait est que je l'ai fait et que j'ai résolu toutes les erreurs, il me faudra donc beaucoup moins de temps pour créer un référentiel de démarrage avec des instructions sur la façon d'installer et de corriger Fresco.

Alors voilà : https://github.com/clytras/RN061FrescoBuild

Il a RN 0.61.5 . Le dépôt contient des instructions détaillées. Il clone Fresco, extrait v2.1.0 et applique un correctif à DecodeProducer.java afin de commenter le code de sous-échantillonnage. Vous n'avez qu'à télécharger le NDK Android et ajouter un fichier libraries/fresco/local.properties . Tout est détaillé dans le readme.

Vous pouvez ajouter Fresco lib à un projet RN existant >= 0.60 (_ou versions antérieures_) si vous suivez les instructions et les scripts de fil.

Tous les 57 commentaires

Salut, il semble qu'il n'y ait eu aucune activité sur ce problème récemment. Le problème a-t-il été résolu ou nécessite-t-il toujours l'attention de la communauté ? Ce problème peut être fermé si aucune autre activité ne se produit. Vous pouvez également étiqueter ce problème comme "bug" ou "amélioration" et je le laisserai ouvert. Merci pour vos contributions.

Quelles versions de Fresco sont utilisées par les RN 0.56.0 et 0.57.1 ? Cela réduit le nombre de commits qui pourraient avoir causé cela.

Bonjour @oprisnik ,

Je vérifierai et verrai exactement dans quelle version le correctif a obtenu la mise à niveau lorsque je retournerai à mon bureau, bien que je pense que https://github.com/facebook/react-native/issues/21301#issuecomment -520155609 rapporte exactement à partir de quelle version a obtenu ce changement de comportement.

Salut @clytras , j'ai trouvé l'image à l'écran dans ce référentiel .
Je télécharge l'image et trouve que l'image est 2111 (largeur) * 4645 (hauteur).

Fresco sous-échantillonnera une image pour s'adapter à la limite OpenGL, la largeur/hauteur maximale de l'image par défaut est le code en dur dans cette ligne .

À mon avis,
Le moyen le plus simple consiste à modifier le champ maxBitmapSize d'un ResizeOption.
La bonne façon est de ne pas utiliser Fresco pour afficher une TRÈS grande image.

Créez un autre widget et utilisez cette bibliothèque pour afficher une TRÈS grande image est le choix de nombreuses équipes Android.

Salut @s1rius , j'écris la taille de l'image précisément si vous lisez le post du problème ouvert :

Le code n'est qu'une simple image et la taille de l'image est de 2111 x 4645 pixels

Il s'agit d'un changement de comportement qui s'est produit de RN >= 0.57 qui est passé de Fresco 1.9.0 à 1.10.0. De grandes images comme celle-ci fonctionnaient et se chargeaient en pleine qualité avant cette version. Les contributeurs de RN repo ont fermé le problème car ils déclarent qu'il ne s'agit pas d'un problème de RN mais d'un problème de Fresco lib. Si ce changement de comportement est intentionnellement effectué, nous pouvons alors clore ce problème. Oui, il existe des solutions de contournement, mais c'est que cela fonctionnait jusqu'à une version et soudainement, et sans aucune information sur la raison, a cessé de fonctionner.

Salut, il semble qu'il n'y ait eu aucune activité sur ce problème récemment. Le problème a-t-il été résolu ou nécessite-t-il toujours l'attention de la communauté ? Ce problème peut être fermé si aucune autre activité ne se produit. Vous pouvez également étiqueter ce problème comme "bug" ou "amélioration" et je le laisserai ouvert. Merci pour vos contributions.

Fermeture de ce problème après une période d'inactivité prolongée. Si ce problème est toujours présent dans la dernière version, n'hésitez pas à rouvrir avec des informations à jour.

Un changement potentiel qui aurait pu causer cela est https://github.com/facebook/fresco/commit/fa71901055a38a810c190862c7fd582fd3dad2b3

Pouvez-vous vérifier s'il s'agit du changement incriminé ?

Re- bonjour

Je ne suis pas très familier avec gradle et comment je peux changer RN pour compiler la fresque directement à partir de la source au lieu de télécharger la bibliothèque. Mesures que j'ai prises sans succès :

  1. Créez un projet RN 0.57 en utilisant react-native-cli
  2. Cloner fresco lib dans le répertoire racine du projet
  3. Caisse à la succursale v1.10.0 intérieur de la bibliothèque de fresques
  4. Ajouter android-ndk-r20 chemin à <Project>\android\local.properties ( ndk.dir=G:\\Dev\\Android\\android-ndk-r20 )

Ensuite, j'ai trouvé cette réponse sur SO https://stackoverflow.com/a/52861379/1889685 qui compile RN avec fresque à partir de la source et remplace la bibliothèque :

cd android
./gradlew assembleDebug --include-build /e/Sandbox/RN057ImageTest/fresco/

mais j'obtiens l'erreur suivante :

> Task :fresco:imagepipeline:ndk_build_bitmaps FAILED
A problem was found with the configuration of task ':fresco:imagepipeline:ndk_build_bitmaps'. Registering invalid inputs and outputs via TaskInputs and TaskOutputs methods has been deprecated and is scheduled to be removed in Gradle 5.0.
 - File 'E:\Sandbox\RN057ImageTest\fresco\imagepipeline\src\main\jni\bitmaps' specified for property '$1' is not a file.

Peut-être que @sunnylqm peut tester cela s'il a un peu de temps, car il est beaucoup plus familier avec ce processus.

Si cela peut aider, je peux créer un dépôt avec ce que j'ai jusqu'à présent.

Salut, il semble qu'il n'y ait eu aucune activité sur ce problème récemment. Le problème a-t-il été résolu ou nécessite-t-il toujours l'attention de la communauté ? Ce problème peut être fermé si aucune autre activité ne se produit. Vous pouvez également étiqueter ce problème comme "bug" ou "amélioration" et je le laisserai ouvert. Merci pour vos contributions.

J'ai essayé de construire mais j'ai également eu l'erreur ndk. Avez-vous des versions nocturnes sur lesquelles nous pouvons tester ?

Comme je peux compiler la v2.0.0 sans aucune modification, j'ai essayé un autre moyen de vérifier. J'ai désactivé le sous- échantillonnage qui est activé par le commit ci -

uri de l'image de test :
" https://wagonsclub.oss-cn-beijing.aliyuncs.com/static/carousel/carousel1_bg.jpg "

fragment_drawee_simple.xml

  <com.facebook.drawee.view.SimpleDraweeView
      android:id="@+id/drawee_view"
      android:layout_width="match_parent"
      android:layout_height="1000dp"
      />

vitrine d'origine v2.0.0
image

vitrine de sous-échantillonnage v2.0.0 désactivée
image

@sunnylqm merci pour le débogage. Comment puis-je désactiver le sous-échantillonnage ? J'ai essayé les méthodes suivantes sans succès :

1er sur MainApplication.java onCreate :

<strong i="10">@Override</strong>
public void onCreate() {
  super.onCreate();

  ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
    .setDownsampleEnabled(false)
    .build();

  Fresco.initialize(this, config);

  SoLoader.init(this, /* native exopackage */ false);
}

Avec cela, je reçois un message chez Logcat que Fresco est déjà initialisé.

2ème méthode que j'ai utilisée en initialisant MainReactPackage avec MainPackageConfig mais cela n'a pas fonctionné non plus :

protected List<ReactPackage> getPackages() {
  Context context = getApplicationContext();
  ImagePipelineConfig pipelineConfig = ImagePipelineConfig
    .newBuilder(context.getApplicationContext())
    .setDownsampleEnabled(false)
    .build();
  MainPackageConfig config = new MainPackageConfig.Builder().setFrescoConfig(pipelineConfig).build();

  return new ArrayList<>(Arrays.<ReactPackage>asList(
    new MainReactPackage(config),
    new ReactNativeFirebaseAppPackage(),
    new FastImageViewPackage(),
    new RNGestureHandlerPackage(),
    new ReanimatedPackage(),
    new SvgPackage()
  ));
}

@clytras je ne sais pas. Je l'ai désactivé dans le code source.

ping @oprisnik

On dirait que cela est défini via la configuration du package principal React Native : https://github.com/facebook/react-native/blob/6c0f73b3223968448bb186b82f06f6819068a21d/ReactAndroid/src/main/java/com/facebook/react/shell/MainPackageConfig.java

Je ne sais pas comment vous devez configurer cela avec RN, je n'ai jamais essayé cela.

@oprisnik Existe-t-il un plan pour résoudre ce problème ?

Je crois que cette question appartient toujours au repo RN. Le sous-échantillonnage d'image est sans aucun doute quelque chose qui permet de réduire le coût de la mémoire, de gagner en efficacité et d'avoir moins de crasses lors du chargement d'images volumineuses. Je pense que ces problèmes devraient être traités par RN de manière à permettre aux développeurs finaux de choisir s'ils souhaitent ou non un sous-échantillonnage d'image sous la forme d'une option/propriété. Par exemple, dans mon application, où j'utilise de grandes images pour présenter certains plans d'étage, j'ai besoin de la haute résolution lorsque l'utilisateur zoome sur le plan d'étage. Je vérifie toujours les capacités de l'appareil et s'il s'agit d'un appareil bas de gamme avec moins de RAM ou de faible résolution, je charge des images de plus en plus petites.

Il existe la propriété resizeMethod pour le composant <Image/> qui a scale et resize . RN currenlty ne respecte pas la scale de cette propriété, ce qui, à mon avis, devrait désactiver le sous-échantillonnage d'image et ne l'activer que lorsqu'il est défini sur resize .

resizeMethod

Le mécanisme qui doit être utilisé pour redimensionner l'image lorsque les dimensions de l'image diffèrent des dimensions de la vue de l'image. La valeur par défaut est automatique.

resize : Une opération logicielle qui modifie l'image encodée en mémoire avant qu'elle ne soit décodée. Cela devrait être utilisé à la place de scale lorsque l'image est beaucoup plus grande que la vue.

scale : L'image est agrandie ou réduite. Comparé à resize , scale est plus rapide (généralement accéléré par le matériel) et produit des images de meilleure qualité. Cela doit être utilisé si l'image est plus petite que la vue. Il doit également être utilisé si l'image est légèrement plus grande que la vue.

J'aimerais vraiment avoir votre avis sur ce @oprisnik @sunnylqm.

@clytras Comme tu l'as dit, c'est un changement de comportement en fresque sans explication. (La démo que je montre est l'exemple d'application dans le dépôt de fresques) Je ne pense donc pas que cela ait quoi que ce soit à voir avec RN.

@sunnylqm bien sûr, il s'agit d'un changement de comportement dans la fresque sans explication mais RN devrait laisser le choix d'activer/désactiver cette fonctionnalité de fresque aux développeurs finaux.

N'oubliez pas non plus que ce changement de comportement ne se produit bien sûr pas dans iOS, nous devons donc faire quelque chose et comme la configuration de la fresque se fait en natif de réaction, alors je pense que cette configuration devrait être exposée aux développeurs RN finaux.

BTW, j'ai réussi à compiler Fresco 2.0.0 (branche principale) avec le dernier RN 0.61.2 et à désactiver le sous-échantillonnage en commentant la vérification des conditions de sous-échantillonnage sur DecodeProducer.java comme vous l'avez fait.

J'ai créé un fichier local.properties dans le répertoire Fresco repo et utilisé Android NDK Revision 19c x86_64 pour Windows 64 bits.

ndk.dir=G:\\Dev\\Android\\android-ndk-r19c
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true

Les binaires Fresco ont été compilés avec succès et le sous-échantillonnage d'image a été désactivé pour l'application RN créée en exécutant :

cd android
.\gradlew assembleDebug --include-build ..\fresco\

oui, la solution pour cela serait de désactiver le sous-échantillonnage pour vos applications, via la logique d'initialisation RN ou lorsque Fresco est initialisé.

@oprisnik alors je pense que nous avons besoin d'un moyen meilleur, propre et facile d'initialiser la fresque dans le projet Android généré, ce que je n'ai pu réaliser avec aucune méthode que j'ai essayée. J'ai vu certains projets utiliser com.facebook.imagepipeline.core.ImagePipelineConfig , com.facebook.react.shell.MainReactPackage et com.facebook.react.shell.MainPackageConfig pour l'initialiser dans la méthode getPackages en passant la configuration à MainReactPackage , mais cela n'a pas fonctionné pour moi ni dans le dernier RN 0.61 ni RN 0.57 que j'ai essayé :

protected List<ReactPackage> getPackages() {
  Context context = getApplicationContext();

  ImagePipelineConfig pipelineConfig = ImagePipelineConfig
    .newBuilder(context.getApplicationContext())
    .setDownsampleEnabled(false)
    .build();

  MainPackageConfig config = new MainPackageConfig.Builder()
    .setFrescoConfig(pipelineConfig)
    .build();

  return new ArrayList<>(Arrays.<ReactPackage>asList(
    new MainReactPackage(config),
    ...
  ));
}

Peut-être que je fais quelque chose de mal là-bas, et cela n'a certainement pas fonctionné avec le nouveau système de liaison >= 0.60 qui génère un fichier PackageList.java répertoire <project>/android/app/build/generated/rncli/src/main/java/com/facebook/react/ parce que MainReactPackage est passé sans aucun argument et je ne vois aucun moyen de transmettre n'importe quel type d'argument en utilisant le système de liaison automatique, mais j'ai essayé en passant manuellement le MainReactPackage avec la configuration de fresque et cela n'a pas fonctionné non plus.

Nous avons besoin d'un moyen clair et documenté sur la façon d'initialiser la bibliothèque de fresques avec une configuration personnalisée dans le projet Android généré pour React Native.

Après avoir lu https://frescolib.org/docs/resizing.html et si j'ai bien compris, downsampling remplace resizing . Donc @clytras, je pense que vous avez raison, si resizeMethod est défini sur l'échelle, il ne devrait pas permettre le sous-échantillonnage.

Le code dans RN me semble correct https://github.com/facebook/react-native/blob/aee88b6843cea63d6aa0b5879ad6ef9da4701846/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java#L505 ( il transmettrait une valeur nulle à imagepipeline, ce qui n'indique aucun redimensionnement/sous-échantillonnage)
Mais en fresque cela ne respecte pas les null resizeOptions https://github.com/facebook/fresco/blob/v2.0.0/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java#L158 - L169
Si les deux downsampleEnabled et downsampleEnabledForNetwork sont vrais, il sera sous-échantillonné, même si les options de redimensionnement sont nulles
https://github.com/facebook/fresco/blob/master/imagepipeline-base/src/main/java/com/facebook/imagepipeline/transcoder/DownsampleUtil.java#L56
Il me semble donc qu'il y a un décalage entre la doc et le code. Et nous avons besoin d'un moyen plus flexible de contrôler si nous voulons qu'une image spécifique soit sous-échantillonnée. (maintenant, il est contrôlé par 2 configurations globales) @oprisnik

Beau travail là-bas @sunnylqm. J'ai commencé à chercher et à suivre la configuration RN pour le composant <Image/> pour vérifier ces choses, mais vous m'avez dépassé !

Puisqu'il y a un tel changement de comportement, je pense que l'une ou l'autre des fresques ne devrait vérifier et appliquer le sous-échantillonnage que si resizeOptions n'est pas nul ; qui est défini uniquement si resizeMethod est défini sur resize (ou auto et pour les images locales), ce qui est vérifié dans https://github.com/facebook/react- native/blob/aee88b6843cea63d6aa0b5879ad6ef9da4701846/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java#L606 shouldResize fonction, ou il devrait y avoir une nouvelle fonction resizeMethod option pour le sous-échantillonnage en particulier.

Salut, il semble qu'il n'y ait eu aucune activité sur ce problème récemment. Le problème a-t-il été résolu ou nécessite-t-il toujours l'attention de la communauté ? Ce problème peut être fermé si aucune autre activité ne se produit. Vous pouvez également étiqueter ce problème comme "bug" ou "amélioration" et je le laisserai ouvert. Merci pour vos contributions.

@clytras peux -tu nous dire ta solution ?

@ club9822 la solution pour l'instant est de compiler les binaires de fresque à partir de la source après avoir d'abord désactivé le sous-échantillonnage d'image comme je le décris ici https://github.com/facebook/fresco/issues/2397#issuecomment -541802753

Existe-t-il une solution de contournement pour cela sans recompiler les bibliothèques principales ?

@CaptainN Il n'y a pas de solution facile à ce problème. Le processus de compilation des sources peut sembler difficile et fastidieux, mais il s'agit en fait d'apporter quelques modifications mineures et d'exécuter des commandes. Suivez mes messages dans ce numéro pour savoir comment vous procédez.

@clytras Vous pouvez passer config dans le deuxième argument dans new PackageList(this, config)
Et j'ai essayé cela a fonctionné comme prévu. Le problème est que la logique ici a simplement ignoré la configuration https://github.com/facebook/fresco/blob/v2.0.0/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java#L158 -L169 si c'était false
ça devrait être comme ça non ?

- if (mDownsampleEnabled || !statusHasFlag(status, Consumer.IS_RESIZING_DONE))
+ if (mDownsampleEnabled && !statusHasFlag(status, Consumer.IS_RESIZING_DONE))

@oprisnik

@sunnylqm Je suis absent du bureau et je ne peux pas vérifier maintenant, mais je me souviens que je n'ai pas trouvé de moyen de passer la configuration en utilisant le nouveau système de liaison automatique _RN >= 60_. Je ne suis pas sûr cependant. Cela n'a pas fonctionné même pour les anciennes versions de _RN_ pour moi. Je vérifierai dans quelques jours à mon retour de vacances.

Je pense que le changement OR à AND résoudra le problème car il est assez évident que le sous-échantillonnage s'applique désormais toujours si le statut n'a pas l'indicateur IS_RESIZING_DONE , il contourne donc complètement mDownsampleEnabled . Bien sûr, ce sera le cas si la configuration de fresque personnalisée désactivant le sous-échantillonnage est appliquée et transmise à fresque.

@clytras Je reçois toutes sortes d'erreurs avec la dépréciation de gradle et tout ça. Avez-vous une chance de mettre en place un binaire de pré-construction (et me dire où l'installer) ? Je l'apprécierais vraiment.

Ah oublie ça. C'est même impoli de demander. Je vais le découvrir, et peut-être mettre dans un PR.

@CaptainN ce n'est pas impoli. Le fait est que je l'ai fait et que j'ai résolu toutes les erreurs, il me faudra donc beaucoup moins de temps pour créer un référentiel de démarrage avec des instructions sur la façon d'installer et de corriger Fresco.

Alors voilà : https://github.com/clytras/RN061FrescoBuild

Il a RN 0.61.5 . Le dépôt contient des instructions détaillées. Il clone Fresco, extrait v2.1.0 et applique un correctif à DecodeProducer.java afin de commenter le code de sous-échantillonnage. Vous n'avez qu'à télécharger le NDK Android et ajouter un fichier libraries/fresco/local.properties . Tout est détaillé dans le readme.

Vous pouvez ajouter Fresco lib à un projet RN existant >= 0.60 (_ou versions antérieures_) si vous suivez les instructions et les scripts de fil.

@clytras Merci beaucoup d'avoir mis cela en place. J'apprécie vraiment cela.

Y a-t-il un mot pour savoir si le commentaire ci-dessus résoudra le problème à l'avenir ?

J'ai testé le changement suggéré par @sunnylqm :

- if (mDownsampleEnabled || !statusHasFlag(status, Consumer.IS_RESIZING_DONE))
+ if (mDownsampleEnabled && !statusHasFlag(status, Consumer.IS_RESIZING_DONE))

et il s'avère qu'après ce changement, j'ai pu désactiver le sous-échantillonnage d'image en utilisant simplement la configuration dans MainApplication.java , ce qui signifie que personne n'aura à compiler la fresque et n'aura qu'à y modifier les paramètres de la fresque :

<strong i="12">@Override</strong>
protected List<ReactPackage> getPackages() {
  Context context = getApplicationContext();

  ImagePipelineConfig frescoConfig = ImagePipelineConfig
    .newBuilder(context)
    .setDownsampleEnabled(false)
    .build();

  MainPackageConfig appConfig = new MainPackageConfig
    .Builder()
    .setFrescoConfig(frescoConfig)
    .build();

  @SuppressWarnings("UnnecessaryLocalVariable")
  List<ReactPackage> packages = new PackageList(this, appConfig).getPackages();
  // Packages that cannot be autolinked yet can be added manually here, for example:
  // packages.add(new MyReactNativePackage());
  return packages;
}

Après ce seul changement, le code de configuration ci-dessus fonctionnera et désactivera le sous-échantillonnage. Si nous supprimons cette configuration ou définissons .setDownsampleEnabled(true) cela activera correctement le sous-échantillonnage. Cela ressemble à un bug pour moi @oprisnik. Bien sûr, l'idéal pour moi sera que RN respecte resizeMethod et applique le sous-échantillonnage dynamiquement, mais je ne suis pas sûr que ce soit possible.

ÉDITER

En fait, j'avais en partie tort. Avec ce changement (_qui a tout son sens_), RN définit .setDownsampleEnabled(false) comme nous pouvons le voir ici ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java#L155 , donc, dans Afin d'activer le sous-échantillonnage, nous devons configurer Fresco avec le code ci-dessus et définir .setDownsampleEnabled(true) . RN a désactivé le sous-échantillonnage par défaut !

@clytras @CaptainN Merci beaucoup pour votre travail sur ce problème. J'en fais l'expérience, en utilisant Expo et j'ai vraiment hâte de trouver une solution, sans éjecter mon application, si possible.

réaction-native-cli: 2.0.1
natif réactif : 0.61.2

Petite mise à jour. Cela fait longtemps que je n'ai pas rencontré ce problème. Mais je ne sais pas si c'est parce que je suis passé à 3 échelles différentes de la même image ( @1x , @2x , @3x) pour la plupart des images.

@enguerranws Je n'ai aucune expérience avec Expo. @gorvinsky Je viens de le tester avec RN 0.61.5 et cela ne fonctionne pas. Malheureusement, les tailles d'image groupées n'ont jamais fonctionné. C'était la première chose que j'ai testée lorsque j'ai rencontré ce problème pour la première fois.

J'ai créé un modèle react -native-community/cli qui a le projet RN 0.61.5 et les modifications requises pour créer Fresco à partir de la source. C'est un moyen simple et rapide d'avoir un nouveau projet RN conçu avec un nom de projet personnalisé et avec les modifications nécessaires pour compiler Fresco à partir de la source. Il utilise également Android NDK Révision 21 et je l'ai testé sur macOS et Windows en utilisant yarn 1.21 .

Dépôt Github :
Modèle NPM :

Il peut être installé comme ceci :

npx @react-native-community/cli<strong i="17">@next</strong> init --template=@lytrax/react-native-fresco <ProjectName>

Il y a des instructions d'installation détaillées dans le README . Vous devez cloner/corriger Fresco à l'aide de yarn fresco-setup , puis installer Android NDK et créer android/libraries/fresco/local.properties avec le chemin Android NDK.

Est-ce que ce commit dans react-native corrige cela? (pas publié pour l'instant)

https://github.com/facebook/react-native/commit/f535c8b4bb4474ffe0a0765270cbca8d839deca8

Dans la description, il est dit que nous pouvons passer un PipelineConfig qui a un attribut "setDownsampleEnabled".

https://frescolib.org/docs/configure-image-pipeline.html

@enguerranws Je n'ai aucune expérience avec Expo. @gorvinsky Je viens de le tester avec RN 0.61.5 et cela ne fonctionne pas. Malheureusement, les tailles d'image groupées n'ont jamais fonctionné. C'était la première chose que j'ai testée lorsque j'ai rencontré ce problème pour la première fois.

J'ai créé un modèle react -native-community/cli qui a le projet RN 0.61.5 et les modifications requises pour créer Fresco à partir de la source. C'est un moyen simple et rapide d'avoir un nouveau projet RN conçu avec un nom de projet personnalisé et avec les modifications nécessaires pour compiler Fresco à partir de la source. Il utilise également Android NDK Révision 21 et je l'ai testé sur macOS et Windows en utilisant yarn 1.21 .

Dépôt Github :
Modèle NPM :

Il peut être installé comme ceci :

npx @react-native-community/cli<strong i="18">@next</strong> init --template=@lytrax/react-native-fresco <ProjectName>

Il y a des instructions d'installation détaillées dans le README . Vous devez cloner/corriger Fresco à l'aide de yarn fresco-setup , puis installer Android NDK et créer android/libraries/fresco/local.properties avec le chemin Android NDK.

Existe-t-il un moyen de l'appliquer à un projet existant ?

@kalmahik
Essayez de cette façon. (Mon RN est la v0.61.4)
C'est le moyen d'appliquer le patch @clytras à un projet existant.
Et il ne peut plus exécuter le simulateur Android. Je teste toujours sur de vrais appareils. ??

  1. Ajouter des scripts à package.json
"fresco-clone": "git clone https://github.com/facebook/fresco.git android/libraries/fresco && cd android/libraries/fresco && git checkout tags/v2.1.0",
"fresco-patch": "yarn file-patch ./patches/DecodeProducer.java.diff android/libraries/fresco/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java",
"fresco-setup": "yarn fresco-clone && yarn fresco-patch"
  1. Créer des correctifs/DecodeProducer.java.diff

'patch de fresque de fil'

Résultat

@@ -7279,32 +7279,35 @@

+// 
 if (mDownsampleE
@@ -7381,24 +7381,27 @@

+// 
   ImageReque
@@ -7460,24 +7460,27 @@

+// 
   if (mDowns
@@ -7513,24 +7513,27 @@

+ //
        %7C%7C !U
@@ -7587,36 +7587,39 @@

+//

+ 
 encodedImage.set
@@ -7637,32 +7637,35 @@
 %0A               
+ //
          Downsam
@@ -7700,32 +7700,35 @@
 %0A               
+ //
              req
@@ -7762,32 +7762,35 @@

+// 
             requ
@@ -7820,32 +7820,35 @@
 %0A               
+ //
              enc
@@ -7866,32 +7866,35 @@

+// 
             maxB
@@ -7914,32 +7914,35 @@

+// 
   %7D%0A            
@@ -7937,32 +7937,35 @@

+// 
 %7D%0A%0A             
@@ -7962,24 +7962,27 @@

+ //
  if (produce
@@ -8002,28 +8002,31 @@

+//

+ 
 .getImagePip
@@ -8050,24 +8050,27 @@

+ //
      .getExp
@@ -8091,24 +8091,27 @@

+ //
      .should
@@ -8151,24 +8151,27 @@

+// 
   maybeIncre
@@ -8206,32 +8206,35 @@
 %0A               
+ //
  %7D%0A%0A            
  1. Modifier android/settings.gradle

Ajouter includeBuild ('libraries/fresco') avant include ':app'

rootProject.name = 'YOURPROJECT'
...
includeBuild ('libraries/fresco') 

include ':app'

  1. android/build.gradle

Utiliser la dépendance gradle est 3.4.1

dependencies {
  ...
  classpath("com.android.tools.build:gradle:3.4.1")
  ...
}
  1. Script de lancement

yarn fresco-setup

  1. Télécharger android ndk

J'ai utilisé la version r21.

https://developer.android.com/ndk/downloads

  1. Décompressez et déplacez le ndk

Décompressez le NDK
J'ai décompressé ndk en Users/YOURNAME/Library/Android/android-ndk-r21
Et créez android/libraries/fresco/local.properties dans votre projet

ndk.dir=/Users/YOURNAME/Library/Android/android-ndk-r21
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
  1. Exécuter Android

C'est tout.

yarn android et vérifiez la grande qualité de l'image.

Merci à @clytras

https://github.com/clytras/react-native-fresco

@JeffGuKang
qu'est-ce que la commande file-patch ?

Qu'est-ce qui l'empêche de fusionner ? Pourquoi avons-nous besoin de ces correctifs au lieu de simplement les réparer (en supposant que ce n'est pas seulement une contrainte de temps - je comprends tout à fait, sans essayer d'être arrogant) ?

@kalmahik file-patch est un outil de correctif CLI du package NPM.

@JeffGuKang, vous devez inclure les modifications dans package.json qui sont requises pour que les scripts de configuration du modèle fonctionnent.

@CaptainN Je ne pense pas que ce soit aussi simple, même si je n'ai pas encore eu le temps de tester les commits ci-dessus.

@clytras oh celui- ci ? Merci)

@kalmahik
Essayez de cette façon. (Mon RN est la v0.61.4)
C'est le moyen d'appliquer le patch @clytras à un projet existant.
Et il ne peut plus exécuter le simulateur Android. Je teste toujours sur de vrais appareils. ??

  1. Ajouter des scripts à package.json
"fresco-clone": "git clone https://github.com/facebook/fresco.git android/libraries/fresco && cd android/libraries/fresco && git checkout tags/v2.1.0",
"fresco-patch": "yarn file-patch ./patches/DecodeProducer.java.diff android/libraries/fresco/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java",
"fresco-setup": "yarn fresco-clone && yarn fresco-patch"
  1. Créer des correctifs/DecodeProducer.java.diff

'patch de fresque de fil'

Résultat

@@ -7279,32 +7279,35 @@

+// 
 if (mDownsampleE
@@ -7381,24 +7381,27 @@

+// 
   ImageReque
@@ -7460,24 +7460,27 @@

+// 
   if (mDowns
@@ -7513,24 +7513,27 @@

+ //
        %7C%7C !U
@@ -7587,36 +7587,39 @@

+//

+ 
 encodedImage.set
@@ -7637,32 +7637,35 @@
 %0A               
+ //
          Downsam
@@ -7700,32 +7700,35 @@
 %0A               
+ //
              req
@@ -7762,32 +7762,35 @@

+// 
             requ
@@ -7820,32 +7820,35 @@
 %0A               
+ //
              enc
@@ -7866,32 +7866,35 @@

+// 
             maxB
@@ -7914,32 +7914,35 @@

+// 
   %7D%0A            
@@ -7937,32 +7937,35 @@

+// 
 %7D%0A%0A             
@@ -7962,24 +7962,27 @@

+ //
  if (produce
@@ -8002,28 +8002,31 @@

+//

+ 
 .getImagePip
@@ -8050,24 +8050,27 @@

+ //
      .getExp
@@ -8091,24 +8091,27 @@

+ //
      .should
@@ -8151,24 +8151,27 @@

+// 
   maybeIncre
@@ -8206,32 +8206,35 @@
 %0A               
+ //
  %7D%0A%0A            
  1. Modifier android/settings.gradle

Ajouter includeBuild ('libraries/fresco') avant include ':app'

rootProject.name = 'YOURPROJECT'
...
includeBuild ('libraries/fresco') 

include ':app'
  1. android/build.gradle

Utiliser la dépendance gradle est 3.4.1

dependencies {
  ...
  classpath("com.android.tools.build:gradle:3.4.1")
  ...
}
  1. Script de lancement

yarn fresco-setup

  1. Télécharger android ndk

J'ai utilisé la version r21.

https://developer.android.com/ndk/downloads

  1. Décompressez et déplacez le ndk

Décompressez le NDK
J'ai décompressé ndk en Users/YOURNAME/Library/Android/android-ndk-r21
Et créez android/libraries/fresco/local.properties dans votre projet

ndk.dir=/Users/YOURNAME/Library/Android/android-ndk-r21
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
  1. Exécuter Android

C'est tout.

yarn android et vérifiez la grande qualité de l'image.

Merci à @clytras

https://github.com/clytras/react-native-fresco

Je suis confronté à ce problème lorsque j'essaie de compiler Fresco à partir de la source suivant le script @clytras . Je le compile dans un projet RN (v0.59.9) existant

Screen Shot 2020-05-31 at 1 11 34 PM

Aussi, j'ai essayé d'ajouter Fresco Config dans MainApplication.java mais pas de chance là-bas

@ ravali121 Ces étapes sont pour RN >= 0.60.x, pas pour RN 0.59 ou versions antérieures. Il peut être corrigé pour les anciennes versions RN, mais les étapes et la vérification de Fresco doivent suivre la version fournie avec cette version RN spécifique. Je vérifie Fresco 2.1.0 pour RN 0.61 et RN 0.59 a une version différente et bien sûr un patch différent bien que le patch ne soit pas nécessaire, les changements de code peuvent être appliqués manuellement en éditant DecodeProducer.java . En outre, il existe une configuration gradle supplémentaire pour gérer les dépendances.

Bien que vous puissiez le faire fonctionner avec 0,59, je vous suggère de mettre à niveau votre/vos projet(s) vers au moins 0,61 (ou mieux 0,62).

Bonjour! Une mise à jour sur un ETA pour le patch à fusionner ? (Merci @clytras pour le travail formidable, je dois essayer votre patch dès que possible mais j'aimerais savoir si cela va être corrigé)

@FRizzonelli le correctif est une solution de contournement, ce n'est pas vraiment une solution au problème et c'est pourquoi ce problème reste ouvert si longtemps.
Je dois vérifier le correctif et le modèle @react-native-community/cli et le mettre à niveau vers la dernière version RN.

@clytras Je comprends :( Le problème est en ce moment que j'essaye de configurer un petit POC avec react-native-web sur Expo, qui a ce problème pour Android. Et pour une petite démo, j'aimerais ne pas m'éjecter. Mais Je pense que je dois :(

@clytras Je comprends :( Le problème est en ce moment que j'essaye de configurer un petit POC avec react-native-web sur Expo, qui a ce problème pour Android. Et pour une petite démo, j'aimerais ne pas m'éjecter. Mais Je pense que je dois :(

Que diriez-vous d'utiliser le format jpg au lieu de png ? Je ne suis pas sûr que cela puisse résoudre le problème.

@clytras Je comprends :( Le problème est en ce moment que j'essaye de configurer un petit POC avec react-native-web sur Expo, qui a ce problème pour Android. Et pour une petite démo, j'aimerais ne pas m'éjecter. Mais Je pense que je dois :(

Que diriez-vous d'utiliser le format jpg au lieu de png ? Je ne suis pas sûr que cela puisse résoudre le problème.

Malheureusement, cela ne fonctionne pas non plus et j'ai besoin de png pour la couche alpha :(

J'ai le même problème avec RN 0.63.4.
La taille de l'image de 960 x 13983 est beaucoup moins échantillonnée, les textes de l'image peuvent à peine être lus.
La taille de l'image de 680 X 2538 est également sous-échantillonnée mais tout à fait correcte.
J'ai utilisé Image.getSize pour connaître la taille de l'image et en calculer la hauteur (la largeur est de 100%)
Les images sont toutes au format jpg.
Je l' ai fait la méthode de @clytras de gradle avec 3.5.4, NDK 21.4.7075529. Mais, même problème.

        <Image
          style={{ width: SCREEN_WIDTH, height }}
          resizeMode="contain"
          source={{ uri }}
          resizeMethod="scale"
        />

Nous avons résolu le problème avec FastImage. J'espère que cela aiderait.

 <FastImage
          style={{ width: SCREEN_WIDTH, height: height }}
          source={{
            uri: uri,
            priority: FastImage.priority.normal,
          }}
          resizeMode={FastImage.resizeMode.center}
 />

@JJMoon Savez-vous comment forcer FastImage à restituer l'image lorsque je modifie la taille de l'image dans le style.
L'image est toujours restituée, mais pas FastImage.

Bonjour ensemble,

J'ai essayé toutes les solutions possibles à partir de ce fil, mais avec RN 0.64.2 et Fresco 2.5.0.
J'utilise NDK v22.1.7171670 et gradle 4.2.1.

Je suis actuellement bloqué sur l'erreur suivante (le problème est-il lié à l'émulateur Android ?) :

E/AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
    Process: com.veerle.wiener.debug, PID: 10813
    java.lang.NoSuchMethodError: No static method initialize(Lcom/facebook/imagepipeline/core/ImagePipelineConfig;)V in class Lcom/facebook/imagepipeline/core/ImagePipelineFactory; or its super classes (declaration of 'com.facebook.imagepipeline.core.ImagePipelineFactory' appears in /data/app/<project>/base.apk!classes16.dex)
        at com.facebook.drawee.backends.pipeline.Fresco.initialize(Fresco.java:83)
        at com.facebook.drawee.backends.pipeline.Fresco.initialize(Fresco.java:45)
        at com.facebook.react.modules.fresco.FrescoModule.initialize(FrescoModule.java:114)
        at com.facebook.react.bridge.ModuleHolder.doInitialize(ModuleHolder.java:236)
        at com.facebook.react.bridge.ModuleHolder.markInitializable(ModuleHolder.java:100)
        at com.facebook.react.bridge.NativeModuleRegistry.notifyJSInstanceInitialized(NativeModuleRegistry.java:103)
        at com.facebook.react.bridge.CatalystInstanceImpl$2.run(CatalystInstanceImpl.java:438)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
        at android.os.Looper.loop(Looper.java:223)
        at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:226)
        at java.lang.Thread.run(Thread.java:923)
I/Process: Sending signal. PID: 10813 SIG: 9

@JJMoon utilisant FastImage avec des images locales (obligatoire) m'a donné une mauvaise expérience de scintillement.

En attendant que l'équipe résolve ce problème, j'utilise à la fois Image et FastImage comme ça
if(height < blurSize){ return <Image/> }else{ return <FastImage/> }

Cette page vous a été utile?
0 / 5 - 0 notes