Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache ignores ColorMapper differences. #901

Closed
abigotado opened this issue Apr 7, 2023 · 1 comment · Fixed by #902
Closed

Cache ignores ColorMapper differences. #901

abigotado opened this issue Apr 7, 2023 · 1 comment · Fixed by #902

Comments

@abigotado
Copy link

I am converting SVG picture to BitmapDescriptor for Google Maps. But I have found it impossible to change color of the created icons dynamically. I can change colors using ColorMapper when first time creating my icon from SVG. But if I try to create another icon from the same SVG with other colors - it doesn't work. ColorMapper change colors only once per asset.

Is there any way to change color dynamically every time I need?

Some pieces of code:

Converter of SVG:

/// Utility for converting SVG.
class SvgConverter {
  /// Converts SVG to [BitmapDescriptor].
  static Future<BitmapDescriptor> getBitmapDescriptorFromSvgAsset(
    final String assetName, {
    final Size size = const Size(32, 32),
    final ColorMapper? colorMapper,
  }) async {
    final PictureInfo pictureInfo = await vg.loadPicture(
      SvgAssetLoader(assetName, colorMapper: colorMapper),
      null,
    );

    final double devicePixelRatio = ui.window.devicePixelRatio;
    final int width = (size.width * devicePixelRatio).toInt();
    final int height = (size.height * devicePixelRatio).toInt();

    final double scaleFactor = min(
      width / pictureInfo.size.width,
      height / pictureInfo.size.height,
    );

    final ui.PictureRecorder recorder = ui.PictureRecorder();

    ui.Canvas(recorder)
      ..scale(scaleFactor)
      ..drawPicture(pictureInfo.picture);

    final ui.Picture rasterPicture = recorder.endRecording();

    final ui.Image image = rasterPicture.toImageSync(width, height);
    final ByteData bytes =
        (await image.toByteData(format: ui.ImageByteFormat.png))!;

    return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
  }
}

ColorMapper:

/// Default color mapper for inverting icon's colors.
const SvgColorMapper defaultColorMapper = SvgColorMapper(
  mainColor: Color(0xFF3581B8),
  oldMainColor: Colors.white,
  secondaryColor: Colors.white,
  oldSecondaryColor: Color(0xFF3581B8),
);

These way I always get non-colored icon (original SVG - both from footballIcon and footballIconDark):

footballIcon = await SvgConverter.getBitmapDescriptorFromSvgAsset(
        'assets/icons/map_icons/football.svg',
);
footballIconDark = await SvgConverter.getBitmapDescriptorFromSvgAsset(
        'assets/icons/map_icons/football.svg',
        colorMapper: defaultColorMapper);

result:
Снимок экрана 2023-04-07 в 16 48 29

If I change the sequence - I will always get colored one (with mapper - both from footballIcon and footballIconDark):

footballIconDark = await SvgConverter.getBitmapDescriptorFromSvgAsset(
        'assets/icons/map_icons/football.svg',
        colorMapper: defaultColorMapper);
footballIcon = await SvgConverter.getBitmapDescriptorFromSvgAsset(
        'assets/icons/map_icons/football.svg',
);

result:
Снимок экрана 2023-04-07 в 16 50 02

And no way to change colors once more for this asset.

@dnfield
Copy link
Owner

dnfield commented Apr 7, 2023

This is a caching bug. The cache needs to take the ColorMapper into account. Right now it's not.

@dnfield dnfield changed the title Is it possible to change Svg color dynamically when converting to Bitmap? Cache ignores ColorMapper differences. Apr 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants