Fresco: Niedrige Bildqualität mit<image/> Komponente auf RN &gt; = 0.57 (Fresko &gt;= 1.10.0)

Erstellt am 22. Aug. 2019  ·  57Kommentare  ·  Quelle: facebook/fresco

Beschreibung

RN-Problem: RN 0.57.x Gebündelte große Bilder haben eine niedrige Qualität bei der Anzeige mit \

Beim Laden großer gebündelter Bilder (PNG, GIF und möglicherweise mehr Formate, NICHT JPEG ) ist die Qualität nur auf Android gering:

Auf dem linken Screenshot sehen wir genau den gleichen Code, der mit RN 0.56.0 läuft und auf dem rechten Screenshot sehen wir RN 0.57.1 . Der Code ist nur ein einfaches Bild <Image source={require('./assets/ELHall1.png')} resizeMethod="resize" /> und die Bildgröße ist 2111 x 4645 pixels . Beide Projekte werden mit react-native init RN057ImageTest und react-native init --version="0.56.0" RN056ImageTest installiert. Dies geschieht weiterhin ab 0.56 und allen Versionen nach und neuestem RN 0.60.x.

Es wird bestätigt, dass dies durch die Änderung der RN Fresco-Lib zwischen 0.56 und 0.57 von 1.9.0 auf 1.10.0 verursacht wird https://github.com/facebook/react-native/commit/b6f2aad9c0119d11e52978ff3fa9c6f269f04a14. Überprüfen Sie den Kommentar https://github.com/facebook/react-native/issues/21301#issuecomment-520155609.

Nach einiger Suche bei Fresco-Problemen kann ich einige verwandte Probleme sehen, die vorgeschlagen werden, große Bilder Stück für Stück zu teilen und neu zusammenzusetzen, was viele Fälle löst (die meisten kartenbezogenen großen Bilder), aber es kann besonders für dynamisch geladene Bilder sehr unpraktisch sein /erstellte Bilder. Dies funktionierte bis RN 0.56 und ab 0.57 und danach nicht mehr.

Reproduktion

RN: Es ist das anfängliche App.js mit einer hinzugefügten <Image/> Komponente.

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

zusätzliche Information

In diesem Kommentar https://github.com/facebook/react-native/issues/21301#issuecomment-520418832 schreibt Lambdapioneer , dass dies möglicherweise mit dem

Ich gehe davon aus, dass es damit zusammenhängt, wie Fresco große Bilder verkleinert (Unterabtastung) (was ein wichtiges Merkmal für Speicher- und Leistungsprobleme ist). In dieser Zeit gab es einige Änderungen in diesem Bereich, hauptsächlich zum Entfernen von Abhängigkeiten vom nativen Code, um die ebenfalls dringenden .so-Linkfehler zu reduzieren. Sozusagen: Es könnte ein Nebeneffekt einer weiteren großen Verbesserung sein.

  • Fresko-Version: >= 1.10.0
  • Plattformversion: RN >= 0.57, alle Android-Versionen
enhancement

Hilfreichster Kommentar

@CaptainN es ist nicht unhöflich. Die Sache ist, dass ich es getan und alle Fehler behoben habe, sodass es viel weniger Zeit in Anspruch nimmt, ein Starter-Repo mit Anweisungen zur Installation und zum Patchen von Fresco zu erstellen.

Hier ist es also: https://github.com/clytras/RN061FrescoBuild

Es hat RN 0.61.5 . Das Repo enthält detaillierte Anweisungen. Es klont Fresco, checkt v2.1.0 und wendet einen Patch auf DecodeProducer.java an, um den Downsampling-Code zu kommentieren. Sie müssen nur das Android NDK herunterladen und eine libraries/fresco/local.properties Datei hinzufügen. In der Readme ist alles ausführlich beschrieben.

Sie können fresco lib zu einem bestehenden RN >= 0.60 (_oder älteren Versionen_) Projekt hinzufügen, wenn Sie die Anweisungen und die Garnskripte befolgen.

Alle 57 Kommentare

Hallo, anscheinend gab es in letzter Zeit keine Aktivitäten zu diesem Thema. Wurde das Problem behoben oder erfordert es immer noch die Aufmerksamkeit der Community? Dieses Problem kann geschlossen werden, wenn keine weitere Aktivität auftritt. Sie können dieses Problem auch als "Fehler" oder "Erweiterung" bezeichnen und ich werde es offen lassen. Vielen Dank für Ihre Beiträge.

Welche Fresco-Versionen verwenden RN 0.56.0 und 0.57.1? Dies grenzt die Anzahl der Commits ein, die dies verursacht haben könnten.

Hallo @oprisnik ,

Ich werde überprüfen und sehen, in welcher Version Patch das Upgrade erhalten hat, wenn ich in mein Büro zurückkehre, obwohl ich denke, dass https://github.com/facebook/react-native/issues/21301#issuecomment -520155609 genau berichtet ab welcher Version diese Verhaltensänderung erhalten wurde.

Hallo @clytras , ich habe das Bild auf dem Bildschirm in diesem Repository gefunden .
Ich lade das Bild herunter und finde das Bild 2111 (Breite) * 4645 (Höhe).

Fresco wird ein Bild herunterskalieren, damit es dem OpenGL-Limit entspricht. Die maximale Breite/Höhe des Standardbilds ist in dieser Zeile fest codiert.

Meiner Meinung nach,
Der einfachste Weg besteht darin, das maxBitmapSize-Feld einer ResizeOption zu ändern.
Der richtige Weg ist, Fresco nicht zu verwenden, um ein SEHR großes Bild anzuzeigen.

Erstellen Sie ein anderes Widget und verwenden Sie diese Bibliothek , um ein SEHR großes Bild anzuzeigen.

Hallo @s1rius , ich schreibe die Bildgröße genau, wenn Sie den offenen Ausgabepost lesen:

Der Code ist nur ein einfaches Bild und die Bildgröße beträgt 2111 x 4645 Pixel

Es handelt sich um eine Verhaltensänderung von RN >= 0,57, die sich von Fresco 1.9.0 auf 1.10.0 geändert hat. Große Bilder wie dieses funktionierten und wurden in voller Qualität vor dieser Version geladen. Mitwirkende von RN Repo haben das Problem geschlossen, da sie angeben, dass es sich nicht um ein RN-Problem, sondern um ein Fresco-Lib-Problem handelt. Wenn diese Verhaltensänderung absichtlich vorgenommen wird, können wir dieses Problem schließen. Ja, es gibt Problemumgehungen, aber es war so, dass dies bis zu einer Version funktionierte und plötzlich und ohne Informationen darüber, warum es nicht mehr funktionierte.

Hallo, anscheinend gab es in letzter Zeit keine Aktivitäten zu diesem Thema. Wurde das Problem behoben oder erfordert es immer noch die Aufmerksamkeit der Community? Dieses Problem kann geschlossen werden, wenn keine weitere Aktivität auftritt. Sie können dieses Problem auch als "Fehler" oder "Erweiterung" bezeichnen und ich werde es offen lassen. Vielen Dank für Ihre Beiträge.

Schließen dieses Problems nach längerer Inaktivität. Wenn dieses Problem in der neuesten Version weiterhin auftritt, können Sie sie mit aktuellen Informationen erneut öffnen.

Eine mögliche Änderung, die dies verursacht haben könnte, ist https://github.com/facebook/fresco/commit/fa71901055a38a810c190862c7fd582fd3dad2b3

Können Sie überprüfen, ob dies die beleidigende Änderung ist?

Hallo nochmal @oprisnik und danke für die Untersuchung.

Ich bin nicht so vertraut mit Gradle und wie ich RN ändern kann, um Fresko direkt aus der Quelle zu kompilieren, anstatt die Bibliothek herunterzuladen. Schritte, die ich ohne Erfolg unternommen habe:

  1. Erstellen Sie ein RN 0.57-Projekt mit react-native-cli
  2. Klonen Sie fresco lib in das Projekt-Stammverzeichnis
  3. Bezahlen Sie in der Filiale v1.10.0 in der Fresco-Lib
  4. android-ndk-r20 Pfad zu <Project>\android\local.properties ( ndk.dir=G:\\Dev\\Android\\android-ndk-r20 )

Dann habe ich diese Antwort bei SO https://stackoverflow.com/a/52861379/1889685 gefunden , die RN mit Fresko aus der Quelle kompiliert und die Bibliothek überschreibt:

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

aber ich bekomme folgenden Fehler:

> 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.

Vielleicht kann @sunnylqm das testen, wenn er etwas Zeit hat, da er mit diesem Prozess viel vertrauter ist.

Wenn es hilft, kann ich mit dem, was ich bisher habe, ein Repo erstellen.

Hallo, anscheinend gab es in letzter Zeit keine Aktivitäten zu diesem Thema. Wurde das Problem behoben oder erfordert es immer noch die Aufmerksamkeit der Community? Dieses Problem kann geschlossen werden, wenn keine weitere Aktivität auftritt. Sie können dieses Problem auch als "Fehler" oder "Erweiterung" bezeichnen und ich werde es offen lassen. Vielen Dank für Ihre Beiträge.

Ich habe versucht zu bauen, bekam aber auch den ndk-Fehler. Habt ihr nächtliche Builds, die wir testen können?

Da ich v2.0.0 ohne Änderungen kompilieren kann, habe ich einen anderen Weg zur Überprüfung versucht. Ich habe das Downsampling deaktiviert, das durch das obige Commit aktiviert wird , und hier sind die Ergebnisse

Testbild uri:
" 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"
      />

Original v2.0.0-Schaufenster
image

Deaktiviertes Downsampling v2.0.0 Vitrine
image

@sunnylqm danke für das Debuggen. Wie kann ich das Downsampling deaktivieren? Ich habe die folgenden Methoden ohne Erfolg ausprobiert:

Erster in 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);
}

Damit bekomme ich bei Logcat eine Meldung, dass Fresco bereits initialisiert ist.

Zweite Methode, die ich verwendet habe, indem ich MainReactPackage mit MainPackageConfig initialisiert habe, aber es hat auch nicht funktioniert:

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 Ich weiß es nicht. Ich habe es im Quellcode deaktiviert.

ping @oprisnik

Sieht so aus, als ob dies über die React Native-Hauptpaketkonfiguration eingestellt wird: https://github.com/facebook/react-native/blob/6c0f73b3223968448bb186b82f06f6819068a21d/ReactAndroid/src/main/java/com/facebook/react/shell/MainPackageConfig.java

Ich bin mir nicht sicher, wie Sie das mit RN einrichten müssen, habe das noch nie versucht.

@oprisnik Gibt es einen Plan, dieses Problem zu beheben?

Ich glaube, dieses Problem gehört immer noch zum RN-Repo. Bild-Downsampling ist etwas, das ohne Zweifel dazu dient, die Speicherkosten zu senken, die Effizienz zu steigern und beim Laden großer Bilder weniger Karies zu verursachen. Ich denke, diese Probleme sollten von RN so behandelt werden, dass Endentwickler wählen können, ob sie ein Bild-Downsampling in Form einer Option/Eigenschaft haben möchten oder nicht. Zum Beispiel in meiner App, wo ich große Bilder für die Präsentation einiger Grundrisse verwende, brauche ich die High-Res, wenn der Benutzer in den Grundriss hineinzoomt. Ich überprüfe immer die Gerätefunktionen und wenn es sich um ein Low-End-Gerät mit weniger RAM oder niedriger Auflösung handelt, lade ich kleinere und niedrigere Bilder.

Es gibt die Eigenschaft resizeMethod für die Komponente <Image/> , die scale und resize . RN currenlty respektiert nicht den scale Wert dieser Eigenschaft, was meiner Meinung nach das Downsampling von Bildern deaktivieren und nur aktivieren sollte, wenn es auf resize .

resizeMethod

Der Mechanismus, der verwendet werden sollte, um die Größe des Bildes zu ändern, wenn die Abmessungen des Bildes von den Abmessungen der Bildansicht abweichen. Standardmäßig ist automatisch.

resize : Eine Softwareoperation, die das kodierte Bild im Speicher ändert, bevor es dekodiert wird. Dies sollte anstelle von scale wenn das Bild viel größer als die Ansicht ist.

scale : Das Bild wird verkleinert oder verkleinert gezeichnet. Im Vergleich zu resize ist scale schneller (normalerweise hardwarebeschleunigt) und produziert qualitativ hochwertigere Bilder. Dies sollte verwendet werden, wenn das Bild kleiner als die Ansicht ist. Es sollte auch verwendet werden, wenn das Bild etwas größer als die Ansicht ist.

Ich würde wirklich gerne Ihre Meinung zu diesem

@clytras Wie Sie gesagt haben, handelt es sich um eine Verhaltensänderung im Fresko ohne Erklärung. (Die Demo, die ich zeige, ist die Beispiel-App im Fresco-Repo) Ich glaube also nicht, dass es etwas mit RN zu tun hat.

@sunnylqm natürlich handelt es sich um eine Verhaltensänderung im Fresko ohne Erklärung, aber RN sollte die Wahl zum Aktivieren/Deaktivieren dieser Freskofunktion den Endentwicklern überlassen.

Vergessen Sie auch nicht, dass diese Verhaltensänderung in iOS natürlich nicht stattfindet, also müssen wir etwas dagegen tun und da die Fresco-Konfiguration in React Native stattfindet, denke ich, dass diese Konfiguration End-RN-Entwicklern zugänglich gemacht werden sollte.

Übrigens, ich habe es geschafft, Fresco 2.0.0 (Master-Zweig) mit dem neuesten RN 0.61.2 und deaktiviertem Downsampling zu kompilieren, indem ich die Downsampling-Bedingungsprüfung bei DecodeProducer.java auskommentiert habe, wie Sie es getan haben.

Ich habe eine local.properties Datei im Fresco-Repo-Verzeichnis erstellt und Android NDK Revision 19c x86_64 für Windows 64-Bit verwendet.

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

Fresco-Binärdateien wurden erfolgreich kompiliert und das Downsampling von Bildern wurde für die RN-App deaktiviert, die erstellt wurde, indem Folgendes ausgeführt wurde:

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

Ja, die Lösung hierfür wäre, das Downsampling für Ihre Anwendungen über die RN-Initialisierungslogik oder bei der Initialisierung von Fresco zu deaktivieren.

@oprisnik dann brauchen wir meiner Meinung nach eine bessere, saubere und einfache Möglichkeit, das Fresko innerhalb des generierten Android-Projekts zu initialisieren, was ich mit keiner von mir ausprobierten Methode erreichen konnte. Ich habe gesehen, dass einige Projekte com.facebook.imagepipeline.core.ImagePipelineConfig , com.facebook.react.shell.MainReactPackage und com.facebook.react.shell.MainPackageConfig , um es innerhalb der getPackages Methode zu initialisieren, indem die Konfiguration an MainReactPackage , aber das hat bei mir weder in der neuesten RN 0.61 noch in der RN 0.57, die ich ausprobiert habe, funktioniert:

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),
    ...
  ));
}

Vielleicht mache ich da etwas falsch, und das hat definitiv nicht mit dem neuen >= 0.60 Linking-System funktioniert, das eine PackageList.java Datei im <project>/android/app/build/generated/rncli/src/main/java/com/facebook/react/ Verzeichnis generiert, weil MainReactPackage ist ohne Argumente übergeben und ich kann keine Möglichkeit sehen, Argumente mit dem Auto-Linking-System zu übergeben, aber ich habe versucht, MainReactPackage manuell mit der Fresco-Konfiguration zu übergeben, und das hat auch nicht funktioniert.

Wir brauchen einen sauberen und dokumentierten Weg, um die Fresco-Bibliothek mit benutzerdefinierter Konfiguration innerhalb des generierten Android-Projekts für React Native zu initialisieren.

Nachdem ich https://frescolib.org/docs/resizing.html gelesen habe und wenn ich das richtig verstanden habe, ist downsampling ein Ersatz für resizing . Also @clytras Ich denke, Sie haben Recht, wenn resizeMethod auf Scale eingestellt ist, sollte es kein Downsampling ermöglichen.

Der Code in RN scheint mir korrekt zu sein https://github.com/facebook/react-native/blob/aee88b6843cea63d6aa0b5879ad6ef9da4701846/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java#L505 ( es würde einen Nullwert an imagepipeline übergeben, was darauf hinweist, dass keine Größenänderung/Downsampling erfolgt)
Aber in Fresko werden die null resizeOptions nicht respektiert https://github.com/facebook/fresco/blob/v2.0.0/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java#L158 - L169
Wenn sowohl downsampleEnabled als auch downsampleEnabledForNetwork wahr sind, wird ein Downsampling durchgeführt, unabhängig davon, ob resizeOptions null sind
https://github.com/facebook/fresco/blob/master/imagepipeline-base/src/main/java/com/facebook/imagepipeline/transcoder/DownsampleUtil.java#L56
Es scheint mir also eine Diskrepanz zwischen dem Dokument und dem Code zu sein. Und wir brauchen einen flexibleren Weg, um zu steuern, ob ein bestimmtes Bild ein Downsampling erhalten soll. (jetzt wird es von 2 globalen Konfigurationen gesteuert) @clytras @oprisnik

Schöne Arbeit dort @sunnylqm. Ich habe angefangen, die RN-Konfiguration nach der Komponente <Image/> zu suchen und zu verfolgen, um diese Dinge zu überprüfen, aber Sie haben mich überfordert!

Da es eine solche Verhaltensänderung gibt, denke ich, dass jedes Fresko das Downsampling nur überprüfen und anwenden sollte, wenn resizeOptions nicht null ist; was nur gesetzt wird, wenn resizeMethod auf resize (oder auto und für lokale Bilder), was in https://github.com/facebook/react- überprüft wird. shouldResize Funktion, oder es sollte eine neue resizeMethod Aufzählung geben Option zum gezielten Downsampling.

Hallo, anscheinend gab es in letzter Zeit keine Aktivitäten zu diesem Thema. Wurde das Problem behoben oder erfordert es immer noch die Aufmerksamkeit der Community? Dieses Problem kann geschlossen werden, wenn keine weitere Aktivität auftritt. Sie können dieses Problem auch als "Fehler" oder "Erweiterung" bezeichnen und ich werde es offen lassen. Vielen Dank für Ihre Beiträge.

@clytras kannst du deine Lösung verraten?

@club9822 Die Lösung für den https://github.com/facebook/fresco/issues/2397#issuecomment -541802753

Gibt es eine Problemumgehung dafür, ohne die Kernbibliotheken neu zu kompilieren?

@CaptainN Es gibt keine einfache Lösung für dieses Problem. Der Prozess des Kompilierens der Quellen mag schwierig und mühsam erscheinen, aber es ist tatsächlich eine Frage kleiner Änderungen und Ausführen von Befehlen. Folgen Sie meinen Beiträgen in dieser Ausgabe, um herauszufinden, wie Sie es machen.

@clytras Sie können config im zweiten Argument in new PackageList(this, config)
Und ich habe versucht, es funktionierte tatsächlich wie erwartet. Das Problem ist, dass die Logik hier einfach die Konfiguration ignoriert https://github.com/facebook/fresco/blob/v2.0.0/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java#L158 -L169 wenn es false
Es sollte so sein oder?

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

@oprisnik

@sunnylqm Ich bin nicht im Büro und kann jetzt nicht nachsehen, aber ich erinnere mich, dass ich keinen Weg finden konnte, die Konfiguration mit dem neuen _RN >= 60_ Auto-Link-System zu übergeben. Ich bin mir aber nicht sicher. Bei mir hat es nicht einmal für ältere _RN_-Versionen funktioniert. Ich schaue in ein paar Tagen nach, wenn ich aus dem Urlaub zurückkomme.

Ich glaube, dass die Änderung von ODER zu UND das Problem lösen wird, da es ziemlich offensichtlich ist, dass das Downsampling jetzt immer dann angewendet wird, wenn der Status nicht das Flag IS_RESIZING_DONE sodass mDownsampleEnabled vollständig umgangen wird. Dies ist natürlich der Fall, wenn die benutzerdefinierte Fresco-Konfiguration, die das Downsample deaktiviert, angewendet und an Fresco übergeben wird.

@clytras Ich

Ach vergiss es. Es ist unhöflich, überhaupt zu fragen. Ich werde es herausfinden und vielleicht eine PR einreichen.

@CaptainN es ist nicht unhöflich. Die Sache ist, dass ich es getan und alle Fehler behoben habe, sodass es viel weniger Zeit in Anspruch nimmt, ein Starter-Repo mit Anweisungen zur Installation und zum Patchen von Fresco zu erstellen.

Hier ist es also: https://github.com/clytras/RN061FrescoBuild

Es hat RN 0.61.5 . Das Repo enthält detaillierte Anweisungen. Es klont Fresco, checkt v2.1.0 und wendet einen Patch auf DecodeProducer.java an, um den Downsampling-Code zu kommentieren. Sie müssen nur das Android NDK herunterladen und eine libraries/fresco/local.properties Datei hinzufügen. In der Readme ist alles ausführlich beschrieben.

Sie können fresco lib zu einem bestehenden RN >= 0.60 (_oder älteren Versionen_) Projekt hinzufügen, wenn Sie die Anweisungen und die Garnskripte befolgen.

@clytras Vielen Dank für die Zusammenstellung. Ich weiß es wirklich zu schätzen.

Gibt es ein Wort darüber, ob der obige Kommentar das Problem in Zukunft behandeln wird?

Ich habe die von @sunnylqm vorgeschlagene Änderung getestet :

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

und es stellte sich heraus, dass ich nach dieser Änderung das Bild-Downsampling deaktivieren konnte, indem ich nur die Konfiguration in MainApplication.java , was bedeutet, dass niemand Fresko kompilieren muss und nur dort die Fresko-Einstellungen ändern muss:

<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;
}

Nach dieser einzigen Änderung funktioniert der obige Konfigurationscode und deaktiviert das Downsampling. Wenn wir diese Konfiguration entfernen oder .setDownsampleEnabled(true) festlegen, wird das Downsampling ordnungsgemäß aktiviert. Das sieht für mich nach einem Fehler aus @oprisnik. Natürlich ist das Ideale für mich, dass RN resizeMethod respektiert und Downsampling dynamisch anwendet, aber ich bin mir nicht sicher, ob das möglich ist.

BEARBEITEN

Eigentlich lag ich teilweise falsch. Mit dieser Änderung (_was total Sinn macht_) setzt RN .setDownsampleEnabled(false) wie wir hier sehen können ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java#L155 , also in Um das Downsampling zu aktivieren, müssen wir fresco mit dem obigen Code konfigurieren und .setDownsampleEnabled(true) festlegen. RN hat das Downsampling standardmäßig deaktiviert!

@clytras @CaptainN Vielen Dank für Ihre Arbeit zu diesem Thema. Ich erlebe es, benutze Expo und freue mich sehr darauf, eine Lösung zu finden, möglichst ohne meine App auszuwerfen.

reaktive-native-cli: 2.0.1
reaktiv: 0.61.2

Kleines Update. Dieses Problem ist mir schon lange nicht mehr begegnet. Ich bin mir jedoch nicht sicher, ob dies daran liegt, dass ich für die meisten Bilder auf 3 verschiedene Skalierungen desselben Bildes umgestellt habe ( @1x , @2x , @3x).

@enguerranws Ich habe überhaupt keine Erfahrung mit Expo. @gorvinsky Ich habe es gerade mit RN 0.61.5 getestet und es funktioniert nicht. Leider haben gebündelte Bildgrößen nie funktioniert. Es war das erste, was ich getestet habe, als ich zum ersten Mal mit diesem Problem konfrontiert wurde.

Ich habe eine React -Native-Community/Cli- Vorlage erstellt, die das RN 0.61.5-Projekt und die erforderlichen Änderungen enthält, um Fresco aus dem Quellcode zu erstellen. Dies ist eine einfache und schnelle Möglichkeit, ein neues RN-Projekt mit einem benutzerdefinierten Projektnamen und mit den erforderlichen Änderungen zum Kompilieren von Fresco aus dem Quellcode erstellen zu lassen. Es verwendet auch Android NDK Revision 21 und ich habe es unter macOS und Windows mit yarn 1.21 getestet.

Github-Repository: clytras/react-native-fresco
NPM-Vorlage: @lytrax/react-native-fresco

Es kann wie folgt installiert werden:

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

Eine ausführliche Installationsanleitung finden Sie in der README . Sie müssen Fresco mit yarn fresco-setup klonen/patchen und dann Android NDK installieren und android/libraries/fresco/local.properties mit dem Android NDK-Pfad erstellen.

Ist dies ein Commit bei der Reaktivnativen Behebung dieses Problems? (vorerst nicht freigegeben)

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

In der Beschreibung steht, dass wir eine PipelineConfig übergeben können, die ein "setDownsampleEnabled"-Attribut hat.

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

@enguerranws Ich habe überhaupt keine Erfahrung mit Expo. @gorvinsky Ich habe es gerade mit RN 0.61.5 getestet und es funktioniert nicht. Leider haben gebündelte Bildgrößen nie funktioniert. Es war das erste, was ich getestet habe, als ich zum ersten Mal mit diesem Problem konfrontiert wurde.

Ich habe eine React -Native-Community/Cli- Vorlage erstellt, die das RN 0.61.5-Projekt und die erforderlichen Änderungen enthält, um Fresco aus dem Quellcode zu erstellen. Dies ist eine einfache und schnelle Möglichkeit, ein neues RN-Projekt mit einem benutzerdefinierten Projektnamen und mit den erforderlichen Änderungen zum Kompilieren von Fresco aus dem Quellcode erstellen zu lassen. Es verwendet auch Android NDK Revision 21 und ich habe es unter macOS und Windows mit yarn 1.21 getestet.

Github-Repository: clytras/react-native-fresco
NPM-Vorlage: @lytrax/react-native-fresco

Es kann wie folgt installiert werden:

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

Eine ausführliche Installationsanleitung finden Sie in der README . Sie müssen Fresco mit yarn fresco-setup klonen/patchen und dann Android NDK installieren und android/libraries/fresco/local.properties mit dem Android NDK-Pfad erstellen.

Gibt es eine Möglichkeit, es in ein bestehendes Projekt zu implementieren?

@kalmahik
Versuchen Sie es auf diese Weise. (Meine RN ist v0.61.4)
Auf diese Weise können Sie den Patch von @clytras auf ein vorhandenes Projekt anwenden.
Und der Android-Simulator kann nicht mehr ausgeführt werden. Ich teste immer auf echten Geräten. 😢

  1. Skripte zu package.json hinzufügen
"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. Patches erstellen/DecodeProducer.java.diff

'Garn Fresko-Patch'

Ergebnis

@@ -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. Android/settings.gradle bearbeiten

includeBuild ('libraries/fresco') vor include ':app'

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

include ':app'

  1. android/build.gradle

Die Gradle-Abhängigkeit ist 3.4.1

dependencies {
  ...
  classpath("com.android.tools.build:gradle:3.4.1")
  ...
}
  1. Skript ausführen

yarn fresco-setup

  1. Android ndk herunterladen

Ich habe die r21-Version verwendet.

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

  1. Entpacken und verschieben Sie das ndk

NDK entpacken
Ich habe ndk in Users/YOURNAME/Library/Android/android-ndk-r21 entpackt
Und erstelle android/libraries/fresco/local.properties in deinem Projekt

ndk.dir=/Users/YOURNAME/Library/Android/android-ndk-r21
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
  1. Android ausführen

Das ist alles.

yarn android und überprüfen Sie die große Bildqualität.

Danke an @clytras

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

@JeffGuKang
Was ist der file-patch Befehl?

Was hält dies davon ab, zusammengeführt zu werden? Warum brauchen wir diese Patches, anstatt sie nur zu reparieren (vorausgesetzt, es ist nicht nur eine Zeitbeschränkung - das verstehe ich völlig, ich versuche nicht aufdringlich zu sein)?

@kalmahik file-patch ist ein CLI-Patch-Tool für NPM-Pakete.

@JeffGuKang Sie müssen die Änderungen in package.json , die für die Funktion der Vorlagen-Setup-Skripte erforderlich sind.

@CaptainN Ich glaube nicht, dass es so einfach ist, obwohl ich noch keine Zeit hatte, die oben genannten Commits zu testen.

@clytras oh diese ein ? Vielen Dank)

@kalmahik
Versuchen Sie es auf diese Weise. (Meine RN ist v0.61.4)
Auf diese Weise können Sie den Patch von @clytras auf ein vorhandenes Projekt anwenden.
Und der Android-Simulator kann nicht mehr ausgeführt werden. Ich teste immer auf echten Geräten. 😢

  1. Skripte zu package.json hinzufügen
"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. Patches erstellen/DecodeProducer.java.diff

'Garn Fresko-Patch'

Ergebnis

@@ -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. Android/settings.gradle bearbeiten

includeBuild ('libraries/fresco') vor include ':app'

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

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

Die Gradle-Abhängigkeit ist 3.4.1

dependencies {
  ...
  classpath("com.android.tools.build:gradle:3.4.1")
  ...
}
  1. Skript ausführen

yarn fresco-setup

  1. Android ndk herunterladen

Ich habe die r21-Version verwendet.

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

  1. Entpacken und verschieben Sie das ndk

NDK entpacken
Ich habe ndk in Users/YOURNAME/Library/Android/android-ndk-r21 entpackt
Und erstelle android/libraries/fresco/local.properties in deinem Projekt

ndk.dir=/Users/YOURNAME/Library/Android/android-ndk-r21
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
  1. Android ausführen

Das ist alles.

yarn android und überprüfen Sie die große Bildqualität.

Danke an @clytras

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

Ich habe dieses Problem, wenn ich versuche, Fresco aus dem Quellcode nach dem @clytras- Skript zu kompilieren. Ich kompiliere es in ein vorhandenes RN(v0.59.9)-Projekt

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

Habe auch versucht, Fresco Config zu MainApplication.java hinzuzufügen, aber kein Glück dort

@ravali121 Diese Schritte gelten für RN >= 0.60.x, nicht für RN 0.59 oder ältere Versionen. Es kann für ältere RN-Versionen gepatcht werden, aber die Schritte und der Fresco-Checkout sollten der Version folgen, die mit dieser spezifischen RN-Version geliefert wird. Ich teste Fresco 2.1.0 für RN 0.61 und RN 0.59 hat eine andere Version und natürlich einen anderen Patch, obwohl der Patch nicht notwendig ist, die Codeänderungen können manuell durch Bearbeiten von DecodeProducer.java angewendet werden. Außerdem gibt es zusätzliche Gradle-Konfigurationen, um Abhängigkeiten zu handhaben.

Obwohl Sie es mit 0,59 zum Laufen bringen können, schlage ich vor, dass Sie Ihr Projekt/Ihre Projekte auf mindestens 0,61 (oder besser 0,62) aktualisieren.

Hallo! Irgendein Update zu einer ETA für den zusammenzuführenden Patch? (Danke @clytras für die tolle Arbeit, ich muss deinen Patch so

@FRizzonelli der Patch ist ein Workaround, er ist nicht wirklich eine Lösung für das Problem und deshalb bleibt dieses Problem so lange offen.
Ich muss den Patch und die @react-native-community/cli Vorlage überprüfen und auf die neueste RN-Version aktualisieren.

@clytras Ich verstehe :( Das Problem ist, dass ich gerade versuche, einen kleinen POC mit React-Native-Web auf Expo

@clytras Ich verstehe :( Das Problem ist, dass ich gerade versuche, einen kleinen POC mit React-Native-Web auf Expo

Wie wäre es, das Format jpg anstelle von png ? Ich bin mir nicht sicher, ob das Problem gelöst werden kann.

@clytras Ich verstehe :( Das Problem ist, dass ich gerade versuche, einen kleinen POC mit React-Native-Web auf Expo

Wie wäre es, das Format jpg anstelle von png ? Ich bin mir nicht sicher, ob das Problem gelöst werden kann.

Funktioniert leider auch nicht und ich benötige png für die Alphaebene :(

Ich habe das gleiche Problem mit RN 0.63.4.
Die Bildgröße von 960 x 13983 ist stark heruntergesampelt, die Texte im Bild können kaum gelesen werden.
Die Bildgröße von 680 x 2538 ist ebenfalls verkleinert, aber recht ordentlich.
Ich habe Image.getSize verwendet, um die Größe des Bildes herauszufinden und die Höhe daraus zu berechnen (Breite ist 100%).
Bilder sind alle jpg.
Ich habe @clytras ‚s Methode mit gradle 3.5.4, NDK 21.4.7075529. Aber gleiches Problem.

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

Wir haben das Problem mit FastImage gelöst. Ich hoffe, es würde helfen.

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

@JJMoon Wissen Sie, wie man FastImage erzwingt, das Bild neu zu rendern, wenn ich die Bildgröße im Stil ändere.
Das Bild wird immer neu gerendert, FastImage jedoch nicht.

Hallo zusammen,

Ich habe alle möglichen Lösungen aus diesem Thread ausprobiert, aber mit RN 0.64.2 und Fresco 2.5.0.
Ich verwende NDK v22.1.7171670 und Gradle 4.2.1.

Ich stecke derzeit bei folgendem Fehler fest (hängt das Problem mit dem Android-Emulator zusammen?):

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 , das FastImage mit lokalen Bildern (erforderlich) verwendet, hat mir ein schlechtes Flackern beschert.

Während ich darauf warte, dass das Team dieses Problem behebt, verwende ich sowohl Image als auch FastImage so.
if(height < blurSize){ return <Image/> }else{ return <FastImage/> }

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

sungerk picture sungerk  ·  3Kommentare

qiiyue picture qiiyue  ·  4Kommentare

rhettor picture rhettor  ·  3Kommentare

hbzhzw picture hbzhzw  ·  3Kommentare

goodev picture goodev  ·  4Kommentare