从图片中选择主要颜色 [英] Pick main color from picture

查看:137
本文介绍了从图片中选择主要颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Dart / Flutter框架的新手,我还在探索它们的可能性。

I'm new to Dart/Flutter framework and I'm still exploring their possibilities.

我知道在Android中可以拍照并提取主要内容以编程方式从中获取颜色值。 ( Android示例

I know in Android it's possible to take a picture and extract the main color value from it programmatically. (Android example)

我想知道,在纯Dart中如何实现?我希望它与iOS和Android操作系统兼容。

I wonder, how would this be achieved in pure Dart? I would like it to be compatible with both iOS and Android operating system.

推荐答案

我可能认为您已解决问题,但将来搜索此问题后,建议您由Flutter团队检查 Pallete Generator
我将尝试给出代码的工作方式的简单说明,但有关详细示例,请转到插件的 GitHub存储库

I probably think you got a fix but for future searches to this question, I suggest you check Pallete Generator by the flutter team. I will try and give a simple explanation of how the code works but for a detailed example head over to the plugin's GitHub repo.

以下示例将拍摄一张图片,然后选择

The example below is going to take an image then select the dominant colors from it and then display the colors

首先,我们添加所需的进口

First, we add the required imports

import 'package:palette_generator/palette_generator.dart';

之后,让我们创建主应用程序类。

After that let's create the main application class.

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ...
      home: const HomePage(
        title: 'Colors from image',
        image: AssetImage('assets/images/artwork_default.png',),
        imageSize: Size(256.0, 170.0),
      ...

      ),
    );
  }
}

在上面的图像字段中,将您要放置的图像要提取主要颜色,我使用了此处所示的图像。

In the image field above, place the image that you want to extract the dominant colors from, i used the image shown here.

接下来,我们创建HomePage类

Next, we create the HomePage class

@immutable
class HomePage extends StatefulWidget {
  /// Creates the home page.
  const HomePage({
    Key key,
    this.title,
    this.image,
    this.imageSize,
  }) : super(key: key);

  final String title; //App title
  final ImageProvider image; //Image provider to load the colors from
  final Size imageSize; //Image dimensions

  @override
  _HomePageState createState() {
    return _HomePageState();
  }
}

也创建_HomePageState

Lets create the _HomePageState too

class _HomePageState extends State<HomePage> {
  Rect region;
  PaletteGenerator paletteGenerator;

  final GlobalKey imageKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    region = Offset.zero & widget.imageSize;
    _updatePaletteGenerator(region);
  }

  Future<void> _updatePaletteGenerator(Rect newRegion) async {
    paletteGenerator = await PaletteGenerator.fromImageProvider(
      widget.image,
      size: widget.imageSize,
      region: newRegion,
      maximumColorCount: 20,
    );
    setState(() {});
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: _kBackgroundColor,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          new AspectRatio(
            aspectRatio: 15 / 15,
            child: Image(
              key: imageKey,
              image: widget.image,
            ),
          ),
          Expanded(child: Swatches(generator: paletteGenerator)),
        ],
      ),
    );
  }
}

上面的代码仅列出了图像和色板这是下面定义的类。在initState中,我们首先选择一个要从中得出颜色的区域,在本例中为整个图像。

The code above just lays out the image and the Swatches which is a class defined below. In initState, we first select a region which the colors will be derived from which in our case is the whole image.

之后,我们创建一个Swatches类,该类将接收PalleteGenerator并为其绘制色板。

After that we create a class Swatches which receives a PalleteGenerator and draws the swatches for it.

class Swatches extends StatelessWidget {

  const Swatches({Key key, this.generator}) : super(key: key);

  // The PaletteGenerator that contains all of the swatches that we're going
  // to display.
  final PaletteGenerator generator;

  @override
  Widget build(BuildContext context) {
    final List<Widget> swatches = <Widget>[];
    //The generator field can be null, if so, we return an empty container
    if (generator == null || generator.colors.isEmpty) {
      return Container();
    }
    //Loop through the colors in the PaletteGenerator and add them to the list of swatches above
    for (Color color in generator.colors) {
      swatches.add(PaletteSwatch(color: color));
    }
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        //All the colors,
        Wrap(
          children: swatches,
        ),
        //The colors with ranking
        Container(height: 30.0),
        PaletteSwatch(label: 'Dominant', color: generator.dominantColor?.color),
        PaletteSwatch(
            label: 'Light Vibrant', color: generator.lightVibrantColor?.color),
        PaletteSwatch(label: 'Vibrant', color: generator.vibrantColor?.color),
        PaletteSwatch(
            label: 'Dark Vibrant', color: generator.darkVibrantColor?.color),
        PaletteSwatch(
            label: 'Light Muted', color: generator.lightMutedColor?.color),
        PaletteSwatch(label: 'Muted', color: generator.mutedColor?.color),
        PaletteSwatch(
            label: 'Dark Muted', color: generator.darkMutedColor?.color),
      ],
    );
  }
}

之后,我们创建一个PaletteSwatch类。调色板色板只是带有可选标签的颜色正方形

After that lets create a PaletteSwatch class. A palette swatch is just a square of color with an optional label

@immutable
class PaletteSwatch extends StatelessWidget {
  // Creates a PaletteSwatch.
  //
  // If the [color] argument is omitted, then the swatch will show a
  // placeholder instead, to indicate that there is no color.
  const PaletteSwatch({
    Key key,
    this.color,
    this.label,
  }) : super(key: key);

  // The color of the swatch. May be null.
  final Color color;

  // The optional label to display next to the swatch.
  final String label;

  @override
  Widget build(BuildContext context) {
    // Compute the "distance" of the color swatch and the background color
    // so that we can put a border around those color swatches that are too
    // close to the background's saturation and lightness. We ignore hue for
    // the comparison.
    final HSLColor hslColor = HSLColor.fromColor(color ?? Colors.transparent);
    final HSLColor backgroundAsHsl = HSLColor.fromColor(_kBackgroundColor);
    final double colorDistance = math.sqrt(
        math.pow(hslColor.saturation - backgroundAsHsl.saturation, 2.0) +
            math.pow(hslColor.lightness - backgroundAsHsl.lightness, 2.0));

    Widget swatch = Padding(
      padding: const EdgeInsets.all(2.0),
      child: color == null
          ? const Placeholder(
              fallbackWidth: 34.0,
              fallbackHeight: 20.0,
              color: Color(0xff404040),
              strokeWidth: 2.0,
            )
          : Container(
              decoration: BoxDecoration(
                  color: color,
                  border: Border.all(
                    width: 1.0,
                    color: _kPlaceholderColor,
                    style: colorDistance < 0.2
                        ? BorderStyle.solid
                        : BorderStyle.none,
                  )),
              width: 34.0,
              height: 20.0,
            ),
    );

    if (label != null) {
      swatch = ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 130.0, minWidth: 130.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            swatch,
            Container(width: 5.0),
            Text(label),
          ],
        ),
      );
    }
    return swatch;
  }
}

希望这会有所帮助,谢谢。

Hope this helps, thank you.

这篇关于从图片中选择主要颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆