【问题标题】:Flutter get pixel color from image in varFlutter从var中的图像获取像素颜色
【发布时间】:2020-05-14 09:19:46
【问题描述】:

假设我们有几个背景图片:

我们如何使用函数选择图像的左上角、右上角、左下角、右下角和中心像素颜色并将它们保存在 vars 中?

我没有找到任何好去处..

编辑,这是我目前得到的代码。

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,
                )
              ],
            ),
          )
        ],
      ),
    );
  }}

这就是我打印出来的值$hex

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

我不确定我现在是否已经有了十六进制值。那么如何将它应用到我的容器颜色呢?好像还是少了点什么。。

【问题讨论】:

标签: flutter dart


【解决方案1】:

您好,您尝试过这个功能吗?

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

int getPixel (
int x,
int y
)

从给定的 x, y 坐标获取像素。颜色在 Uint32 中编码为 #AABBGGRR。没有进行范围检查。

工作示例:

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,
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

【讨论】:

  • 我看到了,这很好,我们如何定义屏幕的角落和中心?然后我们可以在上面使用 getPixel 。你知道如何定义它们吗?
  • 你好@MarcelDz 你如何在 Flutter 应用程序中加载图像?此方法需要一个 Image 对象。
  • 有网络图像数据,你能举个例子吗?
  • 我添加了一些代码,我现在刚刚编写并在迄今为止的研究中发现了这些代码。所以我试图获得右上角屏幕的颜色,我的打印给了我一个值,我不确定这是否已经正确。我想将它作为颜色应用于容器,但这不起作用。仍然缺少某些东西...请您检查一下吗?
【解决方案2】:

2020 年 9 月起,如果您需要读取小部件树中图像的图像像素,您可以使用 https://pub.dev/packages/image_pixels 包中的 ImagePixels 小部件:

// 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)}.");
              );
} 

注意:您也可以使用pixelColorAt 从特定位置读取像素颜色,或使用pixelColorAtAlignment 从小数偏移处读取。

另请注意:我已经创建了这个包。

【讨论】:

  • @martijn-pieters 这个答案实际上是针对这个问题量身定制的。问题相似但不完全相同,答案也相似但不完全相同。
猜你喜欢
  • 2013-07-21
  • 2019-07-27
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多