feat: klasor tabanli galeri, brightness efekti (Ctrl+Shift+sag tik), .deb guncellendi

This commit is contained in:
Alhan committed 2026-08-03 08:26:31 +03:00
1 parent 56ab4b5495
commit d4c243b445
9 files changed
+249 -37

No files matched your search

+68 -14
View File
@@ -21,13 +21,15 @@ class _ImageCanvasState extends State<ImageCanvas> {
double _angle = 0;
double _contrast = 1.0;
double _saturation = 1.0;
double _brightness = 0;
// ── Gesture tracking ──
String _interactionMode = 'none'; // 'contrast' | 'rotate' | 'saturation'
String _interactionMode = 'none'; // 'contrast' | 'rotate' | 'saturation' | 'brightness'
Offset _pointerDownPos = Offset.zero;
double _startAngle = 0;
double _startContrast = 1.0;
double _startSaturation = 1.0;
double _startBrightness = 0;
DateTime? _lastRightTapTime;
Offset _lastRightTapPos = Offset.zero;
@@ -139,14 +141,14 @@ class _ImageCanvasState extends State<ImageCanvas> {
void _resetView() {
setState(() {
_tx = 0; _ty = 0; _sc = 1.0; _isFilled = true; _vpSize = Size.zero;
_angle = 0; _contrast = 1.0; _saturation = 1.0;
_angle = 0; _contrast = 1.0; _saturation = 1.0; _brightness = 0;
});
}
void _toggleFillFit() {
setState(() {
_isFilled = !_isFilled; _tx = 0; _ty = 0; _sc = 1.0; _vpSize = Size.zero;
_angle = 0; _contrast = 1.0; _saturation = 1.0;
_angle = 0; _contrast = 1.0; _saturation = 1.0; _brightness = 0;
});
}
@@ -196,6 +198,7 @@ class _ImageCanvasState extends State<ImageCanvas> {
_angle = 0;
_contrast = 1.0;
_saturation = 1.0;
_brightness = 0;
_interactionMode = 'none';
});
_lastRightTapTime = null;
@@ -204,7 +207,10 @@ class _ImageCanvasState extends State<ImageCanvas> {
_lastRightTapTime = now;
_lastRightTapPos = e.localPosition;
if (_ctrlPressed) {
if (_ctrlPressed && _shiftPressed) {
_interactionMode = 'brightness';
_startBrightness = _brightness;
} else if (_ctrlPressed) {
_interactionMode = 'saturation';
_startSaturation = _saturation;
} else if (_shiftPressed) {
@@ -237,6 +243,11 @@ class _ImageCanvasState extends State<ImageCanvas> {
_saturation = (_startSaturation + dy * 0.005).clamp(0.0, 2.0);
});
break;
case 'brightness':
setState(() {
_brightness = (_startBrightness + dy * 0.5).clamp(-100.0, 100.0);
});
break;
}
}
@@ -244,7 +255,7 @@ class _ImageCanvasState extends State<ImageCanvas> {
_interactionMode = 'none';
}
// ── Combined color filter (saturation × contrast) ──
// ── Combined color filter (brightness × saturation × contrast) ──
static const double _rLum = 0.2126;
static const double _gLum = 0.7152;
@@ -253,29 +264,72 @@ class _ImageCanvasState extends State<ImageCanvas> {
ColorFilter? _cachedFilter;
double _cachedSat = -1;
double _cachedCon = -1;
double _cachedBri = double.nan;
List<double> _multiply4x5(List<double> a, List<double> b) {
final result = List<double>.filled(20, 0.0);
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
double sum = 0.0;
for (int k = 0; k < 4; k++) {
sum += a[row * 5 + k] * b[k * 5 + col];
}
result[row * 5 + col] = sum;
}
double offsetSum = a[row * 5 + 4];
for (int k = 0; k < 4; k++) {
offsetSum += a[row * 5 + k] * b[k * 5 + 4];
}
result[row * 5 + 4] = offsetSum;
}
return result;
}
ColorFilter _buildCombinedFilter() {
if (_cachedFilter != null && _cachedSat == _saturation && _cachedCon == _contrast) {
if (_cachedFilter != null &&
_cachedSat == _saturation &&
_cachedCon == _contrast &&
_cachedBri == _brightness) {
return _cachedFilter!;
}
_cachedSat = _saturation;
_cachedCon = _contrast;
_cachedBri = _brightness;
final s = _saturation;
final c = _contrast;
final t = (1.0 - c) / 2.0;
final b = _brightness;
final invS = 1.0 - s;
final sR_R = invS * _rLum + s, sR_G = invS * _gLum, sR_B = invS * _bLum;
final sG_R = invS * _rLum, sG_G = invS * _gLum + s, sG_B = invS * _bLum;
final sB_R = invS * _rLum, sB_G = invS * _gLum, sB_B = invS * _bLum + s;
_cachedFilter = ColorFilter.matrix(<double>[
c * sR_R, c * sR_G, c * sR_B, 0, t,
c * sG_R, c * sG_G, c * sG_B, 0, t,
c * sB_R, c * sB_G, c * sB_B, 0, t,
0, 0, 0, 1, 0,
]);
final saturationMatrix = <double>[
sR_R, sR_G, sR_B, 0, 0,
sG_R, sG_G, sG_B, 0, 0,
sB_R, sB_G, sB_B, 0, 0,
0, 0, 0, 1, 0,
];
final brightnessMatrix = <double>[
1, 0, 0, 0, b,
0, 1, 0, 0, b,
0, 0, 1, 0, b,
0, 0, 0, 1, 0,
];
final offset = 128.0 * (1.0 - c);
final contrastMatrix = <double>[
c, 0, 0, 0, offset,
0, c, 0, 0, offset,
0, 0, c, 0, offset,
0, 0, 0, 1, 0,
];
// M_final = M_contrast * M_brightness * M_saturation
_cachedFilter = ColorFilter.matrix(
_multiply4x5(_multiply4x5(contrastMatrix, brightnessMatrix), saturationMatrix));
return _cachedFilter!;
}
@@ -302,7 +356,7 @@ class _ImageCanvasState extends State<ImageCanvas> {
Widget imageContent = Builder(
builder: (context) {
final hasFilter = _saturation != 1.0 || _contrast != 1.0;
final hasFilter = _saturation != 1.0 || _contrast != 1.0 || _brightness != 0.0;
final image = _isFilled
? SizedBox.expand(child: _buildImage())
: Center(child: _buildImage());