Fresco: 低图像质量使用<image/> RN 上的组件 &gt; = 0.57(Fresco &gt;= 1.10.0)

创建于 2019-08-22  ·  57评论  ·  资料来源: facebook/fresco

描述

RN 问题: RN 0.57.x 使用\查看时捆绑的大图像质量低

仅在 Android 上加载大型捆绑(PNG、GIF 和可能更多格式,而不是 JPEG )图像时质量较低:

在左侧屏幕截图中,我们看到使用RN 0.56.0运行的完全相同的代码,在右侧屏幕截图中,我们看到RN 0.57.1 。 代码只是一个简单的图像<Image source={require('./assets/ELHall1.png')} resizeMethod="resize" />并且图像大小为2111 x 4645 pixels 。 这两个项目都是使用react-native init RN057ImageTestreact-native init --version="0.56.0" RN056ImageTest全新安装的。 从 0.56 以及最新的 RN 0.60.x 之后的所有版本都会继续发生这种情况。

这被证实是由 RN Fresco lib 从 1.9.0 到 1.10.0 https://github.com/facebook/react-native/commit/b6f2aad9c0119d11e52978ff3fa9c6f269f04a14 在 0.56 和 0.57 之间的变化引起的。 检查评论 https://github.com/facebook/react-native/issues/21301#issuecomment-520155609。

在 Fresco 问题上进行了一些搜索后,我可以看到一些相关的问题,建议将大图像一块一块地分割和重新组合,它解决了许多情况(大多数与地图相关的大图像)但它可能非常不方便,尤其是对于动态加载/创建图像。 这一直工作到 RN 0.56 和从 0.57 开始,之后就没有了。

再生产

RN:这是最初的App.js加上<Image/>组件。

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

附加信息

在此评论https://github.com/facebook/react-native/issues/21301#issuecomment-520418832, lambdapioneer写道,这可能是有关缩减(子采样)大图片:

我认为这与 Fresco 如何缩小(子采样)大图像有关(这是内存和性能问题的重要功能)。 在那段时间里,这些区域发生了一些变化,主要是为了删除本机代码依赖项,以帮助减少同样紧迫的 .so 不满意链接错误。 可以这么说:这可能是另一项重大改进的副作用。

  • 壁画版本:>= 1.10.0
  • 平台版本:RN >= 0.57,所有安卓版本
enhancement

最有用的评论

@CaptainN这并不粗鲁。 问题是我已经完成并解决了所有错误,因此我将花费更少的时间来制作包含有关如何安装和修补 Fresco 的说明的入门存储库。

所以这里是: https :

它有RN 0.61.5 。 回购有详细说明。 它克隆 Fresco,检查v2.1.0并将补丁应用到DecodeProducer.java以便注释掉下采样代码。 您只需要下载 Android NDK 并添加一个libraries/fresco/local.properties文件。 自述文件中都有详细说明。

如果您按照说明和纱线脚本操作,您可以将 fresco lib 添加到现有的 RN >= 0.60(_或旧版本_)项目中。

所有57条评论

您好,最近好像没有关于这个问题的活动。 问题已经解决了,还是仍然需要社区的关注? 如果没有进一步的活动发生,这个问题可能会被关闭。 您也可以将此问题标记为“错误”或“增强”,我将保持开放状态。 感谢你的贡献。

RN 0.56.0 和 0.57.1​​ 使用哪些 Fresco 版本? 这缩小了可能导致这种情况的提交数量。

你好@oprisnik

当我回到我的办公室时,我会检查并查看升级的确切版本补丁,尽管我认为https://github.com/facebook/react-native/issues/21301#issuecomment -520155609 报告准确从哪个版本获得了这种行为改变。

@clytras ,我在这个存储库的屏幕上找到了图像。
我下载了图片,发现图片是2111(宽)*4645(高)。

Fresco 将对图像进行下采样以适应 OpenGL 限制,默认图像的最大宽度/高度在这一行中是硬编码的。

在我看来,
简单的方法是更改​​ ResizeOption 的 maxBitmapSize 字段。
正确的方法是不要使用 Fresco 来显示非常大的图像。

创建另一个小部件,并使用这个来显示非常大的图像是许多 android 团队的选择。

@s1rius ,如果您阅读未解决的问题帖子,我会精确地写出图像大小:

代码只是一个简单的图像并且图像大小为 2111 x 4645 像素

这是关于从 RN >= 0.57 发生的行为变化,从 Fresco 1.9.0 到 1.10.0。 在那个版本之前,像这样的大图像可以正常工作并以完整质量加载。 RN repo 的贡献者关闭了这个问题,因为他们声明这不是 RN 问题而是 Fresco lib 问题。 如果故意做出这种行为改变,那么我们可以关闭这个问题。 是的,有一些解决方法,但它一直工作到一个版本,突然间,没有任何关于原因的信息,停止工作。

您好,最近好像没有关于这个问题的活动。 问题已经解决了,还是仍然需要社区的关注? 如果没有进一步的活动发生,这个问题可能会被关闭。 您也可以将此问题标记为“错误”或“增强”,我将保持开放状态。 感谢你的贡献。

在长时间不活动后关闭此问题。 如果最新版本中仍然存在此问题,请随时重新打开并提供最新信息。

可能导致这种情况的潜在变化是https://github.com/facebook/fresco/commit/fa71901055a38a810c190862c7fd582fd3dad2b3

你能验证这是否是违规更改吗?

再次您好@oprisnik ,感谢您对此进行调查。

我不太熟悉 gradle 以及如何更改 RN 以直接从源代码编译 fresco 而不是下载库。 我没有成功采取的步骤:

  1. 使用react-native-cli创建 RN 0.57 项目
  2. Clone fresco lib 到项目根目录
  3. 结帐到 fresco lib 内的v1.10.0分支
  4. android-ndk-r20路径添加到<Project>\android\local.properties ( ndk.dir=G:\\Dev\\Android\\android-ndk-r20 )

然后我在 SO https://stackoverflow.com/a/52861379/1889685 上找到了这个答案,它使用源代码的 fresco 编译 RN 并覆盖库:

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

但我收到以下错误:

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

如果他有时间的话,也许@sunnylqm可以测试一下,因为他对这个过程更加熟悉。

如果有帮助,我可以用我目前拥有的东西创建一个 repo。

您好,最近好像没有关于这个问题的活动。 问题已经解决了,还是仍然需要社区的关注? 如果没有进一步的活动发生,这个问题可能会被关闭。 您也可以将此问题标记为“错误”或“增强”,我将保持开放状态。 感谢你的贡献。

我尝试构建但也遇到了 ndk 错误。 你们有我们可以测试的每晚构建吗?

由于我可以不做任何修改编译v2.0.0,所以我尝试了另一种方式来验证。 我禁用了由上面的提交启用的下采样,这是结果

测试图像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"
      />

原版 v2.0.0 展示
image

禁用下采样 v2.0.0 展示
image

@sunnylqm感谢调试。 如何禁用下采样? 我尝试了以下方法但没有成功:

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

有了这个,我在 Logcat 收到一条消息,说 Fresco 已经初始化。

我通过用MainPackageConfig初始化MainReactPackage使用的第二种方法,但它也不起作用:

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我不知道。 我在源代码中禁用了它。

ping @oprisnik

看起来这是通过 React Native 主包配置设置的: https :

不确定您必须如何使用 RN 进行设置,从未尝试过。

@oprisnik有解决这个问题的计划吗?

我相信这个问题仍然属于 RN repo。 图像下采样毫无疑问是为了降低内存成本,提高效率并减少加载大图像时的粗鲁。 我认为这个问题应该由 RN 处理,它允许最终开发人员选择是否要以选项/属性的形式进行图像下采样。 例如,在我的应用程序中,我使用大图像来呈现一些平面图,当用户放大平面图时,我需要高分辨率。 我总是检查设备功能,如果它是具有较少 RAM 或低分辨率的低端设备,那么我会加载更小和更低分辨率的图像。

<Image/>组件有resizeMethod属性,它具有scaleresize 。 RN 当前不尊重该属性的scale值,我认为它应该禁用图像下采样,并且仅在将其设置为resize时才启用它。

resizeMethod

当图像的尺寸与图像视图的尺寸不同时应该用于调整图像大小的机制。 默认为自动。

resize :一种软件操作,它在解码之前更改内存中的编码图像。 当图像比视图大得多时,应该使用它而不是scale

scale :图像被缩小或放大。 与resizescale速度更快(通常是硬件加速)并生成更高质量的图像。 如果图像小于视图,则应使用此选项。 如果图像比视图稍大,也应该使用它。

我真的很想看看你对这个@oprisnik @sunnylqm 的想法。

@clytras正如您所说,这是壁画中的行为变化,无需解释。 (我展示的演示是 fresco repo 中的示例应用程序)所以我认为它与 RN 没有任何关系。

@sunnylqm当然,这是

另外不要忘记,这种行为变化当然不会发生在 iOS 中,所以我们必须对此做一些事情,而且由于 fresco 配置发生在 react native 中,那么我认为这个配置应该暴露给最终的 RN 开发人员。

顺便说一句,我设法用最新的 RN 0.61.2 编译了 Fresco 2.0.0(主分支),并像您一样通过在DecodeProducer.java 中注释掉下采样条件检查来禁用下采样。

我在 fresco repo 目录中创建了一个local.properties文件,并在 Windows 64 位上使用了Android NDK Revision 19c x86_64

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

Fresco 二进制文件已成功编译,并且已为通过运行构建的 RN 应用程序禁用图像下采样:

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

是的,解决方案是通过 RN 初始化逻辑或在 Fresco 初始化时禁用应用程序的下采样。

@oprisnik那么我认为我们需要一种更好、更干净、更简单的方法来在生成的 android 项目中初始化com.facebook.imagepipeline.core.ImagePipelineConfigcom.facebook.react.shell.MainReactPackagecom.facebook.react.shell.MainPackageConfig通过将配置传递给MainReactPackage来在getPackages方法中初始化它,但是在我尝试过的最新 RN 0.61 和 RN 0.57 中,这对我都不起作用:

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

也许我在那里做错了什么,这绝对不适用于新的 >= 0.60 链接系统,该系统在<project>/android/app/build/generated/rncli/src/main/java/com/facebook/react/目录中生成PackageList.java文件,因为MainReactPackage是没有任何参数传递,我看不到使用自动链接系统传递任何类型参数的方法,但我尝试通过 fresco 配置手动传递MainReactPackage并且这也不起作用。

我们需要一种干净且记录在案的方式来说明如何在为 React Native 生成​​的 android 项目中使用自定义配置初始化 fresco lib。

阅读https://frescolib.org/docs/resizing.html 后,如果我理解正确, downsamplingresizing的替代品。 所以@clytras我认为你是对的,如果 resizeMethod 设置为缩放它不应该启用下采样。

RN 中的代码对我来说似乎是正确的https://github.com/facebook/react-native/blob/aee88b6843cea63d6aa0b5879ad6ef9da4701846/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java#L505 (它会将一个空值传递给 imagepipeline,这表示没有调整大小/下采样)
但在壁画中它不尊重 null resizeOptions https://github.com/facebook/fresco/blob/v2.0.0/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java#L158 - L169
如果downsampleEnableddownsampleEnabledForNetwork都为真,它将被降采样,无论 resizeOptions 为空
https://github.com/facebook/fresco/blob/master/imagepipeline-base/src/main/java/com/facebook/imagepipeline/transcoder/DownsampleUtil.java#L56
所以对我来说,文档和代码之间似乎不匹配。 我们需要一种更灵活的方法来控制我们是否希望对特定图像进行下采样。 (现在它由 2 个全局配置控制) @clytras @oprisnik

干得好@sunnylqm。 我开始查看并跟踪<Image/>组件的 RN 配置以检查这些内容,但您超出了我的范围!

由于有这样的行为变化,我认为只有当resizeOptions不为空时,壁画才应该检查和应用下采样; 仅当resizeMethod设置为resize (或auto和用于本地图像)时才设置,在https://github.com/facebook/react- 中检查shouldResize函数,或者应该有一个新的resizeMethod enum专门用于下采样的选项。

您好,最近好像没有关于这个问题的活动。 问题已经解决了,还是仍然需要社区的关注? 如果没有进一步的活动发生,这个问题可能会被关闭。 您也可以将此问题标记为“错误”或“增强”,我将保持开放状态。 感谢你的贡献。

@clytras你能说出你的解决方案吗?

@club9822现在的解决方案是在首先禁用图像下采样后从源代码编译https://github.com/facebook/fresco/issues/2397#issuecomment -541802753

在不重新编译核心库的情况下,是否有解决方法?

@CaptainN这个问题没有简单的解决方案。 编译源代码的过程看似艰巨繁琐,但其实就是做一些小改动和执行命令。 按照我在这个问题上的帖子来了解你是如何做到的。

@clytras您可以在new PackageList(this, config)的第二个参数中传递配置
我试过它实际上按预期工作。 问题是这里的逻辑只是忽略了配置https://github.com/facebook/fresco/blob/v2.0.0/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/DecodeProducer.java#L158 -L169 如果是false
应该是这样吧?

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

@oprisnik

@sunnylqm我不在办公室,现在无法检查,但我记得我找不到使用新的 _RN >= 60_ 自动链接系统传递配置的方法。 我不确定。 对我来说,即使对于较旧的 _RN_ 版本也不起作用。 过几天我放假回来时会检查一下。

我相信 OR 到 AND 更改将解决问题,因为很明显,如果状态没有IS_RESIZING_DONE标志,则下采样现在始终适用,因此它完全绕过mDownsampleEnabled 。 当然,如果禁用下采样的自定义 fresco 配置被应用并传递给 fresco,情况就会如此。

@clytras我在 gradle 弃用和所有这些方面遇到了各种各样的错误。 你有没有机会发布一个预构建的二进制文件(并告诉我在哪里安装它)? 我真的很感激。

啊忘记了。 连问都是不礼貌的。 我会弄清楚的,也许会提交 PR。

@CaptainN这并不粗鲁。 问题是我已经完成并解决了所有错误,因此我将花费更少的时间来制作包含有关如何安装和修补 Fresco 的说明的入门存储库。

所以这里是: https :

它有RN 0.61.5 。 回购有详细说明。 它克隆 Fresco,检查v2.1.0并将补丁应用到DecodeProducer.java以便注释掉下采样代码。 您只需要下载 Android NDK 并添加一个libraries/fresco/local.properties文件。 自述文件中都有详细说明。

如果您按照说明和纱线脚本操作,您可以将 fresco lib 添加到现有的 RN >= 0.60(_或旧版本_)项目中。

@clytras 非常感谢你把它们放在一起。 对此,我真的非常感激。

关于上述评论将来是否会解决该问题,是否有任何消息?

我已经测试了@sunnylqm建议的更改:

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

事实证明,在那次更改之后,我可以仅使用MainApplication.java配置来禁用图像下采样,这意味着没有人必须编译 fresco 并且只需要更改那里的 fresco 设置:

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

在那次更改之后,上面的配置代码将起作用并禁用下采样。 如果我们删除该配置或设置.setDownsampleEnabled(true)那么它将正确启用下采样。 这对我来说似乎是一个错误@oprisnik。 当然,对我来说最理想的事情是 RN 尊重resizeMethod并动态应用下采样,但我不确定这是否可能。

编辑

其实我错了。 有了这个变化(_这完全有道理_),RN 设置.setDownsampleEnabled(false) ,我们可以在这里看到ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java#L155 ,所以,在为了启用下采样,我们必须使用上述代码配置 fresco 并设置.setDownsampleEnabled(true) 。 RN 默认禁用下采样!

@clytras @CaptainN非常感谢您在这个问题上所做的工作。 我正在体验它,使用 Expo,我真的很期待找到一个解决方案,如果可能的话,不会弹出我的应用程序。

反应原生cli:2.0.1
反应原生:0.61.2

小更新。 我已经很长时间没有遇到这个问题了。 但我不确定这是不是因为我已经切换到对大多数图像使用 3 种不同比例的同一图像( @1x@2x 、@3x)。

@enguerranws我完全没有使用 Expo 的经验。 @gorvinsky我刚刚使用 RN 0.61.5 对其进行了测试,但它不起作用。 不幸的是,捆绑的图像大小从未奏效。 这是我第一次遇到这个问题时测试的第一件事。

我创建了一个react-native-community/cli模板,其中包含 RN 0.61.5 项目和从源代码构建 Fresco 所需的修改。 这是一种使用自定义项目名称和从源代码编译 Fresco 所需的更改来制作新 RN 项目的简单快捷的方法。 它还使用Android NDK 修订版 21 ,我已经使用yarn 1.21在 macOS 和 Windows 上对其进行了测试。

Github 存储库: clytras/react-native-fresco
NPM 模板: @lytrax/react-native-fresco

它可以像这样安装:

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

README 中有详细的安装说明。 您需要使用yarn fresco-setup克隆/修补 Fresco,然后安装 Android NDK 并使用 Android NDK 路径创建android/libraries/fresco/local.properties

这是在 react-native 修复中提交的吗? (暂未发布)

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

在描述中,它说我们可以传递一个具有“setDownsampleEnabled”属性的 PipelineConfig。

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

@enguerranws我完全没有使用 Expo 的经验。 @gorvinsky我刚刚使用 RN 0.61.5 对其进行了测试,但它不起作用。 不幸的是,捆绑的图像大小从未奏效。 这是我第一次遇到这个问题时测试的第一件事。

我创建了一个react-native-community/cli模板,其中包含 RN 0.61.5 项目和从源代码构建 Fresco 所需的修改。 这是一种使用自定义项目名称和从源代码编译 Fresco 所需的更改来制作新 RN 项目的简单快捷的方法。 它还使用Android NDK 修订版 21 ,我已经使用yarn 1.21在 macOS 和 Windows 上对其进行了测试。

Github 存储库: clytras/react-native-fresco
NPM 模板: @lytrax/react-native-fresco

它可以像这样安装:

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

README 中有详细的安装说明。 您需要使用yarn fresco-setup克隆/修补 Fresco,然后安装 Android NDK 并使用 Android NDK 路径创建android/libraries/fresco/local.properties

有没有办法将它实施到现有项目中?

@kalmahik
试试这个方法。 (我的 RN 是 v0.61.4)
这是将@clytras的补丁应用到现有项目的方法。
它不能再运行安卓模拟器了。 我总是在真实设备上进行测试。 😢

  1. 将脚本添加到 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. 创建补丁/DecodeProducer.java.diff

'纱线壁画'

结果

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

include ':app'之前添加includeBuild ('libraries/fresco') include ':app'

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

include ':app'

  1. android/build.gradle

使用 gradle 依赖是 3.4.1

dependencies {
  ...
  classpath("com.android.tools.build:gradle:3.4.1")
  ...
}
  1. 运行脚本

yarn fresco-setup

  1. 下载安卓ndk

我用的是r21版本。

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

  1. 解压并移动 ndk

解压 NDK
我将 ndk 解压到Users/YOURNAME/Library/Android/android-ndk-r21
并在您的项目中创建android/libraries/fresco/local.properties

ndk.dir=/Users/YOURNAME/Library/Android/android-ndk-r21
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
  1. 运行安卓

就这样。

yarn android并检查大图像质量。

感谢@clytras

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

@JeffGuKang
file-patch命令是什么?

是什么阻止了它被合并? 为什么我们需要这些补丁而不是仅仅修复它(假设这不仅仅是时间限制——我完全明白这一点,而不是试图咄咄逼人)?

@kalmahik file-patch是一个 NPM 包 CLI 补丁工具。

@JeffGuKang您必须在package.json中包含模板设置脚本工作所需的更改。

@CaptainN我认为没那么简单,尽管我还没有时间测试上述提交。

@clytras哦,这一个? 谢谢)

@kalmahik
试试这个方法。 (我的 RN 是 v0.61.4)
这是将@clytras的补丁应用到现有项目的方法。
它不能再运行安卓模拟器了。 我总是在真实设备上进行测试。 😢

  1. 将脚本添加到 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. 创建补丁/DecodeProducer.java.diff

'纱线壁画'

结果

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

include ':app'之前添加includeBuild ('libraries/fresco') include ':app'

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

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

使用 gradle 依赖是 3.4.1

dependencies {
  ...
  classpath("com.android.tools.build:gradle:3.4.1")
  ...
}
  1. 运行脚本

yarn fresco-setup

  1. 下载安卓ndk

我用的是r21版本。

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

  1. 解压并移动 ndk

解压 NDK
我将 ndk 解压到Users/YOURNAME/Library/Android/android-ndk-r21
并在您的项目中创建android/libraries/fresco/local.properties

ndk.dir=/Users/YOURNAME/Library/Android/android-ndk-r21
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
  1. 运行安卓

就这样。

yarn android并检查大图像质量。

感谢@clytras

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

我在尝试按照@clytras脚本从源代码编译 Fresco 时遇到了这个问题。 我正在将它编译成一个现有的 RN(v0.59.9) 项目

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

另外,尝试将 Fresco Config 添加到 MainApplication.java 中,但没有运气

@ravali121这些步骤适用于 RN >= 0.60.x,不适用于 RN 0.59 或更旧版本。 它可以针对较旧的 RN 版本进行修补,但步骤和 Fresco 检出应遵循该特定 RN 版本附带的版本。 我正在检查 RN 0.61 的 Fresco 2.1.0 和 RN 0.59 有不同的版本,当然还有不同的补丁,虽然补丁不是必需的,代码更改可以通过编辑DecodeProducer.java手动应用。 此外,还有额外的 gradle 配置来处理依赖项。

尽管您可以使用 0.59 使其工作,但我建议您将项目升级到至少 0.61(或更好的 0.62)。

你好呀! 要合并补丁的 ETA 上有任何更新吗? (感谢@clytras 的出色工作,我需要尽快尝试您的补丁,但我想知道这是否会得到修复)

@FRizzonelli补丁是一种解决方法,它并不是真正解决问题的方法,这就是为什么这个问题会持续这么长时间。
我必须检查补丁和@react-native-community/cli模板并将其升级到最新的 RN 版本。

@clytras我明白:( 问题是现在我正在尝试在 Expo 上设置一个带有 react-native-web 的小型 POC,这对于 Android 有这个问题。对于一个小型演示,我不想弹出。但是我想我需要:(

@clytras我明白:( 问题是现在我正在尝试在 Expo 上设置一个带有 react-native-web 的小型 POC,这对于 Android 有这个问题。对于一个小型演示,我不想弹出。但是我想我需要:(

如何使用jpg格式而不是png ? 我不确定它可以解决这个问题。

@clytras我明白:( 问题是现在我正在尝试在 Expo 上设置一个带有 react-native-web 的小型 POC,这对于 Android 有这个问题。对于一个小型演示,我不想弹出。但是我想我需要:(

如何使用jpg格式而不是png ? 我不确定它可以解决这个问题。

不幸的是也不起作用,我需要 png 作为 alpha 层:(

我对 RN 0.63.4 有同样的问题。
960 x 13983 的图像大小被下采样很多,图像中的文本几乎无法阅读。
680 X 2538 的图像大小也被下采样,但相当不错。
我使用 Image.getSize 找出图像的大小,并从中计算高度(宽度为 100%)
图片都是jpg。
我用 gradle 3.5.4, NDK 21.4.7075529 做了@clytras的方法。 但是,同样的问题。

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

我们用 FastImage 解决了这个问题。 我希望它会有所帮助。

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

@JJMoon当我在样式中更改图像大小时,您知道如何强制 FastImage 重新渲染图像吗?
Image 总是重新渲染,但 FastImage 不会。

大家好,

我尝试了该线程中所有可能的解决方案,但使用的是 RN 0.64.2 和 Fresco 2.5.0。
我正在使用 NDK v22.1.7171670 和 gradle 4.2.1。

我目前遇到以下错误(问题是否与 android-emulator 相关?):

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使用带有本地图像(需要)的 FastImage 给我带来了糟糕的闪烁体验。

在等待团队解决此问题时,我同时使用 Image 和 FastImage
if(height < blurSize){ return <Image/> }else{ return <FastImage/> }

此页面是否有帮助?
0 / 5 - 0 等级