%ffp Category: "easy.Filter" Title: "Edge detection color" Version: "1.0" Filename: "edgedetection2.8bf" Author: "Alois Zingl" Copyright:"© 2008" URL: "http://free.pages.at/easyfilter/gauss.html" Description:"Detection image edges by derivative convolution." // flexible version: works in all 8-bit color modes and considers all color planes seperately SupportedModes: GrayScaleMode, RGBMode ctl(0): "Blur (pixels)", divisor = 2, range = (1,128) ctl(1): CheckBox, "Monochrom" ctl(4): statictext(center), "" ctl(5): statictext(center), "" ctl(6): statictext(center), "" ctl(8): statictext(center), "X:" ctl(9): statictext(center), "Y:" ctl(CTL_PREVIEW): preview (mousemove), Anchor = ANCHOR_LEFT|ANCHOR_RIGHT|ANCHOR_TOP|ANCHOR_BOTTOM OnCtl(n): { if (n == CTL_PREVIEW && e == FME_MOUSEMOVE && getAsyncKeyState(VK_LBUTTON) == 0) { // show color info int x = getPreviewCoordX(), y = getPreviewCoordY(); setCtlTextv(8, "X: %i", x*zoomFactor+filterRectLeft); // view pos setCtlTextv(9, "Y: %i", y*zoomFactor+filterRectTop); if (x < 0 || y < 0 || x >= X || y >= Y) return false; // out of preview for (i = 0; i < planesWithoutAlpha; ++i) // view values setCtlTextv(4+i, "%c: %3i / %3i", 82-14*i+3*i*i, src(x, y, i), pget(x, y, i)); } return false; } OnFilterStart: { int Blur = doingProxy?(ctl(0)+scaleFactor/2)/scaleFactor:ctl(0); // blur radius needPadding = 3*Blur/2+2; bandWidth = 100+4*needPadding; isTileable = !doingProxy; // split large images setPreviewCursor(IDC_CROSS); return false; } ForEveryTile: { int Blur = max(1, (ctl(0)+scaleFactor/2)/scaleFactor); // blur radius int x, y, z, p, Blur2 = (3*Blur+1)/2; double Weight = 1.0/(Blur*Blur*Blur); for (z = 0; z < planesWithoutAlpha; ++z) // for all color planes { for (x = x_start-3*Blur; x= y_start) dif -= 3*get(y+2*Blur);// -3, if (y+Blur >= y_start) dif += 3*get(y+Blur); // +3, if (y >= y_start) // -1} { dif -= get(y); tset(x, y, z, (int)(sum*Weight)); // blur pset(x, y, z, (int)(der*Blur*Weight/2)+128); // derivation } sum += der; der += dif; // accumulate pixel blur } // y } // x //Update progress bar and cancel if ESC key was pressed if (updateProgress((1-doingProxy)*y_start*planesWithoutAlpha+(y_end-y_start)*z, (doingProxy?y_end-y_start:Y)*planesWithoutAlpha)) abort(); for (y = y_start; y < y_end; ++y) // horizontal blur for every column { int dif = 0, der = 0, sum = 0; // blur int dif2 = 0, sum2 = 0, p2; // derivative blur for (x = x_start-3*Blur; x < x_end; ++x) // horizontal blur loop { p2 = tget(x+Blur2, y, z); p = pget(x+Blur2, y, z); // pixel value put(p2+(p<<16), x+3*Blur); // buffer pixel, min buffer size: 3*Blur dif += p; dif2 += p2;// accumulate differences {+1, if (x+2*Blur >= x_start) // -3, { p = get(x+2*Blur); dif -= 3*(p>>16); dif2 -= 3*(p&0xffff); } if (x+Blur >= x_start) // +3, { p = get(x+Blur); dif += 3*(p>>16); dif2 += 3*(p&0xffff); } if (x >= x_start) { p = get(x); dif -= p>>16; dif2 -= p&0xffff; // -1} p = 2*sum*Weight-256; // horizontal edges p2 = sum2*Blur*Weight; // vertical edges p = min(255, sqr((p*p+p2*p2)*16/9)); // sum up edges if (ctl(1)) psetp(x, y, (p+z*pget(x, y, 0))/(z+1)*0x10101); // monochrom else pset(x, y, z, p); // set pixel color } sum += der; der += dif; sum2 += dif2; // accumulate pixel blur } // x } // y } // z return true; //Done! } OnFilterEnd: { updateProgress(0, 1); return false; }