image_pixels_plus 1.0.0 copy "image_pixels_plus: ^1.0.0" to clipboard
image_pixels_plus: ^1.0.0 copied to clipboard

Read the width/height and the color of any pixel of an image — raster or SVG. A modern, Flutter-web-compatible fork of image_pixels.

image_pixels_plus #

Build widgets that depend on the width, height, or color of any pixel of an image — raster images and SVGs alike, on all Flutter platforms, including web.

ImagePixelsPlus(
    imageProvider: imageProvider,
    builder: (context, img) => Text("Img size is: ${img.width} × ${img.height}"),
);

Why this fork exists #

image_pixels_plus is a fork of image_pixels by Marcelo Glasberg. The original is a great idea that had fallen out of maintenance: it crashed on Flutter web, used deprecated framework internals, and shipped without tests. This fork keeps the original API you know, fixes what was broken, and extends it where the ecosystem needed it:

image_pixels image_pixels_plus
Flutter web ❌ throws Failed to encode the image into bytes ✅ works
SVG support ImagePixelsPlusSvg + rasterizeSvg()
Load errors silently swallowed ✅ optional errorBuilder
Pre-decoded images ImagePixelsPlus.uiImage()
Deprecated APIs (loadImage()) used ✅ removed
Tests none ✅ full widget + unit suite

The web fix, in one paragraph #

On several Flutter web renderer configurations, ui.Image.toByteData() cannot read back the pixels of a decoded image and throws Failed to encode the image into bytes. This package first tries the direct readback and, if it fails, re-rasterizes the image into a fresh engine-owned offscreen surface whose pixels are always readable. If even that fails (e.g., cross-origin images without CORS headers), pixel reads degrade gracefully to the defaultColor instead of crashing your app.


Extend the background-color of an image #

ImagePixelsPlus.container() paints a background with the color of the pixel at the colorAlignment position — perfect for making an image blend into its surroundings:

ImagePixelsPlus.container(
    imageProvider: myImageProvider,
    colorAlignment: Alignment.topLeft,
    child:
        Container(
            width: 250,
            height: 100,
            alignment: Alignment.center,
            child:
                Container(
                    width: 40.0,
                    height: 60.0,
                    child: Image(image: myImageProvider),
                ),
        ),
);

Using a builder #

The default constructor gives you full control through an ImgDetails object:

  • img.hasImage is true once the image is available, along with img.width and img.height.
  • img.pixelColorAt(x, y) reads any pixel — (0,0) is top-left, (width-1, height-1) is bottom-right. Coordinates outside the image return the defaultColor.
  • img.pixelColorAtAlignment(alignment) does the same with -1..1 alignment coordinates, e.g., Alignment.center.
  • img.uiImage exposes the raw ui.Image, img.byteData the raw RGBA bytes.
ImagePixelsPlus(
    imageProvider: imageProvider,
    defaultColor: Colors.grey,
    builder: (context, img) => Text("Img size is: ${img.width} × ${img.height}"),
);

If loading fails, an optional errorBuilder is called; otherwise the widget degrades gracefully to empty details.

Already have a decoded image? #

Skip the provider entirely:

final ui.Image image = await decodeSomehow();

ImagePixelsPlus.uiImage(
    image: image,
    builder: (context, img) => ...,
);

Note: ImagePixelsPlus never disposes images you pass in — you own them.

Performance: lazy pixel extraction #

By default, the raw RGBA bytes of the whole image are extracted as soon as the image arrives (width × height × 4 bytes + a GPU→CPU readback). If you only need the image dimensions, or read pixels rarely, opt out with lazyBytes — extraction then happens on demand at the first pixel read:

ImagePixelsPlus(
    imageProvider: provider,
    lazyBytes: true, // Extract pixels only when actually read.
    builder: (context, img) => ...,
);

While the bytes have not been extracted yet, hasPixelData is false and pixel reads return the defaultColor; when extraction completes the widget rebuilds.

SVG support #

SVGs aren't decodable by Flutter's codecs, so this package rasterizes them (via flutter_svg) into real pixels you can read — on all platforms including web:

1) The turnkey widget:

ImagePixelsPlusSvg.asset(
    assetName: 'assets/my_image.svg',
    width: 300, // Raster width in pixels; height follows the aspect ratio.
    builder: (context, img) => Container(
        color: img.pixelColorAtAlignment(Alignment.topLeft),
        child: Text("SVG size is: ${img.width} × ${img.height}"),
    ),
);

Also available: ImagePixelsPlusSvg.string(), ImagePixelsPlusSvg() (any vector graphics BytesLoader), plus optional placeholder, errorBuilder, width/height and clipViewbox.

The built-in flutter_svg loaders compare by value, so creating them inline is fine. If you use a custom BytesLoader that doesn't implement ==, pass a constant cacheKey so the SVG isn't re-rasterized on every rebuild.

2) Do it yourself:

final ui.Image image = await rasterizeSvg(assetName: 'assets/my_image.svg', width: 300);

// Then use it directly:
ImagePixelsPlus.uiImage(image: image, builder: (context, img) => ...);

Declare your .svg files as assets in pubspec.yaml:

flutter:
  assets:
    - assets/

Picking the tapped pixel color #

Wrap the image in a Listener/GestureDetector, convert the local position to pixel coordinates, and read the color — works for raster images and SVGs. The example app implements exactly this, including a live alignment picker for the container demo. Run it with:

cd example
flutter run -d chrome   # or any device

Migrating from image_pixels? #

Change the import and you're done — the core API is source-compatible:

- import 'package:image_pixels/image_pixels.dart';
+ import 'package:image_pixels_plus/image_pixels_plus.dart';

Credits #

Built on top of image_pixels by Marcelo Glasberg. Thank you for the original idea and API design.

3
likes
160
points
66
downloads
screenshot

Documentation

API reference

Publisher

verified publisheresentis.dev

Weekly Downloads

Read the width/height and the color of any pixel of an image — raster or SVG. A modern, Flutter-web-compatible fork of image_pixels.

Repository (GitHub)
View/report issues

Topics

#image #image-processing #image-pixels #image-colors #widget

License

MIT (license)

Dependencies

flutter, flutter_svg

More

Packages that depend on image_pixels_plus