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

greyscale pngs appear inverted + transparent #15600

Closed
ltc opened this issue Mar 16, 2018 · 10 comments
Closed

greyscale pngs appear inverted + transparent #15600

ltc opened this issue Mar 16, 2018 · 10 comments
Labels
dependency: skia Skia team may need to help us engine flutter/engine repository. See also e: labels. waiting for PR to land (fixed) A fix is in flight

Comments

@ltc
Copy link

ltc commented Mar 16, 2018

When I try decoding greyscale pngs (1-channel, 8 bytes), they render as inverted transparent PNGs.

This may be an embedder client specific problem. This problem does not occur in the Android emulator (haven't tested this on other devices).

e.g.

final codec = await instantiateImageCodec(new Uint8List.fromList(imageBytes));
final image = await codec.getNextFrame();
// then render using RawImage widget.

Same problem occurs using Image.memory(imageBytes)

When I save the greyscale imageBytes to disk using file.writeAsBytes(imageBytes), I can see the expected image. Also using color pngs (3-channel, RGB) work fine.

Steps to Reproduce

Here is a reduced test case:

import 'dart:convert';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/widgets.dart';

final _base64 = '''
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA
B3RJTUUH4gMPATUy47+DrgAAAHZJREFUOMul0lEOgCAMA9CW+9+5/hgZ0m0h+KOJL7OrEEJ5EY0g
GkGgJnzv6kBKGJ7VAUu+NZmQ2UMSNxZlydok9zD/JjdCM3IxtLECIUoBDFOeOoANsAM4BaYYpT85
+YQuM8QRwx2s+zWB8oisb/IJOs2Q7fEAaioeHiHi+38AAAAASUVORK5CYII=
'''
    .replaceAll(new RegExp(r'\s'), '');

final _imageBytes = new Uint8List.fromList(base64.decode(_base64));

class BugWidget extends StatelessWidget {
  final ui.Image image;
  BugWidget(this.image);

  @override
  Widget build(BuildContext context) => new Container(
        color: const Color(0xffff0000),
        width: 1920.0,
        height: 1080.0,
        child: new Stack(
          children: <Widget>[
            new Positioned(
              left: 10.0,
              top: 10.0,
              child: new Image.memory(_imageBytes),
            ),
            new Positioned(
              left: 10.0,
              top: 40.0,
              child: new Text('Image.memory'),
            ),
            new Positioned(
              left: 10.0,
              top: 250.0,
              child: new RawImage(image: image),
            ),
            new Positioned(
              left: 10.0,
              top: 280.0,
              child: new Text('RawImage'),
            ),
          ],
        ),
      );
}

void main() async {
  final codec = await ui.instantiateImageCodec(_imageBytes);
  final frame = await codec.getNextFrame();

  runApp(new Directionality(
    textDirection: TextDirection.ltr,
    child: new BugWidget(frame.image),
  ));
}

Here is the original image (the _base64 string in the above snippet):
grey32x32

Here is the expected output (screenshot from Android emulator):
expected

Here is what I get instead:
screenshot

@jason-simmons
Copy link
Member

This was introduced in flutter/engine@0a7155d

The image renders as expected if the engine passes an SkColorSpace::MakeSRGB() colorspace to SkImage::MakeCrossContextFromEncoded

@brianosman should we be using a different color space configuration?

@brianosman
Copy link

I wouldn't expect any changes to color space handling of grayscale images. There have been changes to externally created grayscale images (that are wrapped in SkImages). I wouldn't expect that to affect this use-case either, although the incorrect image appears to be rendering as transparent, which could suggest a mis-match (of GL_ALPHA vs. GL_R8), which is the kind of thing that was modified. And because cross-context images do involve wrapping GL textures (even though they start out as SkImages), it's possible that's to blame. The sRGB thing probably works around it by forcing us to create the GL texture as RGBA8888 (because we don't have support for single channel sRGB encoded formats).

I'll confer with other Skia folks...

@tvolkert tvolkert added engine flutter/engine repository. See also e: labels. customer critical dependency: skia Skia team may need to help us labels Mar 20, 2018
@tvolkert
Copy link
Contributor

/cc @chinmaygarde

@Hixie
Copy link
Contributor

Hixie commented Mar 20, 2018

@ltc Can you speak to the timeframe on which you care about this? Does using RGB images in the meantime work for you as a workaround? (Trying to determine how to prioritise this.)

@ltc
Copy link
Author

ltc commented Mar 20, 2018

Yes - I'm currently working around this by converting to RGB before they arrive in flutter.

It's not a showstopper at the moment, but the trade-off is these RGB images are being streamed, so it does triple the size. If this can be addressed in the next few months, that would be great. :)

@brianosman
Copy link

I've landed https://skia.googlesource.com/skia/+/052ef695708eddeaa81c3fcf5747824c1f0ad073 in Skia, which should fix this issue. It still needs to be rolled into the Flutter engine repo, but that should happen before too long.

@ltc
Copy link
Author

ltc commented Mar 28, 2018

Great - thanks! :)

@Hixie
Copy link
Contributor

Hixie commented Apr 10, 2018

@ltc Can you check with the master channel (flutter channel master) if this is resolved for you now?

@Hixie Hixie added the waiting for PR to land (fixed) A fix is in flight label Apr 10, 2018
@ltc
Copy link
Author

ltc commented Apr 12, 2018

Checked - looks like it's fixed now. Thanks for fixing this!

@github-actions
Copy link

github-actions bot commented Sep 3, 2021

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dependency: skia Skia team may need to help us engine flutter/engine repository. See also e: labels. waiting for PR to land (fixed) A fix is in flight
Projects
None yet
Development

No branches or pull requests

5 participants