For those who looking for Contrast and Invert Color HSBCI, I added and reorder the filter based on BananaNeil's answer:
class ColorFilterGenerator {
static List<double> hueAdjustMatrix({required double value}) {
value = value * pi;
if (value == 0)
return [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
];
double cosVal = cos(value);
double sinVal = sin(value);
double lumR = 0.213;
double lumG = 0.715;
double lumB = 0.072;
return List<double>.from(<double>[
(lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)), (lumG + (cosVal * (-lumG))) + (sinVal * (-lumG)), (lumB + (cosVal * (-lumB))) + (sinVal * (1 - lumB)), 0, 0, (lumR + (cosVal * (-lumR))) + (sinVal * 0.143), (lumG + (cosVal * (1 - lumG))) + (sinVal * 0.14), (lumB + (cosVal * (-lumB))) + (sinVal * (-0.283)), 0, 0, (lumR + (cosVal * (-lumR))) + (sinVal * (-(1 - lumR))), (lumG + (cosVal * (-lumG))) + (sinVal * lumG), (lumB + (cosVal * (1 - lumB))) + (sinVal * lumB), 0, 0, 0, 0, 0, 1, 0,
]).map((i) => i.toDouble()).toList();
}
static List<double> brightnessAdjustMatrix({required double value}) {
if (value <= 0) value = value * 255;
else value = value * 100;
if (value == 0)
return [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
];
return List<double>.from(<double>[
1, 0, 0, 0, value, 0, 1, 0, 0, value, 0, 0, 1, 0, value, 0, 0, 0, 1, 0
]).map((i) => i.toDouble()).toList();
}
static List<double> saturationAdjustMatrix({required double value}) {
value = value * 100;
if (value == 0)
return [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
];
double x = ((1 + ((value > 0) ? ((3 * value) / 100) : (value / 100)))).toDouble();
double lumR = 0.3086;
double lumG = 0.6094;
double lumB = 0.082;
return List<double>.from(<double>[
(lumR * (1 - x)) + x, lumG * (1 - x), lumB * (1 - x),
0, 0,
lumR * (1 - x),
(lumG * (1 - x)) + x,
lumB * (1 - x),
0, 0,
lumR * (1 - x),
lumG * (1 - x),
(lumB * (1 - x)) + x,
0, 0, 0, 0, 0, 1, 0,
]).map((i) => i.toDouble()).toList();
}
static List<double> invertAdjustMatrix({required double value}) {
if (value == 0)
return [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
];
return List<double>.from(<double>[
-value, 0, 0, value, 0,
0, -value, 0, value, 0,
0, 0, -value, value, 0,
0, 0, 0, 1, 0
]).map((i) => i.toDouble()).toList();
}
static List<double> contrastAdjustMatrix({required double value}) {
if (value == 0)
return [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
];
return List<double>.from(<double>[
Pow(2,value), 0, 0, 0.5-value/2, 0,
0, Pow(2,value), 0, 0.5-value/2, 0,
0, 0, Pow(2,value), 0.5-value/2, 0,
0, 0, 0, 1, 0
]).map((i) => i.toDouble()).toList();
}
}
And the Widget ImageFilter:
Widget ImageFilter({saturation, hue, contrast, brightness, invert, child}) {
return
ColorFiltered(colorFilter: ColorFilter.matrix(ColorFilterGenerator.saturationAdjustMatrix(value: saturation,)),
child: ColorFiltered(colorFilter: ColorFilter.matrix(ColorFilterGenerator.hueAdjustMatrix(value: hue,)),
child: ColorFiltered(colorFilter: ColorFilter.matrix(ColorFilterGenerator.contrastAdjustMatrix(value: contrast,)),
child: ColorFiltered(colorFilter: ColorFilter.matrix(ColorFilterGenerator.brightnessAdjustMatrix(value: brightness,)),
child: ColorFiltered(colorFilter: ColorFilter.matrix(ColorFilterGenerator.invertAdjustMatrix(value: invert,)),
child: child,
)
)
)
)
);
}
The priority execute is following: Invert > Brightness > Contrast > Hue > Saturation
This order help easy predict result and protect color signal.
Using:
ImageFilter(
hue: 0.5,
saturation: -0.5,
brightness: 0.2,
contrast: 0.5,
invert: 1.0,
child: yourWidget,
);
Invert
- Value from 0 to 1, between 0 and 1 will have affect on contrast too.
Contrast