【问题标题】:React Native 0.57.x <Image/> large images low qualityReact Native 0.57.x <Image/> 大图像质量低
【发布时间】:2019-04-23 10:42:59
【问题描述】:

即使使用resizeMethod="resize",加载大型捆绑图像时质量也确实很差。 这仅发生在 Android 上,不会发生在任何 iOS 模拟器/设备上。已在 Android 8.1 模拟器和带有 Android 8.0 的 LG G6 上对其进行了测试。请看下面的截图。

在左侧屏幕截图中,我们看到使用 RN 0.56.0 运行的完全相同的代码,在右侧屏幕截图中,我们看到 RN 0.57.5。代码只是一个简单的图像&lt;Image source={require('./assets/ELHall1.png')} resizeMethod="resize" /&gt;,图像大小为2111 x 4645 pixels。这两个项目都是使用react-native init RN057ImageTestreact-native init --version="0.56.0" RN056ImageTest 全新安装的。

带有图片的简单应用

...
type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        {/*<Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>*/}
        <Image source={require('./assets/ELHall1.png')} resizeMethod="resize" />
      </View>
    );
  }
}
...

自 9 月以来,我已经为 RN 回购创建了一个 Github issue,但没有人回复,这让我觉得我做错了什么。在 RN 0.57.x 中是否有新的道具或其他方法可以使大图像以全质量正常显示?也许 Metro obuilder 更新到 0.57.x 改变了捆绑器处理图像资产的方式?我已经使用 resizeMethod 道具到 "scale""resize" 完全没有区别。我使用了PNG8PNG24PNG32,结果都一样。

编辑

Github repo 带有代码和 PNG 图像文件:https://github.com/clytras/RN057ImageTest

请不要给出关于 JPEG 图像的任何答案,并且它们确实有效,我 already know that;我想让 PNG 图像像在 RN 0.56 中一样工作。

2020 年 1 月更新

这是关于此问题的更新。

RN Issue 自 2019 年 8 月 10 日起已关闭,并声明这是not a React Native issue,而是一个 Fresco 问题。

我在 2019 年 8 月 22 日创建了一个 issue at Fresco,经过一些对话和讨论,目前禁用图像下采样的唯一方法是在删除/注释掉 DecodeProducer.java 中的下采样代码后从源代码编译 Fresco .

我创建了一个包含 RN 0.61 的存储库,并详细说明了如何编译 Fresco 和禁用图像下采样。可以在此处找到存储库:https://github.com/clytras/RN061FrescoBuild

事实证明,Fresco 有一个错误,并且在 MainApplication.java 中使用 ImagePipelineConfigMainPackageConfig 无法应用 Fresco 配置,您可以查看有关此 here 的更多详细信息。 RN 默认禁用下采样!在 Fresco 修复此问题之前,禁用图像下采样的唯一方法是在删除下采样代码后从源代码编译 Fresco。

2020 年 2 月更新

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

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

可以这样安装:

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

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

【问题讨论】:

  • resizeMode="contain" 怎么样?另外,如果您在样式中添加 maxWidth:"100%" 属性会怎样?如果没有任何效果,那么我相信问题可能出在其他地方,也可能是某些设置在以特定方式控制 dpi 或缩放的设备中?
  • @LastBreath 我知道 EN 图像缩放,但我没有尝试过。我会尽快试一试,我会在这里回复。另外,我不关心contain resizeMode
  • @LastBreath resizeMode 选项都不能解决质量问题。将宽度设置为 100% 也无济于事,并且质量不佳。这是不可能的,设备设置/功能在这里不相关。不要忘记它可以在使用 RN 0.56 的相同设备/模拟器上完美运行。
  • 你尝试过 width 还是 maxWidth ?
  • @LastBreath maxWidth 也不起作用。我已经上传了一个 github 仓库。如果需要,请检查问题以获取链接。

标签: android reactjs react-native components bundler


【解决方案1】:

我测试了FastImage,它的质量更好

<FastImage source={require('./assets/ELHall1.png')} style={{height: '100%', aspectRatio: 2.5}} />

【讨论】:

  • 我知道 FastImage;我不将它用于捆绑资产,我只将它用于远程图像。我的问题/问题是,为什么大的捆绑图像适用于 RN 0.56 &lt;Image/&gt; 而不要使用 RN 0.57.x &lt;Image/&gt;
  • 使用 FastImage imo 仍然模糊
【解决方案2】:

在大多数情况下,重要的是图像的尺寸,UI 设计师将设计用于标准高端手机(具有固定屏幕尺寸)并将图像导出为 .png 到 xhdpi、xxhdpi 和 xxxhdpi 分辨率。因此,开发人员通过将@1x、@2x 和@3x 附加到这些分辨率来重命名这些图像。示例:ELHall1@1x ,ELHall1@2x, ELHall1@3x

导入图像时使用图像的标准名称。 Example: ELHall1.png.

要解决&lt;Image&gt; 标签的问题,我大部分时间都使用 React-Native 中的Dimension API 来自动设置图像的宽度和高度。

示例:var {height, width} = Dimensions.get('window');

例如,如果图像必须覆盖整个屏幕,我会这样做,

 <View style={{flex:1,width:"100%",height:"100%"}}>
    <Image style={{width:width, height:height}} source={require('./assets/ELHall1.png')}  /> 
    // width & height is auto taken using Dimension API
    // To play around pixels use resizeMode= ("contain","center") (Keep this as last option)
  </View>

希望能帮到你。

【讨论】:

  • 我不想只覆盖整个屏幕,我想以自然大小显示图像,问题在于质量。在 RN 0.56 中它显示没有问题,但在 RN 0.57 中它失去了质量。
  • 那么在这种情况下使用 resizeMode:"center" 而不是别的。它将图像限制为其实际大小。
  • 我试一试,我会在这里回复
  • 我在之前的评论中犯了一个小错误,它的resizeMode='center'。它应该用作图像道具。
  • 不幸的是,resizeMode 选项都不起作用,center 也不起作用。我尝试使用 @xX 名称 ELHall1@1xELHall1@2xELHall1@3x 创建副本,但质量仍然相同。
【解决方案3】:

这是将@clytras 的补丁应用到现有项目的方法。 而且它不能再运行android模拟器了。我总是在真实设备上进行测试。 ?

  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')

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

原来我的回答:https://github.com/facebook/fresco/issues/2397#issuecomment-626631033

【讨论】:

    【解决方案4】:
    type StyledImageProps = {
      draftsMode: boolean;
      height: number;
      width: number;
    };
    
    export const StyledImage = styled(FastImage)<StyledImageProps>`
      height: ${({ height }) => `${height}px`};
      margin: ${({ draftsMode }) => (draftsMode ? '8px' : '0')};
      width: ${({ width }) => `${width}px`};
    `;        
    
    
    
    <ImageZoom
          cropWidth={width}
          cropHeight={height}
          imageWidth={width}
          imageHeight={height}
          >
          <StyledImage
            draftsMode={draftsMode}
            height={height}
            resizeMode="contain"
            source={{ uri: poster }}
            width={width}
            key={asset.id}
            style={{ height: height, width: width }}
          />
        </ImageZoom>
    

    这就是它对我的工作方式,它根本不会影响图像的质量,无论我放大图像多少

    【讨论】:

      【解决方案5】:

      使用“ImageBackground”代替大图像。

      import {
        ImageBackground,
      } from 'react-native';
      
      
      <ImageBackground source={require('./assets/ELHall1.png')} style={{width: '100%', height: '100%'}}></ImageBackground>
      

      【讨论】:

      • 仍处于低质量状态
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2014-10-14
      • 2019-08-23
      • 2021-06-16
      相关资源
      最近更新 更多