Skip to content

Commit e61ade4

Browse files
authored
feat: improved UI and added filters(atkinson and false floyd Steinberg) (#26)
* improve UI and add filters add Atkinson and False Floyd-Steinberg filters * add Stucki Dither and add helper function for palette * updated filter names
1 parent 571ed9b commit e61ade4

File tree

7 files changed

+318
-62
lines changed

7 files changed

+318
-62
lines changed

lib/util/epd/gdey037z03.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ class Gdey037z03 extends Epd {
2525
get controller => Uc8253() as Driver;
2626

2727
Gdey037z03() {
28-
processingMethods.add(ImageProcessing.rwbTriColorDither);
29-
processingMethods.add(ImageProcessing.colorHalftone);
28+
processingMethods.add(ImageProcessing.bwrFloydSteinbergDither);
29+
processingMethods.add(ImageProcessing.bwrFalseFloydSteinbergDither);
30+
processingMethods.add(ImageProcessing.bwrStuckiDither);
31+
processingMethods.add(ImageProcessing.bwrTriColorAtkinsonDither);
32+
processingMethods.add(ImageProcessing.bwrHalftone);
33+
processingMethods.add(ImageProcessing.bwrThreshold);
3034
}
3135
}

lib/util/epd/gdey037z03bw.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ class Gdey037z03BW extends Epd {
2525
get controller => Uc8253() as Driver;
2626

2727
Gdey037z03BW() {
28-
processingMethods.add(ImageProcessing.binaryDither);
29-
processingMethods.add(ImageProcessing.halftone);
28+
processingMethods.add(ImageProcessing.bwFloydSteinbergDither);
29+
processingMethods.add(ImageProcessing.bwFalseFloydSteinbergDither);
30+
processingMethods.add(ImageProcessing.bwStuckiDither);
31+
processingMethods.add(ImageProcessing.bwAtkinsonDither);
32+
processingMethods.add(ImageProcessing.bwHalftoneDither);
33+
processingMethods.add(ImageProcessing.bwThreshold);
3034
}
3135
}

lib/util/image_processing/image_processing.dart

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,82 @@ import 'extract_quantizer.dart';
55
import 'remap_quantizer.dart';
66

77
class ImageProcessing {
8-
static img.Image binaryDither(img.Image orgImg) {
8+
static img.Image bwFloydSteinbergDither(img.Image orgImg) {
99
var image = img.Image.from(orgImg);
1010
return img.ditherImage(image, quantizer: img.BinaryQuantizer());
1111
}
1212

13-
static img.Image halftone(img.Image orgImg) {
13+
static img.Image bwFalseFloydSteinbergDither(img.Image orgImg) {
14+
var image = img.Image.from(orgImg);
15+
return img.ditherImage(image,
16+
quantizer: img.BinaryQuantizer(),
17+
kernel: img.DitherKernel.falseFloydSteinberg);
18+
}
19+
20+
static img.Image bwStuckiDither(img.Image orgImg) {
21+
var image = img.Image.from(orgImg);
22+
return img.ditherImage(image,
23+
quantizer: img.BinaryQuantizer(), kernel: img.DitherKernel.stucki);
24+
}
25+
26+
static img.Image bwAtkinsonDither(img.Image orgImg) {
27+
var image = img.Image.from(orgImg);
28+
return img.ditherImage(image,
29+
quantizer: img.BinaryQuantizer(), kernel: img.DitherKernel.atkinson);
30+
}
31+
32+
static img.Image bwThreshold(img.Image orgImg) {
33+
var image = img.Image.from(orgImg);
34+
return img.ditherImage(image,
35+
quantizer: img.BinaryQuantizer(), kernel: img.DitherKernel.none);
36+
}
37+
38+
static img.Image bwHalftoneDither(img.Image orgImg) {
1439
final image = img.Image.from(orgImg);
1540
img.grayscale(image);
16-
img.colorHalftone(image);
41+
img.colorHalftone(image, size: 3);
1742
return img.ditherImage(image, quantizer: img.BinaryQuantizer());
1843
}
1944

20-
static img.Image colorHalftone(img.Image orgImg) {
45+
static img.Image bwrHalftone(img.Image orgImg) {
2146
var image = img.Image.from(orgImg);
2247

23-
// Tri-color palette
24-
final palette = img.PaletteUint8(3, 3);
25-
palette.setRgb(0, 255, 0, 0); // red
26-
palette.setRgb(1, 0, 0, 0); // black
27-
palette.setRgb(2, 255, 255, 255); // white
48+
img.colorHalftone(image, size: 3);
49+
return img.ditherImage(image,
50+
quantizer: RemapQuantizer(palette: _createTriColorPalette()),
51+
kernel: img.DitherKernel.floydSteinberg);
52+
}
53+
54+
static img.Image bwrFloydSteinbergDither(img.Image orgImg) {
55+
var image = img.Image.from(orgImg);
2856

29-
img.colorHalftone(image);
3057
return img.ditherImage(image,
31-
quantizer: RemapQuantizer(palette: palette),
58+
quantizer: RemapQuantizer(palette: _createTriColorPalette()),
3259
kernel: img.DitherKernel.floydSteinberg);
3360
}
3461

35-
static img.Image rwbTriColorDither(img.Image orgImg) {
62+
static img.Image bwrFalseFloydSteinbergDither(img.Image orgImg) {
3663
var image = img.Image.from(orgImg);
3764

38-
// Tri-color palette
39-
final palette = img.PaletteUint8(3, 3);
40-
palette.setRgb(0, 255, 0, 0); // red
41-
palette.setRgb(1, 0, 0, 0); // black
42-
palette.setRgb(2, 255, 255, 255); // white
65+
return img.ditherImage(image,
66+
quantizer: RemapQuantizer(palette: _createTriColorPalette()),
67+
kernel: img.DitherKernel.falseFloydSteinberg);
68+
}
69+
70+
static img.Image bwrStuckiDither(img.Image orgImg) {
71+
var image = img.Image.from(orgImg);
4372

4473
return img.ditherImage(image,
45-
quantizer: RemapQuantizer(palette: palette),
46-
kernel: img.DitherKernel.floydSteinberg);
74+
quantizer: RemapQuantizer(palette: _createTriColorPalette()),
75+
kernel: img.DitherKernel.stucki);
76+
}
77+
78+
static img.Image bwrTriColorAtkinsonDither(img.Image orgImg) {
79+
var image = img.Image.from(orgImg);
80+
81+
return img.ditherImage(image,
82+
quantizer: RemapQuantizer(palette: _createTriColorPalette()),
83+
kernel: img.DitherKernel.atkinson);
4784
}
4885

4986
static img.Image extract(Color toBeExtract, img.Image orgImg) {
@@ -54,17 +91,19 @@ class ImageProcessing {
5491
kernel: img.DitherKernel.none);
5592
}
5693

57-
static img.Image experiment(img.Image orgImg) {
94+
static img.Image bwrThreshold(img.Image orgImg) {
5895
var image = img.Image.from(orgImg);
5996

60-
// Tri-color palette
61-
final palette = img.PaletteUint8(3, 3);
62-
palette.setRgb(0, 255, 0, 0); // red
63-
palette.setRgb(1, 0, 0, 0); // black
64-
palette.setRgb(2, 255, 255, 255); // white
65-
6697
return img.ditherImage(image,
67-
quantizer: RemapQuantizer(palette: palette),
98+
quantizer: RemapQuantizer(palette: _createTriColorPalette()),
6899
kernel: img.DitherKernel.none);
69100
}
70101
}
102+
103+
img.PaletteUint8 _createTriColorPalette() {
104+
final palette = img.PaletteUint8(3, 3);
105+
palette.setRgb(0, 255, 0, 0); // red
106+
palette.setRgb(1, 0, 0, 0); // black
107+
palette.setRgb(2, 255, 255, 255); // white
108+
return palette;
109+
}

lib/view/image_editor.dart

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:image/image.dart' as img;
88

99
import 'package:magic_epaper_app/provider/image_loader.dart';
1010
import 'package:magic_epaper_app/util/epd/epd.dart';
11+
import 'package:magic_epaper_app/constants.dart';
1112

1213
class ImageEditor extends StatelessWidget {
1314
final Epd epd;
@@ -31,15 +32,50 @@ class ImageEditor extends StatelessWidget {
3132
imgList: processedImgs,
3233
epd: epd,
3334
);
35+
3436
return Scaffold(
37+
backgroundColor: Colors.white,
3538
appBar: AppBar(
36-
title: const Text('Edit Image'),
39+
iconTheme: const IconThemeData(
40+
color: Colors.white,
41+
),
42+
backgroundColor: colorAccent,
43+
elevation: 0,
44+
title: const Center(
45+
child: Padding(
46+
padding: EdgeInsets.symmetric(vertical: 16.0),
47+
child: Text(
48+
'Select Your Filter',
49+
textAlign: TextAlign.center,
50+
style: TextStyle(
51+
fontSize: 16,
52+
fontWeight: FontWeight.bold,
53+
color: Colors.white,
54+
),
55+
),
56+
),
57+
),
58+
toolbarHeight: 85,
3759
actions: <Widget>[
38-
TextButton(
39-
onPressed: () {
40-
imgLoader.pickImage(width: epd.width, height: epd.height);
41-
},
42-
child: const Text("Import Image"),
60+
Padding(
61+
padding:
62+
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
63+
child: TextButton(
64+
style: TextButton.styleFrom(
65+
backgroundColor: Colors.white.withValues(alpha: 0.2),
66+
foregroundColor: Colors.white,
67+
shape: RoundedRectangleBorder(
68+
borderRadius: BorderRadius.circular(8),
69+
),
70+
),
71+
onPressed: () {
72+
imgLoader.pickImage(width: epd.width, height: epd.height);
73+
},
74+
child: const Text(
75+
"Import Image",
76+
style: TextStyle(fontWeight: FontWeight.bold),
77+
),
78+
),
4379
),
4480
TextButton(
4581
onPressed: () async {
@@ -58,7 +94,12 @@ class ImageEditor extends StatelessWidget {
5894
),
5995
],
6096
),
61-
body: Center(child: imgList),
97+
body: SafeArea(
98+
child: Padding(
99+
padding: const EdgeInsets.symmetric(horizontal: 8.0),
100+
child: imgList,
101+
),
102+
),
62103
);
63104
}
64105
}

0 commit comments

Comments
 (0)