blob: c694f822c41f213b9d0beefcbef3c01c5f4fb4e2 [file] [log] [blame]
import 'dart:math';
import '../image.dart';
import '../internal/clamp.dart';
import 'grayscale.dart';
/// Apply Sobel edge detection filtering to the [src] Image.
Image sobel(Image src, {num amount = 1.0}) {
num invAmount = 1.0 - amount;
Image orig = grayscale(new Image.from(src));
final List<int> origRGBA = orig.getBytes();
int rowSize = src.width * 4;
List<int> rgba = src.getBytes();
final rgbaLen = rgba.length;
for (int y = 0, pi = 0; y < src.height; ++y) {
for (int x = 0; x < src.width; ++x, pi += 4) {
int bl = pi + rowSize - 4;
int b = pi + rowSize;
int br = pi + rowSize + 4;
int l = pi - 4;
int r = pi + 4;
int tl = pi - rowSize - 4;
int t = pi - rowSize;
int tr = pi - rowSize + 4;
num tlInt = tl < 0 ? 0.0 : origRGBA[tl] / 255.0;
num tInt = t < 0 ? 0.0 : origRGBA[t] / 255.0;
num trInt = tr < 0 ? 0.0 : origRGBA[tr] / 255.0;
num lInt = l < 0 ? 0.0 : origRGBA[l] / 255.0;
num rInt = r < rgbaLen ? origRGBA[r] / 255.0 : 0.0;
num blInt = bl < rgbaLen ? origRGBA[bl] / 255.0 : 0.0;
num bInt = b < rgbaLen ? origRGBA[b] / 255.0 : 0.0;
num brInt = br < rgbaLen ? origRGBA[br] / 255.0 : 0.0;
num h = -tlInt - 2.0 * tInt - trInt + blInt + 2.0 * bInt + brInt;
num v = -blInt - 2.0 * lInt - tlInt + brInt + 2.0 * rInt + trInt;
int mag = clamp255((sqrt(h * h + v * v) * 255.0).toInt());
rgba[pi] = clamp255((mag * amount + rgba[pi] * invAmount).toInt());
rgba[pi + 1] =
clamp255((mag * amount + rgba[pi + 1] * invAmount).toInt());
rgba[pi + 2] =
clamp255((mag * amount + rgba[pi + 2] * invAmount).toInt());
}
}
return src;
}