Reputation: 2714
Lets say we have several background images:
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..
Upvotes: 2
Views: 14466
Reputation: 7207
getPixel
from the image package as of version 4.0 no longer returns an integer, but a Pixel
object, from which you can get the colors. This retrieves the color of a pixel as an integer:
import 'dart:ui' as ui;
...
final pixel = image.getPixel(x, y);
final intColor = ui.Color.fromRGBO(pixel.r.toInt(), pixel.g.toInt(), pixel.b.toInt(), pixel.a.toDouble()).value;
Upvotes: 3
Reputation: 30889
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.
Upvotes: 6
Reputation: 2367
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,
)
],
),
)
],
),
);
}
}
Upvotes: 12