From 6b7ab14eeea06996afabe423e0d45f81f7cf0302 Mon Sep 17 00:00:00 2001 From: Sharafudheen KK Date: Sun, 2 Aug 2020 19:17:27 +0530 Subject: [PATCH 1/3] typo fixes --- .../{Gaussian 5x5.jpg => Guassian 5x5.jpg} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename exampleimages/convolution/{Gaussian 5x5.jpg => Guassian 5x5.jpg} (100%) diff --git a/exampleimages/convolution/Gaussian 5x5.jpg b/exampleimages/convolution/Guassian 5x5.jpg similarity index 100% rename from exampleimages/convolution/Gaussian 5x5.jpg rename to exampleimages/convolution/Guassian 5x5.jpg From ed2a774c0cc8d8c09fcb8886b3e3d19fa4afb23f Mon Sep 17 00:00:00 2001 From: Sharafudheen KK Date: Sun, 2 Aug 2020 20:17:07 +0530 Subject: [PATCH 2/3] README updated --- README.md | 89 +++++++++++++++++++++++++--- lib/filters/color_filters.dart | 10 +++- lib/filters/convolution_filters.dart | 26 ++++---- lib/filters/image_filters.dart | 8 +++ test/custom_convolution_test.dart | 29 --------- test/custom_filters_test.dart | 40 +++++++++++++ 6 files changed, 150 insertions(+), 52 deletions(-) delete mode 100644 test/custom_convolution_test.dart create mode 100644 test/custom_filters_test.dart diff --git a/README.md b/README.md index f254460..f8e0afe 100644 --- a/README.md +++ b/README.md @@ -120,30 +120,101 @@ class _MyAppState extends State { | Low Pass Low Pass | High Pass High Pass | Mean Mean | | -### Custom filters +## Filters -You can create your own custom filters too +There are two types of filters. `ImageFilter` and `ColorFilter`. + +### Image Filter + +Image filter applies its subfilters directly to the whole image one by one. It is computationally expensive since the complexity & time increases as the number of subfilters increases. + +You can create your own custom image filter as like this: ```dart - var customFilter = new ImageFilter(name: "Custom Filter"); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( + import 'package:photofilters/filters/image_filters.dart'; + + var customImageFilter = new ImageFilter(name: "Custom Image Filter"); + customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel( coloredEdgeDetectionKernel, )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( + customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel( gaussian7x7Kernel, )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( + customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel( sharpenKernel, )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( + customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel( highPass3x3Kernel, )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( + customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel( lowPass3x3Kernel, )); - customFilter.subFilters.add(SaturationSubFilter(0.5)); + customImageFilter.subFilters.add(SaturationSubFilter(0.5)); +``` + +You can also inherit the ImageFilter class to create another image filter. + +```dart + +class MyImageFilter extends ImageFilter { + MyImageFilter(): super(name: "My Custom Image Filter") { + this.addSubFilter(ConvolutionSubFilter.fromKernel(sharpenKernel)); + } +} +``` + +### Color Filter + +Color filter applies its subfilters to each pixel one by one. It is computationally less expensive than the ImageFilter. It will loop through the image pixels only once irrespective of the number of subfilters. + + +You can create your own custom color filter as like this: + +```dart + import 'package:photofilters/filters/color_filters.dart'; + + var customColorFilter = new ColorFilter(name: "Custom Color Filter"); + customColorFilter.addSubFilter(SaturationSubFilter(0.5)); + customColorFilter + .addSubFilters([BrightnessSubFilter(0.5), HueRotationSubFilter(30)]); + ``` +You can inherit the ColorFilter class too + +```dart + +class MyColorFilter extends ColorFilter { + MyColorFilter() : super(name: "My Custom Color Filter") { + this.addSubFilter(BrightnessSubFilter(0.8)); + this.addSubFilter(HueRotationSubFilter(30)); + } +} + +``` + +## Sub filters + +There are two types of subfilters. One can be added to the `ColorFilter` and the other can be added to the `ImageFilter`. You can inherit `ColorSubFilter` class to implement the former and you can use the `ImageSubFilter` mixin to implement the latter. You can create a same subfilter that can be used for both Image and Color Filters. The `BrightnessSubFilter` is an example of this. + +```dart +class BrightnessSubFilter extends ColorSubFilter with ImageSubFilter { + final num brightness; + BrightnessSubFilter(this.brightness); + + ///Apply the [BrightnessSubFilter] to an Image. + @override + void apply(Uint8List pixels, int width, int height) => + image_filter_utils.brightness(pixels, brightness); + + ///Apply the [BrightnessSubFilter] to a color. + @override + RGBA applyFilter(RGBA color) => + color_filter_utils.brightness(color, brightness); +} +``` + + ## Getting Started For help getting started with Flutter, view our online [documentation](https://flutter.io/). diff --git a/lib/filters/color_filters.dart b/lib/filters/color_filters.dart index 14a92a5..d6eff45 100644 --- a/lib/filters/color_filters.dart +++ b/lib/filters/color_filters.dart @@ -10,7 +10,7 @@ abstract class ColorSubFilter extends SubFilter { } ///The [ColorFilter] class to define a Filter which will applied to each color, consists of multiple [SubFilter]s -abstract class ColorFilter extends Filter { +class ColorFilter extends Filter { List subFilters; ColorFilter({String name}) : subFilters = [], @@ -33,4 +33,12 @@ abstract class ColorFilter extends Filter { bytes[i + 3] = color.alpha; } } + + void addSubFilter(ColorSubFilter subFilter) { + this.subFilters.add(subFilter); + } + + void addSubFilters(List subFilters) { + this.subFilters.addAll(subFilters); + } } diff --git a/lib/filters/convolution_filters.dart b/lib/filters/convolution_filters.dart index f5def48..0b918ca 100644 --- a/lib/filters/convolution_filters.dart +++ b/lib/filters/convolution_filters.dart @@ -4,11 +4,11 @@ import 'package:photofilters/utils/convolution_kernels.dart'; var presetConvolutionFiltersList = [ new ImageFilter(name: "Identity") - ..subFilters.add(ConvolutionSubFilter.fromKernel(identityKernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(identityKernel)), new ImageFilter(name: "Sharpen") - ..subFilters.add(new ConvolutionSubFilter.fromKernel(sharpenKernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(sharpenKernel)), new ImageFilter(name: "Emboss") - ..subFilters.add(ConvolutionSubFilter.fromKernel(embossKernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(embossKernel)), new ImageFilter(name: "Colored Edge Detection") ..subFilters .add(ConvolutionSubFilter.fromKernel(coloredEdgeDetectionKernel)), @@ -16,23 +16,23 @@ var presetConvolutionFiltersList = [ ..subFilters .add(ConvolutionSubFilter.fromKernel(edgeDetectionMediumKernel)), new ImageFilter(name: "Edge Detection Hard") - ..subFilters.add(ConvolutionSubFilter.fromKernel(edgeDetectionHardKernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(edgeDetectionHardKernel)), new ImageFilter(name: "Blur") - ..subFilters.add(ConvolutionSubFilter.fromKernel(blurKernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(blurKernel)), new ImageFilter(name: "Guassian 3x3") - ..subFilters.add(ConvolutionSubFilter.fromKernel(Guassian3x3Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(Guassian3x3Kernel)), new ImageFilter(name: "Guassian 5x5") - ..subFilters.add(ConvolutionSubFilter.fromKernel(Guassian5x5Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(Guassian5x5Kernel)), new ImageFilter(name: "Guassian 7x7") - ..subFilters.add(ConvolutionSubFilter.fromKernel(Guassian7x7Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(Guassian7x7Kernel)), new ImageFilter(name: "Mean 3x3") - ..subFilters.add(ConvolutionSubFilter.fromKernel(mean3x3Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(mean3x3Kernel)), new ImageFilter(name: "Mean 5x5") - ..subFilters.add(ConvolutionSubFilter.fromKernel(mean5x5Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(mean5x5Kernel)), new ImageFilter(name: "Low Pass 3x3") - ..subFilters.add(ConvolutionSubFilter.fromKernel(lowPass3x3Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(lowPass3x3Kernel)), new ImageFilter(name: "Low Pass 5x5") - ..subFilters.add(ConvolutionSubFilter.fromKernel(lowPass5x5Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(lowPass5x5Kernel)), new ImageFilter(name: "High Pass 3x3") - ..subFilters.add(ConvolutionSubFilter.fromKernel(highPass3x3Kernel)), + ..addSubFilter(ConvolutionSubFilter.fromKernel(highPass3x3Kernel)), ]; diff --git a/lib/filters/image_filters.dart b/lib/filters/image_filters.dart index c823576..405a1ba 100644 --- a/lib/filters/image_filters.dart +++ b/lib/filters/image_filters.dart @@ -22,4 +22,12 @@ class ImageFilter extends Filter { subFilter.apply(pixels, width, height); } } + + void addSubFilter(ImageSubFilter subFilter) { + this.subFilters.add(subFilter); + } + + void addSubFilters(List subFilters) { + this.subFilters.addAll(subFilters); + } } diff --git a/test/custom_convolution_test.dart b/test/custom_convolution_test.dart deleted file mode 100644 index 5673eee..0000000 --- a/test/custom_convolution_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:photofilters/filters/image_filters.dart'; -import 'package:photofilters/filters/subfilters.dart'; -import 'package:photofilters/utils/convolution_kernels.dart'; - -import 'test_utils.dart'; - -void main() { - test("Custom filter", () { - var customFilter = new ImageFilter(name: "Custom"); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( - coloredEdgeDetectionKernel, - )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( - Guassian7x7Kernel, - )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( - sharpenKernel, - )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( - highPass3x3Kernel, - )); - customFilter.subFilters.add(ConvolutionSubFilter.fromKernel( - lowPass3x3Kernel, - )); - customFilter.subFilters.add(SaturationSubFilter(0.5)); - applyFilterOnFile(customFilter, "res/bird.jpg", "out/custom.jpg"); - }); -} diff --git a/test/custom_filters_test.dart b/test/custom_filters_test.dart new file mode 100644 index 0000000..4974923 --- /dev/null +++ b/test/custom_filters_test.dart @@ -0,0 +1,40 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:photofilters/filters/color_filters.dart'; +import 'package:photofilters/filters/image_filters.dart'; +import 'package:photofilters/filters/subfilters.dart'; +import 'package:photofilters/utils/convolution_kernels.dart'; + +import 'test_utils.dart'; + +void main() { + test("Custom Image filter", () { + var customFilter = new ImageFilter(name: "Custom Image Filter"); + customFilter.addSubFilter(ConvolutionSubFilter.fromKernel( + coloredEdgeDetectionKernel, + )); + customFilter.addSubFilters([ + ConvolutionSubFilter.fromKernel( + Guassian7x7Kernel, + ), + ConvolutionSubFilter.fromKernel( + sharpenKernel, + ), + ConvolutionSubFilter.fromKernel( + highPass3x3Kernel, + ) + ]); + customFilter.addSubFilter(ConvolutionSubFilter.fromKernel( + lowPass3x3Kernel, + )); + customFilter.addSubFilter(SaturationSubFilter(0.5)); + applyFilterOnFile(customFilter, "res/bird.jpg", "out/custom_image.jpg"); + }); + + test("Custom Color filter", () { + var customFilter = new ColorFilter(name: "Custom Color Filter"); + customFilter.addSubFilter(SaturationSubFilter(0.5)); + customFilter + .addSubFilters([BrightnessSubFilter(0.5), HueRotationSubFilter(30)]); + applyFilterOnFile(customFilter, "res/bird.jpg", "out/custom_color.jpg"); + }); +} From a684f1795acb60be702be10f4558c3ce284ffbd7 Mon Sep 17 00:00:00 2001 From: Sharafudheen KK Date: Sun, 2 Aug 2020 20:20:19 +0530 Subject: [PATCH 3/3] v2.0.0 --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 506e30c..7b4a7b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,3 +28,8 @@ ## [1.0.6] - 25 July 2020 * Image Selector Widget Fixes + +## [2.0.0] - 02 Aug 2020 + +* Convolution Filters Functionality Added +* More information about creating subfilters and filters in README diff --git a/pubspec.yaml b/pubspec.yaml index db1007a..2cf6dbb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: photofilters description: A flutter package for applying various types of filters to an image. You can create your own filters and subfilters too. -version: 1.0.6 +version: 2.0.0 homepage: https://github.com/skkallayath/photofilters environment: