1

Lets say we have several background images:

enter image description here

How can we pick top left, top right, bottom left, bottom right and center center pixel color of image with a function and save them in vars?

I didn't find anything good to go..

EDIT, this is the code I got so far.

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

import 'package:image/image.dart' as img;
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter/rendering.dart';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:muego_dev2/models/songs.dart';
import 'package:provider/provider.dart';



class ColorDetect extends StatefulWidget {
  //static const routeName = '/';

  @override
  _ColorDetectState createState() => _ColorDetectState();
}

class _ColorDetectState extends State<ColorDetect> {


 @override
  Widget build(BuildContext context) {

final coverData = 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg';
img.Image photo;



void setImageBytes(imageBytes) {

    List<int> values = imageBytes.buffer.asUint8List();
    photo = null;
    photo = img.decodeImage(values);
  }

  // image lib uses uses KML color format, convert #AABBGGRR to regular #AARRGGBB
int abgrToArgb(int argbColor) {
  int r = (argbColor >> 16) & 0xFF;
  int b = argbColor & 0xFF;
  return (argbColor & 0xFF00FF00) | (b << 16) | r;
}


  // FUNCTION

 Future<void> _getColor() async {

Uint8List data = (await NetworkAssetBundle(Uri.parse(coverData))
      .load(coverData)
  )
      .buffer
      .asUint8List();

setImageBytes(data);

//FractionalOffset(1.0, 0.0); //represents the top right of the [Size].
double px = 1.0;
double py = 0.0;

int pixel32 = photo.getPixelSafe(px.toInt(), py.toInt());
int hex = abgrToArgb(pixel32);
print("Value of int: $hex ");

 }



    return Scaffold(
      appBar: AppBar(
      ),
      body: Column(
        children: <Widget>[
          Flexible(
            flex: 2,
            child: Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: NetworkImage(coverData),
                  fit: BoxFit.cover,
                ),
              ),
            ),
          ),
          Flexible(
            flex: 1,
            child: Container(
              color: HOW TO APPLY MY HEX COLOR HERE?????,
            ),
          ),
          Spacer(),
          Padding(
            padding: const EdgeInsets.only(bottom: 8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                MaterialButton(
                  elevation: 5.0,
                  padding: EdgeInsets.all(15.0),
                  color: Colors.grey,
                  child: Text("Get Sizes"),
                  onPressed: null,
                ),
                MaterialButton(
                  elevation: 5.0,
                  color: Colors.grey,
                  padding: EdgeInsets.all(15.0),
                  child: Text("Get Positions"),
                  onPressed: _getColor,
                )
              ],
            ),
          )
        ],
      ),
    );
  }}

And this is what I get printed with value $hex

Restarted application in 1.419ms.
I/flutter ( 2103): Value of int: 4287593304

I'm not sure if I already have the hex value now. So how can I apply it to my Container color? It seems that there is something still missing..

Marcel Dz
  • 2,321
  • 4
  • 14
  • 49
  • have you checked https://stackoverflow.com/questions/56478321/get-the-pixel-on-which-i-clicked/56488053#56488053 – Epsi95 May 14 '20 at 09:35
  • Yes, this is sample is way too complex to implement for me, I just need to get a color of 5 coordinate pixels and save them. – Marcel Dz May 14 '20 at 09:44
  • Is this what you ultimately want to achieve? https://stackoverflow.com/a/71179259/1032613 – WSBT Sep 13 '22 at 16:25

2 Answers2

10

Hello did you try with this function?

https://api.flutter.dev/flutter/image/Image/getPixel.html

int getPixel (
int x,
int y
)

Get the pixel from the given x, y coordinate. Color is encoded in a Uint32 as #AABBGGRR. No range checking is done.

Working example:

import 'dart:typed_data';

import 'package:image/image.dart' as img;
import 'package:flutter/rendering.dart';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
//import 'package:muego_dev2/models/songs.dart';
//import 'package:provider/provider.dart';


main() {
  runApp(MaterialApp(home: ColorDetect()));
}

class ColorDetect extends StatefulWidget {
  //static const routeName = '/';

  @override
  _ColorDetectState createState() => _ColorDetectState();
}

class _ColorDetectState extends State<ColorDetect> {
  final coverData =
      'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg';

  img.Image photo;

  void setImageBytes(imageBytes) {
    print("setImageBytes");
    List<int> values = imageBytes.buffer.asUint8List();
    photo = null;
    photo = img.decodeImage(values);
  }

  // image lib uses uses KML color format, convert #AABBGGRR to regular #AARRGGBB
  int abgrToArgb(int argbColor) {
    print("abgrToArgb");
    int r = (argbColor >> 16) & 0xFF;
    int b = argbColor & 0xFF;
    return (argbColor & 0xFF00FF00) | (b << 16) | r;
  }

  // FUNCTION

  Future<Color> _getColor() async {
    print("_getColor");
    Uint8List data;

    try{
    data =
        (await NetworkAssetBundle(
          Uri.parse(coverData)).load(coverData))
            .buffer
            .asUint8List();
    }
    catch(ex){
      print(ex.toString());
    }

    print("setImageBytes....");
    setImageBytes(data);

//FractionalOffset(1.0, 0.0); //represents the top right of the [Size].
    double px = 1.0;
    double py = 0.0;

    int pixel32 = photo.getPixelSafe(px.toInt(), py.toInt());
    int hex = abgrToArgb(pixel32);
    print("Value of int: $hex ");

    return Color(hex);
  }

  @override
  Widget build(BuildContext context) {
    print("build");

    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: <Widget>[
          Flexible(
            flex: 2,
            child: Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: NetworkImage(coverData),
                  fit: BoxFit.cover,
                ),
              ),
            ),
          ),
          Flexible(
            flex: 1,
            child: 

            FutureBuilder(
              future: _getColor(),
              builder: (_, AsyncSnapshot<Color> data){
                if (data.connectionState==ConnectionState.done){
                  return Container(
              color: data.data,
            );                
            }
            return CircularProgressIndicator();
              }
            ),
          ),
          Spacer(),
          Padding(
            padding: const EdgeInsets.only(bottom: 8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                MaterialButton(
                  elevation: 5.0,
                  padding: EdgeInsets.all(15.0),
                  color: Colors.grey,
                  child: Text("Get Sizes"),
                  onPressed: null,
                ),
                MaterialButton(
                  elevation: 5.0,
                  color: Colors.grey,
                  padding: EdgeInsets.all(15.0),
                  child: Text("Get Positions"),
                  onPressed: _getColor,
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

enter image description here

camillo777
  • 2,177
  • 1
  • 20
  • 20
  • I saw that, this is great, how do we define the corners and the center of the screen? then we could use getPixel on it. Do you have an idea how to define them? – Marcel Dz May 14 '20 at 10:26
  • Hello @MarcelDz how do you load the image in the Flutter app? This method needs an Image object. – camillo777 May 14 '20 at 12:39
  • with network image data, can you give me an example how to do it with that? – Marcel Dz May 14 '20 at 12:48
  • I added some code, which I just coded right now and found on research so far. So I tried to get the color of the top right screen, my print gives me a value, Im not sure if this is already correct. I want to apply it as color to a container, but this doesnt work. Something is still missing... Can you check it please? – Marcel Dz May 14 '20 at 14:25
  • I got `The argument type 'Pixel' can't be assigned to the parameter type 'int'.` – Taufik Nur Rahmanda Aug 19 '23 at 16:37
5

Since September 2020, if you need to read image pixels of an image you have in your widget tree, you can use the ImagePixels widget from the https://pub.dev/packages/image_pixels package:

// Given some position x and y...

@override
Widget build(BuildContext context) {
    return ImagePixels(
              imageProvider: image,
              builder: (context, img) =>
                  Text(
                     "Img size is: ${img.width} × ${img.height}.\n"
                     "Pixel color is: ${img.pixelColorAt(x, y)}.");
              );
} 

Note: You can also use pixelColorAt to read the pixel color from a specific position, or pixelColorAtAlignment to read from a fractional offset.

Also note: I've created this package.

Marcelo Glasberg
  • 29,013
  • 23
  • 109
  • 133
  • @martijn-pieters This answer is actually tailored to the question. The question is similar but it's not identical to others, and the answer is also similar but not identical. – Marcelo Glasberg Sep 15 '20 at 00:01