Skip to content

Specifying cacheWidth / cacheHeight can degrade the image quality #56239

@nioncode

Description

@nioncode

@iskakaushik asked me to post this as a separate issue from #48885.

When using the cacheWidth and cacheHeight parameters, the resulting image has less details than without using the parameters, although they are set to the same values as the image's width and height.

I was under the assumption that if I supply the same values to the cacheWidth / cacheHeight parameters as I do to the width / height parameters, then the quality should be exactly the same, but the cache uses the given dimensions instead of a possibly much larger native size. I thought the cache parameters are basically just a way to tell the engine that I will never draw the image in a higher resolution, so it is ok to cache it at the specified resolution in order to reduce memory footprint.

However, as the pictures below show, when using the cache parameters, the image gets drawn in less quality, which is especially visible on the edges (e.g. compare the e or the a).

Comparison pictures:

Without cache:
cache_no

With cache:
cache_yes

I stumbled upon this with a real picture in my app (that I can't share) and was wondering why it renders with these artifacts and found by chance that the artifacts are gone when I don't use the cache parameters. I originally noticed this on a Pixel 2, but the screenshots were taken from Android Emulator, where it is also clearly visible.

Sample code:

import 'package:flutter/material.dart';

void main() {
    runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(appBar: AppBar(title: Text('Test')),
        backgroundColor: Colors.black,
        body: Image.asset(
          'assets/test.png',
          width: 200,
          height: 200,
          cacheWidth: 200,
          cacheHeight: 200,
        ),
      ),
    );
  }
}

Source Image:

Logs
[  +40 ms] executing: [/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped/] git -c
log.showSignature=false log -n 1 --pretty=format:%H
[  +58 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%H
[        ] 0b8abb4724aa590dd0f429683339b1e045a1594d
[        ] executing: [/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped/] git describe --match
v*.*.* --first-parent --long --tags
[   +8 ms] Exit code 0 from: git describe --match v*.*.* --first-parent --long --tags
[        ] v1.12.13+hotfix.8-0-g0b8abb472
[   +5 ms] executing: [/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped/] git rev-parse
--abbrev-ref HEAD
[   +7 ms] Exit code 0 from: git rev-parse --abbrev-ref HEAD
[        ] stable
[  +36 ms] Artifact Instance of 'AndroidMavenArtifacts' is not required, skipping update.
[   +3 ms] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterWebSdk' is not required, skipping update.
[   +2 ms] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[  +26 ms] executing: /nix/store/mgb6pwg4r24l2y7qxfz9l4bfmn4p335i-android-studio-stable-3.6.3.0-unwrapped/jre/bin/java -version
[ +110 ms] Exit code 0 from: /nix/store/mgb6pwg4r24l2y7qxfz9l4bfmn4p335i-android-studio-stable-3.6.3.0-unwrapped/jre/bin/java
-version
[   +2 ms] openjdk version "1.8.0_212-release"
           OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
           OpenJDK 64-Bit Server VM (build 25.212-b4-5784211, mixed mode)
[  +11 ms] executing: [/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped/] git rev-parse
--abbrev-ref --symbolic @{u}
[   +7 ms] Exit code 0 from: git rev-parse --abbrev-ref --symbolic @{u}
[        ] origin/stable
[        ] executing: [/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped/] git ls-remote
--get-url origin
[   +7 ms] Exit code 0 from: git ls-remote --get-url origin
[        ] https://github.com/flutter/flutter.git
[  +19 ms] executing: [/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped/] git -c
log.showSignature=false log -n 1 --pretty=format:%ar
[   +8 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%ar
[        ] 3 months ago
[  +14 ms] executing: /home/nion/.cache/flutter/artifacts/engine/android-arm-profile/linux-x64/gen_snapshot
[  +16 ms] Exit code 255 from: /home/nion/.cache/flutter/artifacts/engine/android-arm-profile/linux-x64/gen_snapshot
[        ] At least one input is required
           Usage: gen_snapshot [<vm-flags>] [<options>] <dart-kernel-file>             

           Common options:                                                             
           --help                                                                      
             Display this message (add --verbose for information about all VM options).
           --version                                                                   
             Print the VM version.                                                     

           To create a core snapshot:                                                  
           --snapshot_kind=core                                                        
           --vm_snapshot_data=<output-file>                                            
           --isolate_snapshot_data=<output-file>                                       
           <dart-kernel-file>                                                          

           To create an AOT application snapshot as assembly suitable for compilation  
           as a static or dynamic library:                                             
           --snapshot_kind=app-aot-assembly                                            
           --assembly=<output-file>                                                    
           [--obfuscate]                                                               
           [--save-obfuscation-map=<map-filename>]                                     
           <dart-kernel-file>                                                          

           To create an AOT application snapshot as an ELF shared library:             
           --snapshot_kind=app-aot-elf                                                 
           --elf=<output-file>                                                         
           [--strip]                                                                   
           [--obfuscate]                                                               
           [--save-obfuscation-map=<map-filename>]                                     
           <dart-kernel-file>                                                          

           AOT snapshots can be obfuscated: that is all identifiers will be renamed    
           during compilation. This mode is enabled with --obfuscate flag. Mapping     
           between original and obfuscated names can be serialized as a JSON array     
           using --save-obfuscation-map=<filename> option. See dartbug.com/30524       
           for implementation details and limitations of the obfuscation pass.
[  +11 ms] executing: /nix/store/mgb6pwg4r24l2y7qxfz9l4bfmn4p335i-android-studio-stable-3.6.3.0-unwrapped/jre/bin/java -version
[  +45 ms] Exit code 0 from: /nix/store/mgb6pwg4r24l2y7qxfz9l4bfmn4p335i-android-studio-stable-3.6.3.0-unwrapped/jre/bin/java
-version
[        ] openjdk version "1.8.0_212-release"
           OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
           OpenJDK 64-Bit Server VM (build 25.212-b4-5784211, mixed mode)
[   +2 ms] java -version
⣽[ +124 ms] executing: /home/nion/opt/android-sdk/platform-tools/adb devices -l
[   +7 ms] Exit code 0 from: /home/nion/opt/android-sdk/platform-tools/adb devices -l
[        ] List of devices attached
           192.168.1.31:5555      device product:walleye model:Pixel_2 device:walleye transport_id:17
           emulator-5554          device product:sdk_phone_x86 model:Android_SDK_built_for_x86 device:generic_x86 transport_id:20 [   +6 ms] [✓] Flutter (Channel stable, v1.12.13+hotfix.8, on Linux, locale en_US.UTF-8)
[   +1 ms]     • Flutter version 1.12.13+hotfix.8 at
/nix/store/bxyz9r12vvlg2n37kmpk2rqjxi4s70gj-flutter-stable-1.12.13+hotfix.8-unwrapped
[   +1 ms]     • Framework revision 0b8abb4724 (3 months ago), 2020-02-11 11:44:36 -0800
[        ]     • Engine revision e1e6ced81d
[        ]     • Dart version 2.7.0
⣽[  +11 ms] /home/nion/opt/android-sdk/platform-tools/adb -s 192.168.1.31:5555 shell getprop
[  +65 ms] executing: /home/nion/opt/android-sdk/tools/bin/sdkmanager --licenses                                                  ⢿[ +211 ms] ro.hardware = walleye
[        ] ro.build.characteristics = nosdcard
[   +1 ms] /home/nion/opt/android-sdk/platform-tools/adb -s emulator-5554 shell getprop                                           ⡿[  +83 ms] ro.hardware = ranchu                                                                                                   ⣯
[+3572 ms] [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[        ]     • Android SDK at /home/nion/opt/android-sdk
[        ]     • Android NDK location not configured (optional; useful for native profiling support)
[        ]     • Platform android-29, build-tools 29.0.3
[        ]     • ANDROID_HOME = /home/nion/opt/android-sdk
[        ]     • Java binary at: /nix/store/mgb6pwg4r24l2y7qxfz9l4bfmn4p335i-android-studio-stable-3.6.3.0-unwrapped/jre/bin/java
[        ]     • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
[        ]     • All Android licenses accepted.
[        ] [✓] Android Studio (version 3.6)
[        ]     • Android Studio at /nix/store/mgb6pwg4r24l2y7qxfz9l4bfmn4p335i-android-studio-stable-3.6.3.0-unwrapped
[        ]     • Flutter plugin version 45.0.1
[        ]     • Dart plugin version 192.7761
[        ]     • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
[        ] [✓] Connected device (2 available)
[        ]     • Pixel 2                   • 192.168.1.31:5555 • android-arm64 • Android 10 (API 29)
[        ]     • Android SDK built for x86 • emulator-5554     • android-x86   • Android 10 (API 29) (emulator)
[        ] • No issues found!
[   +7 ms] "flutter doctor" took 4,508ms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: imagesLoading, displaying, rendering imagesa: qualityA truly polished experienceengineflutter/engine repository. See also e: labels.found in release: 3.7Found to occur in 3.7found in release: 3.8Found to occur in 3.8has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions