LoginSignup
4
3

More than 5 years have passed since last update.

RGB補色の計算

Last updated at Posted at 2019-03-02

色彩についてまったく詳しくないけど任意の色の背景に文字を描画する際に読めないと困るので、
補色を計算する処理を書きました

RGBの補色はこう計算するみたいです

補色

カラーの各構成要素を、選択したカラーの最大の RGB 値と最小の RGB 値の合計を元にして、新しい値に変更します。現在のカラーの RGB 値のうち最大と最小の値が合計され、その値から各構成要素の値を引いて、新しい RGB 値が生成されます。

引用元: https://helpx.adobe.com/jp/illustrator/using/adjusting-colors.html#change_a_color_to_its_inverse_or_complement

追記:
Color.fromARGBcolor.blue等があるのに書いてから気づきました
このへんを使うともっと簡単にかけると思います

これをdartで実装

  Color complement(Color baseColor) {
    final int opacity = baseColor.value >> 24 & 0xff;
    final int r = baseColor.value >> 16 & 0xff;
    final int g = baseColor.value >> 8 & 0xff;
    final int b = baseColor.value & 0xff;
    final int sum = [r, g, b].reduce(max) + [r, g, b].reduce(min);
    return Color((opacity << 24) | ((sum - r) << 16) | ((sum - g) << 8) | (sum - b));
  }

flutterで表示を試してみるとこんなかんじ
星が背景の補色
太陽が背景の反対色

import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'dart:math';

void main() => runApp(A());

class A extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(appBar: AppBar(title: const Text('comp-color')), body: Home()),
    );
  }
}

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _State();
  }
}

class _State extends State<Home> {
  Color pickerColor = Color(0xffff0000);
  Color currentColor = Color(0xffff0000);
  Color compColor = Color(0xff00ffff);
  Color invertedColor = Color(0xff00ffff);

  ValueChanged<Color> onColorChanged;

  changeColor(Color color) {
    setState(() {
      pickerColor = color;
      compColor = complement();
      invertedColor = invert();
    });
  }

  Color complement() {
    final int opacity = pickerColor.value >> 24 & 0xff;
    final int r = pickerColor.value >> 16 & 0xff;
    final int g = pickerColor.value >> 8 & 0xff;
    final int b = pickerColor.value & 0xff;
    final int sum = [r, g, b].reduce(max) + [r, g, b].reduce(min);
    return Color((opacity << 24) | ((sum - r) << 16) | ((sum - g) << 8) | (sum - b));
  }

  Color invert() => Color(((pickerColor.value ~/ 0x1000000) << 24) | (0xffffff - (pickerColor.value % 0x1000000)));

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Center(
            child: ColorPicker(
          pickerColor: pickerColor,
          onColorChanged: changeColor,
          enableLabel: false,
          pickerAreaHeightPercent: 0.8,
        )),
        Container(
            margin: const EdgeInsets.all(10),
            padding: const EdgeInsets.all(20),
            color: pickerColor,
            child: Icon(Icons.star, color: compColor, size: 40)),
        Container(
            margin: const EdgeInsets.all(10),
            padding: const EdgeInsets.all(20),
            color: pickerColor,
            child: Icon(Icons.wb_sunny, color: invertedColor, size: 40))
      ],
    );
  }
}


4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3