sclass Gazelle22_GradientImage { // input BWImage posterized; // output BWImage out; // internal PosterizeBWImage op; BWImage unposterized; int w, h, brightnessLevels, singleStep; *(BWImage *posterized) {} bool init() { op = (PosterizeBWImage) getMetaSrc(posterized); if (op == null) false; unposterized = op.img; brightnessLevels = op.brightnessLevels; assertSameSize(unposterized, posterized); w = posterized.getWidth(); h = posterized.getHeight(); singleStep = iceil(doubleRatio(255, brightnessLevels-1)); true; } BWImage get() { init(); out = new BWImage(w*2+1, h*2+1); for y to h: for x to w: { if (x < w-1) checkPair(x, y, x+1, y); if (y < h-1) checkPair(x, y, x, y+1); } ret out; } bool isGradientPoint(int x, int y) { if (op == null) false; new IntMinMax posterizedMinMax; new IntMinMax unposterizedMinMax; // grab point itself posterizedMinMax.add(posterized.getInt(x, y)); unposterizedMinMax.add(unposterized.getInt(x, y)); // grab left neighbor if (x > 0) { posterizedMinMax.add(posterized.getInt(x-1, y)); unposterizedMinMax.add(unposterized.getInt(x-1, y)); } // grab right neighbor if (x < w-1) { posterizedMinMax.add(posterized.getInt(x+1, y)); unposterizedMinMax.add(unposterized.getInt(x+1, y)); } // grab top neighbor if (y > 0) { posterizedMinMax.add(posterized.getInt(x, y-1)); unposterizedMinMax.add(unposterized.getInt(x, y-1)); } // grab bottom neighbor if (y < h-1) { posterizedMinMax.add(posterized.getInt(x, y+1)); unposterizedMinMax.add(unposterized.getInt(x, y+1)); } int posterizedContrast = posterizedMinMax.rangeLength(); if (posterizedContrast == 0 || posterizedContrast > singleStep) false; int unposterizedContrast = unposterizedMinMax.rangeLength(); ret unposterizedContrast <= posterizedContrast/2; } void checkPair(int x, int y, int x2, int y2) { int posterizedContrast = absDiff(posterized.getInt(x, y), posterized.getInt(x2, y2)); if (posterizedContrast == 0) ret; if (posterizedContrast > singleStep) ret; int realContrast = absDiff(unposterized.getInt(x, y), unposterized.getInt(x2, y2)); double ratio = doubleRatio(realContrast, singleStep); float result = cast (.5-ratio)*2; /*if (ratio < .5)*/ { out.setPixel(x*2+1-(y2-y), y*2+1, result); out.setPixel(x*2+1, y*2+1-(x2-x), result); } } }