为了解决这个问题,我建立了一个
ImageFilter
小部件,可以像这样使用:
ImageFilter(
hue: 0.1,
brightness: -0.6,
saturation: 0.8,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(imageUrl),
),
)
)
)
输入必须为介于-1和1之间的十进制小数形式的百分比。
使用3个ColorFiltered小部件层:
Widget ImageFilter({brightness, saturation, hue, child}) {
return ColorFiltered(
colorFilter: ColorFilter.matrix(
ColorFilterGenerator.brightnessAdjustMatrix(
value: brightness,
)
),
child: ColorFiltered(
colorFilter: ColorFilter.matrix(
ColorFilterGenerator.saturationAdjustMatrix(
value: saturation,
)
),
child: ColorFiltered(
colorFilter: ColorFilter.matrix(
ColorFilterGenerator.hueAdjustMatrix(
value: hue,
)
),
child: child,
)
)
);
}
为了生成滤镜矩阵,我参考了类似于安卓的这个问题的答案:https://dev59.com/PW855IYBdhLWcg3wbjnO#7917978,并创建了在Flutter中可用的ColorFilterGenerator
:
import 'dart:math';
class ColorFilterGenerator {
static List<double> hueAdjustMatrix({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({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({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();
}
}
我敢打赌,有一种方法可以连接色调/饱和度/亮度矩阵(就像我上面提到的 Android 问题中所做的那样),并且只使用1个颜色过滤矩阵(这可能更有效),但这对我的情况起作用。