Bilinear Resampling and 21 Other Filters
From Directorforum Collaboration Wiki
Revision as of 21:06, 27 May 2009 by Martin Schaefer (Talk | contribs)
-- Bilinear Image Resampling and many other filters -- by Josh Chunick -- inspired by VB code written by Tanner Helland who, -- in turn, was inspired by code on vbAccelerator.com -- other code -- bilinear-quality code worth considering -- by fazstp DOUG Post: http://director-online.com/forums/read.php?2,30701 on ScaleIncremental var_image, var_scale final_width = integer( var_image.width * var_scale ) final_height = integer( var_image.height * var_scale ) final_image = image( final_width, final_height, 32 ) temp_image = var_image.duplicate() repeat while ( temp_image.width < final_image.width ) temp_image = ScaleImage( temp_image, 2 ) end repeat final_image.copyPixels( temp_image, final_image.rect, temp_image.rect ) return final_image end ScaleIncremental on ScaleImage var_image, var_scale final_width = integer( var_image.width * var_scale ) final_height = integer( var_image.height * var_scale ) final_image = image( final_width, final_height, 32 ) final_image.copyPixels( var_image, final_image.rect, var_image.rect ) final_image.copyPixels( var_image, final_image.rect + [1, 0, 1, 0], var_image.rect, [#blendLevel: 55] ) final_image.copyPixels( var_image, final_image.rect + [-1, 0, -1, 0], var_image.rect, [#blendLevel: 55] ) final_image.copyPixels( var_image, final_image.rect + [0, 1, 0, 1], var_image.rect, [#blendLevel: 55] ) final_image.copyPixels( var_image, final_image.rect + [0, -1, 0, -1], var_image.rect, [#blendLevel: 55] ) final_image.copyPixels( var_image, final_image.rect + [1, 1, 1, 1], var_image.rect, [#blendLevel: 22] ) final_image.copyPixels( var_image, final_image.rect + [-1, 1, -1, 1], var_image.rect, [#blendLevel: 22] ) final_image.copyPixels( var_image, final_image.rect + [1, -1, 1, -1], var_image.rect, [#blendLevel: 22] ) final_image.copyPixels( var_image, final_image.rect + [-1, -1, -1, -1], var_image.rect, [#blendLevel: 22] ) return final_image end ScaleImage on InvertImage (theImage) theImage = theImage.duplicate() newImage = image(theImage.width, theImage.height, theImage.depth) newImage.floodfill(point(0,0), color(0,0,0)) theRect = theImage.rect newImage.useAlpha = theImage.useAlpha newImage.copyPixels(theImage, theRect, theRect, [#ink: 2, #maskImage: theImage.extractAlpha()]) return newImage end on Noise (theImage, colorize, theBlend, theInk) theWidth = theImage.width - 1 theHeight = theImage.height - 1 anImage = theImage.duplicate() if colorize then newImage = image(anImage.width, anImage.height, 8) else newImage = image(anImage.width, anImage.height, 8, #grayscale) end if repeat with y1 = 0 to theHeight repeat with x1 = 0 to theWidth rnd = random(255) newImage.setPixel(point(x1,y1), color(rnd)) end repeat end repeat anImage.copyPixels(newImage, anImage.rect, anImage.rect, [#ink: theInk, #blendLevel: theBlend]) return anImage end on diffuseImage (theImage, amount) theWidth = theImage.width - 1 theHeight = theImage.height - 1 newImage = theImage.duplicate() -- the look-up table for the original image (done for speed purposes) listX = [] listY = [] repeat with x = 0 to theWidth repeat with y = 0 to theHeight listY.add(theImage.getPixel(x,y)) end repeat listX.add(listY) listY = [] end repeat -- draw each pixel in the new image repeat with y1 = 0 to theHeight repeat with x1 = 0 to theWidth rndX = random(amount) - 2 rndY = random(amount) - 2 xMod = max(min(theWidth, x1 + rndX), 1) yMod = max(min(theHeight, y1 + rndY), 1) theColour = listX[xMod][yMod] R = theColour.red G = theColour.green B = theColour.blue newImage.setPixel(point(x1,y1), color(R, G, B)) end repeat end repeat return newImage end on embossImage (theImage, offsetX, offsetY) offsetX = integer(offsetX) offsetY = integer(offsetY) theWidth = theImage.width - 1 theHeight = theImage.height - 1 newImage = theImage.duplicate() -- the look-up table for the original image (done for speed purposes) listX = [] listY = [] repeat with x = 0 to theWidth repeat with y = 0 to theHeight listY.add(theImage.getPixel(x,y)) end repeat listX.add(listY) listY = [] end repeat -- draw each pixel in the new image repeat with y1 = 0 to theHeight yMod = max(min(theHeight, y1), 1) yMod1 = max(min(theHeight, y1 + offsetY), 1) repeat with x1 = 0 to theWidth xMod = max(min(theWidth, x1), 1) xMod1 = max(min(theWidth, x1 + offsetX), 1) theColour1 = listX[xMod][yMod] theColour2 = listX[xMod1][yMod1] R = abs(theColour1.red - theColour2.red + 128) G = abs(theColour1.green - theColour2.green + 128) B = abs(theColour1.blue - theColour2.blue + 128) newImage.setPixel(point(x1,y1), color(R, G, B)) end repeat end repeat return newImage end on blurImage2 (theImage) theWidth = theImage.width - 1 theHeight = theImage.height - 1 newImage = theImage.duplicate() -- the look-up table for the original image (done for speed purposes) listX = [] listY = [] repeat with x = 0 to theWidth repeat with y = 0 to theHeight listY.add(theImage.getPixel(x,y)) end repeat listX.add(listY) listY = [] end repeat repeat with y1 = 0 to theHeight yMod = max(min(theHeight, y1), 1) yMod1 = max(min(theHeight, y1 - 1), 1) yMod2 = max(min(theHeight, y1 + 1), 1) repeat with x1 = 0 to theWidth -- get the 9 pixels around the interpolated one xMod = max(min(theWidth, x1), 1) xMod1 = max(min(theWidth, x1 - 1), 1) xMod2 = max(min(theWidth, x1 + 1), 1) theColour1 = listX[xMod1][yMod1] theColour2 = listX[xMod1][yMod] theColour3 = listX[xMod][yMod1] theColour4 = listX[xMod2][yMod1] theColour5 = listX[xMod1][yMod2] theColour6 = listX[xMod][yMod] theColour7 = listX[xMod2][yMod] theColour8 = listX[xMod][yMod2] theColour9 = listX[xMod2][yMod2] R = (theColour1.red + theColour2.red + theColour3.red + theColour4.red + theColour5.red + theColour6.red + theColour7.red + theColour8.red + theColour9.red) / 9 G = (theColour1.green + theColour2.green + theColour3.green + theColour4.green + theColour5.green + theColour6.green + theColour7.green + theColour8.green + theColour9.green) / 9 B = (theColour1.blue + theColour2.blue + theColour3.blue + theColour4.blue + theColour5.blue + theColour6.blue + theColour7.blue + theColour8.blue + theColour9.blue) / 9 --Set this pixel into the new image newImage.setPixel(point(x1,y1), color(R, G, B)) end repeat end repeat return newImage end on horizontalBlur (theImage) -- ******************************************************************** -- This is a crappy algorithm -- change it with one based off of a convolution matrix and copyPixels -- ******************************************************************** theWidth = theImage.width - 1 theHeight = theImage.height - 1 newImage = theImage.duplicate() -- the look-up table for the original image (done for speed purposes) listX = [] listY = [] repeat with x = 0 to theWidth repeat with y = 0 to theHeight listY.add(theImage.getPixel(x,y)) end repeat listX.add(listY) listY = [] end repeat repeat with y1 = 0 to theHeight yMod = max(min(theHeight, y1 + 1), 1) -- yMod1 = max(min(theHeight, y1 - 1), 1) --yMod2 = max(min(theHeight, y1 + 1), 1) repeat with x1 = 0 to theWidth -- get the 9 pixels around the interpolated one xMod1 = max(min(theWidth, x1 - 4), 1) xMod2 = max(min(theWidth, x1 - 3), 1) xMod3 = max(min(theWidth, x1 - 2), 1) xMod4 = max(min(theWidth, x1), 1) xMod5 = max(min(theWidth, x1 + 1), 1) xMod6 = max(min(theWidth, x1 + 1), 1) xMod7 = max(min(theWidth, x1 + 2), 1) xMod8 = max(min(theWidth, x1 + 3), 1) xMod9 = max(min(theWidth, x1 + 4), 1) clr1 = listX[xMod1][yMod] clr2 = listX[xMod2][yMod] clr3 = listX[xMod3][yMod] clr4 = listX[xMod4][yMod] clr5 = listX[xMod5][yMod] clr6 = listX[xMod6][yMod] clr7 = listX[xMod7][yMod] clr8 = listX[xMod8][yMod] clr9 = listX[xMod9][yMod] R = (clr1.red + 2 * (clr2.red) + 3 * (clr3.red) + 4 * (clr4.red) + 5 * (clr5.red) + 4 * (clr6.red) + 3 * (clr7.red) + 2 * (clr8.red) + clr9.red) / 25 G = (clr1.green + 2 * (clr2.green) + 3 * (clr3.green) + 4 * (clr4.green) + 5 * (clr5.green) + 4 * (clr6.green) + 3 * (clr7.green) + 2 * (clr8.green) + clr9.green) / 25 B = (clr1.blue + 2 * (clr2.blue) + 3 * (clr3.blue) + 4 * (clr4.blue) + 5 * (clr5.blue) + 4 * (clr6.blue) + 3 * (clr7.blue) + 2 * (clr8.blue) + clr9.blue) / 25 --Set this pixel into the new image newImage.setPixel(point(x1,y1), color(R, G, B)) end repeat end repeat return newImage end on sharpenImage (theImage, theAmount) theWidth = theImage.width - 1 theHeight = theImage.height - 1 newImage = theImage.duplicate() -- the look-up table for the original image (done for speed purposes) listX = [] listY = [] repeat with x = 0 to theWidth repeat with y = 0 to theHeight listY.add(theImage.getPixel(x,y)) end repeat listX.add(listY) listY = [] end repeat -- draw each pixel in the new image repeat with y1 = 2 to theHeight repeat with x1 = 2 to theWidth -- get the 2 pixels we need for sharpening theColour1 = listX[x1][y1] theColour2 = listX[x1 - 1][y1 - 1] newColour = theColour1 + theAmount * (theColour1 - theColour2) -- if y1 = 2 and x1 = 2 then put newColour --Set this pixel into the new image newImage.setPixel(point(x1 - 1,y1 - 1), newColour) end repeat end repeat return newImage end -- Bilinear Image Resampling Code -- ©2005 by Josh Chunick (josh@chunick.com) -- code optimizations by Thomas Mavrofides -- This code is free to use in commercial applications -- or however you want.If you use this code you -- must keep the comments, including this message, -- intact. Feel free to add any changes or make improvements. -- -- inspired by VB code from vbAccelerator.com on bilinearResample2 (theImage, newWidth, newHeight, sharpen, amount) --theImage = anImage.duplicate() newImage = image(newWidth, newHeight, 32) oldWidth = theImage.width - 1 oldHeight = theImage.height - 1 -- return the original image if the scale factor is 1 if newImage.rect = theImage.rect then return theImage -- the look-up table for the original image (done for speed purposes) -- this shaves off 600 milliseconds from my 320x240 test image listX = [] listY = [] repeat with x = 0 to oldWidth repeat with y = 0 to oldHeight listY.add(theImage.getPixel(x,y)) end repeat listX.add(listY) listY = [] end repeat -- get the ratio between the old image and the new one xScale = (oldWidth) / float(newWidth) yScale = (oldHeight) / float(newHeight) -- draw each pixel in the new image repeat with y = 1 to newHeight -- generate the y calculation variables dstY = (y - 1) * yScale interplY = bitXor(dstY, 0) calcY = dstY - interplY repeat with x = 1 to newWidth -- generate the x calculation variables dstX = (x - 1) * xScale interplX = bitXor(dstX, 0) calcX = dstX - interplX -- get the 4 pixels around the interpolated one theColour1 = listX[interplX + 1][interplY + 1] theColour2 = listX[interplX + 2][interplY + 1] theColour3 = listX[interplX + 1][interplY + 2] theColour4 = listX[interplX + 2][interplY + 2] -- calculate the new colour newColor1 = theColour1 * (1 - calcY) + theColour3 * calcY newColor2 = theColour2 * (1 - calcY) + theColour4 * calcY newColor= newColor1 * (1 - calcX) + newColor2 * calcX --Set this pixel into the new image newImage.setPixel(point(x - 1,y - 1), newColor) end repeat end repeat if sharpen then if voidP(amount) or amount = 0 then amount = 0.5 newImage = sharpenImage (newImage, amount) end if return newImage end on fastBlur (anImage, hBlur, vBlur) newImage = anImage.duplicate() theWidth = newImage.width - 1 theHeight = newImage.height - 1 -- draw each pixel in the new image repeat with y1 = 0 to theHeight repeat with x1 = 0 to theWidth interplY1 = max(min(y1 - vBlur, y1 - 1), 1) interplX1 = max(min(x1 - hBlur, x1 - 1), 1) interplY2 = min(max(y1 + vBlur, y1 + 1), theHeight) interplX2 = min(max(x1 + hBlur, x1 + 1), theWidth) newImage.copyPixels(anImage, rect(x1,y1,x1 + 1,y1 + 1), rect(interplX1,interplY1,interplX2,interplY2)) end repeat end repeat return newImage end on rescale (membRef, maxW, maxH) wide=membRef.width high=membRef.height k=new(#bitmap) repeat while wide>maxW or high>maxH if wide>maxW then scaler=maxW/float(wide) wide=wide*scaler high=high*scaler nI=image(wide,high,32) nI.copyPixels(membRef,nI.rect,membRef.rect) k.erase() k=new(#bitmap) k.image=nI end if wide=membRef.width high=membRef.height if high>maxH then scaler=maxH/float(high) wide=wide*scaler high=high*scaler nI=image(wide,high,32) nI.copyPixels(membRef,nI.rect,membRef.rect) k.erase() k=new(#bitmap) k.image=nI end if wide=membRef.width high=membRef.height end repeat return k.image k.erase() end on bilinearResample1 (sourceImg, newWidth, newHeight, antiAlias) ---------------------------------------------------------------- -- original code written created by "johnAQ" from the MM forums -- modified by Josh Chunick -- modification includes the addition of a blurring on the image -- to smooth out any jaggies which may appear on diagonal lines -- in the image when scaling by fractional factors. ---------------------------------------------------------------- theStart = the milliseconds oldImgObj = sourceImg.duplicate() sourceDepth = oldImgObj.depth oldWidth = oldImgObj.width oldHeight = oldImgObj.height --first do the scale along the x axis newImgObj1 = image(newWidth, oldHeight, 32) if newWidth <> oldWidth then theWidth = newWidth - 1 theHeight = newHeight - 1 repeat with i = 0 to newWidth ratio = 1.0 * i / (newWidth - 1) * (oldWidth - 1) a = bitOr(ratio, 0) t = ratio - 1 destRect = rect(i, 0, i + 1, oldHeight) sourceRect = rect(a, 0, a + 1, oldHeight) newImgObj1.copyPixels(oldImgObj, destRect, sourceRect) if t > 0 then sourceRect = rect(a + 1, 0, a + 2, oldHeight) newImgObj1.copyPixels(oldImgObj, destRect, sourceRect, [#blendLevel: 255 * t]) end if end repeat else newImgObj1.copyPixels(oldImgObj, oldImgObj.rect, oldImgObj.rect) end if --next do the scale along the y axis newImgObj2 = image(newWidth, newheight, 32) if newHeight <> oldHeight then repeat with i = 0 to newHeight ratio = 1.0 * i / (newHeight - 1) * (oldHeight - 1) a = bitOr(ratio, 0) t = ratio - 1 destRect = rect(0, i, newWidth, i + 1) sourceRect = rect(0, a, newWidth, a + 1) newImgObj2.copyPixels(newImgObj1, destRect, sourceRect) if t > 0 then sourceRect = rect(0, a + 1, newWidth, a + 2) newImgObj2.copyPixels(newImgObj1, destRect, sourceRect, [#blendLevel: 255 * t]) end if end repeat else newImgObj2.copyPixels(newImgObj1, newImgObj1.rect, newImgObj1.rect) end if if antiAlias then theOffset = 3 newImgObj3 = blurImage(newImgObj2, theOffset) newImgObj2.copyPixels(newImgObj3, newImgObj2.rect, newImgObj3.rect + rect(theOffset, theOffset, - theOffset, - theOffset), [#Ink: 39]) end if return newImgObj2 end on nearestNeighbour (sourceImage, newWidth, newHeight, antiAlias) newImage = image(newWidth, newHeight, 32) newImage.copyPixels(sourceImage, newImage.rect, sourceImage.rect) if antiAlias then theOffset = 3 newImage2 = blurImage(newImage, theOffset) newImage.copyPixels(newImage2, newImage.rect, newImage2.rect + rect(theOffset, theOffset, - theOffset, - theOffset), [#Ink: 39]) end if return newImage end on blurImage (anImage, blurLevel) -- blurring the image myImg = anImage.duplicate() imgW = myImg.width imgH = myImg.height buffer1 = myImg.duplicate() -- NW SE NE SW W E N S center offsetL = [[0,0], [2, 2], [0, 2], [2, 0], [0, 1], [2, 1], [1, 0], [1, 2], [1,1]] myBlend = 5*255/offsetL.count --1.8*255/offsetL.count -- 1.8 = luminosity correction, from 1.5 to 5 -- optional : start a loop for multiple pass repeat with i = 1 to blurLevel -- blurring the image buffer2 = image( imgW+2*i, imgH+2*i, 32 ) myRect = rect( 0, 0, buffer1.width, buffer1.height ) repeat with j = 1 to 9 -- = offsetL.count destRect = myRect.offset(offsetL[j][1], offsetL[j][2]) buffer2.copyPixels(buffer1, destRect, myRect, [#blendLevel : myBlend]) end repeat buffer1 = buffer2.duplicate() end repeat -- apply the result return buffer1 end on grayScaleImg (theImage, theMethod, sepia, sepiaColor, sepiaAmount) grayImage = theImage.duplicate() -- Luminance Coefficients -- http://en.wikipedia.org/wiki/Luminance_(video) -- CCIR 601 (most digital standards) Y' = 0.299 R' + 0.587 G' + 0.114 B' -- http://en.wikipedia.org/wiki/Luminance_%28relative%29 -- ITU-R BT.709 (sRGB) Y = 0.2126 R + 0.7152 G + 0.0722 B if grayImage.paletteRef <> #grayscale then Case theMethod of 1: newImage = image(grayImage.width, grayImage.height, 8, #grayscale) newImage.copyPixels(grayImage, grayImage.rect, grayImage.rect, [#dither: 1215]) -- 1969, 1215 grayImage = newImage 2: newImage = image(grayImage.width, grayImage.height, 8, #grayscale) newImage.copyPixels(grayImage, grayImage.rect, grayImage.rect, [#dither: 1969]) grayImage = newImage 3: theWidth = grayImage.width - 1 theHeight = grayImage.height - 1 newImage = image(grayImage.width, grayImage.height, 8, #grayscale) repeat with x = 0 to theWidth repeat with y = 0 to theHeight theColour = grayImage.getPixel(point(x,y)) -- commented out one is not as rich, but brings out more detail, potentially -- grayComp = (0.2980 * theColour.red) + (0.5882 * theColour.green) + (0.1138 * theColour.blue) -- the below uses these fractions: 54/255 R, 182.5/255 G, 18.5/255 B -- correction - using (sRGB) coefficients now. grayComp = (0.2126 * theColour.red) + (0.7152 * theColour.green) + (0.0722 * theColour.blue) newImage.setPixel(point(x,y), color(255 - grayComp)) end repeat end repeat grayImage = newImage 4: theWidth = grayImage.width - 1 theHeight = grayImage.height - 1 newImage = image(grayImage.width, grayImage.height, 8, #grayscale) repeat with x = 0 to theWidth repeat with y = 0 to theHeight theColour = grayImage.getPixel(point(x,y)) -- not as rich, but brings out more detail, potentially -- uses these fractions: 76/255 R, 150/255 G, 29/255 B -- grayComp = (0.1 * theColour.red) + (.8 * theColour.green) + (.1 * theColour.blue) grayComp = (0.2980 * theColour.red) + (0.5882 * theColour.green) + (0.1138 * theColour.blue) newImage.setPixel(point(x,y), color(255 - grayComp)) end repeat end repeat grayImage = newImage end Case end if if the paramCount >= 3 and sepia then sepiaImg = image(grayImage.width, grayImage.height, 32) colour = color(112, 66, 20) if ilk(sepiaColor) = #color then colour = sepiaColor sepiaImg.fill(point(0,0), colour) tmpGrayImg = image(grayImage.width, grayImage.height, 32) tmpGrayImg.copyPixels(grayImage, grayImage.rect, grayImage.rect) grayImage = tmpGrayImg.duplicate() tmpGrayImg.copyPixels(sepiaImg, tmpGrayImg.rect, sepiaImg.rect, [#ink: 33]) blendLvl = 100 if integerP(sepiaAmount) then blendLvl = sepiaAmount grayImage.copyPixels(tmpGrayImg, grayImage.rect, tmpGrayImg.rect, [#ink: 3, #blendLevel: blendLvl]) end if return grayImage end on posterize (imageRef, bitDepth, thePalette, theDither) posterizedImage = image (imageRef.width, imageRef.height, bitDepth, thePalette) posterizedImage.copyPixels (imageRef, imageRef.rect, imageRef.rect, [#dither: theDither]) return posterizedImage end on blackWhite1 (imageRef) b_wImage = image (imageRef.width, imageRef.height, 1) b_wImage.copyPixels (imageRef, imageRef.rect, imageRef.rect) return b_wImage end on blackWhite2 (imageRef, thePalette, theDither) posterizedImage = image (imageRef.width, imageRef.height, 8, thePalette) posterizedImage.copyPixels (imageRef, imageRef.rect, imageRef.rect, [#dither: theDither]) b_wImage = image (imageRef.width, imageRef.height, 1) b_wImage.copyPixels (posterizedImage, imageRef.rect, imageRef.rect) return b_wImage end on flipImage (anImage, aFlip) -------------------------------------------------------------------- -- original code by Luke Wigley www.lingoworkshop.com -- I added the flip parameter. -- aFlip can be these values: #flipV, #flipH, #flipVH -------------------------------------------------------------------- aRect = anImage.rect aQuad = [point(0,0), point(aRect.width,0), point(aRect.width,aRect.height), point(0,aRect.height)] Case aFlip of #flipV: newQuad = [aQuad[4], aQuad[3], aQuad[2], aQuad[1]] #flipH: newQuad = [aQuad[2], aQuad[1], aQuad[4], aQuad[3]] #flipVH: newQuad = [aQuad[3], aQuad[4], aQuad[1], aQuad[2]] end Case newImage = image(anImage.width, anImage.height, anImage.depth) newImage.copyPixels(anImage, newQuad, aRect) return newImage end on rotateImage (anImage, anAngle, anOffSet, aColour, smoothing) -------------------------------------------------------------------- -- rotates the supplied quad. -- Angle is specified in degrees. -- I Added: -- a) anImage parameter -- b) aColour parameter -- c) the smoothing parameter -- the offset parameter is the pivot point of the rotation. -- pass along the member.regPoint for rotation around the center point -- the colour parameter is the background colour of the empty image -- which you get when you rotate an image. -- original code by Luke Wigley www.lingoworkshop.com -------------------------------------------------------------------- aWidth = anImage.width aHeight = anImage.height if smoothing then anImage = bilinearResample2(anImage, aWidth * 2, aHeight * 2, True) anOffSet = anOffSet * 2 end if aRect = anImage.rect aQuad = [point(0,0), point(aRect.width,0), point(aRect.width,aRect.height), point(0,aRect.height)] newQuad = [] anAngle = anAngle * pi/180.0 repeat with j = 1 to 4 thisPoint = aQuad[j] x = thisPoint[1] - anOffSet[1] y = thisPoint[2] - anOffSet[2] thisPoint[1] = x * cos(anAngle) - y * sin(anAngle) thisPoint[2] = x * sin(anAngle) + y * cos(anAngle) newQuad[j] = thisPoint + anOffSet end repeat -- wMax = max(newQuad[1][1], newQuad[2][1], newQuad[3][1], newQuad[4][1]) -- wMin = min(newQuad[1][1], newQuad[2][1], newQuad[3][1], newQuad[4][1]) -- hMax = max(newQuad[1][2], newQuad[2][2], newQuad[3][2], newQuad[4][2]) -- hMin = min(newQuad[1][2], newQuad[2][2], newQuad[3][2], newQuad[4][2]) -- newWidth = bitOr((wMax - wMin),0)+((wMax - wMin)>0) -- newHeight = bitOr((hMax - hMin),0)+((hMax - hMin)>0) -- newRect = rect(0,0,newWidth, newHeight) -- put newRect newImage = image(anImage.width, anImage.height, anImage.depth) newImage.floodFill(point(0,0), aColour) newImage.copyPixels(anImage, newQuad, aRect, [#useFastQuads: 0]) if smoothing then newImage = bilinearResample2 (newImage, aWidth, aHeight) return newImage end -- emulates find edges in paint window: -- findEdges(member(4).image, 2, 1, 1.3) on findEdges (anImage, blurLevel, offsetMultiplier, gamma) myImg = anImage.duplicate() imgW = myImg.width imgH = myImg.height buffer1 = myImg.duplicate() -- NW, SE, NE, SW, W, E, N, S, center -- Sobel filter (kernel) -- offsetL = [[1,-1], [-1, 1], [-1, -1], [1, 1], [2, 0], [-2, 0], [0, -2], [0, 2], [0,0]] -- Prewitt filter (kernel) offsetL = [[1,-1], [-1, 1], [-1, -1], [1, 1], [1, 0], [-1, 0], [0, -1], [0, 1], [0,0]] offsetL = offsetL * offsetMultiplier offsetCount = offsetL.count --myBlend = 1.8*255/offsetCount myBlend = gamma*255/offsetCount -- 1.8 = luminosity correction, from 1.5 to 5 repeat with i = 1 to blurLevel -- blurring the image buffer2 = image( imgW+2*i, imgH+2*i, 32 ) myRect = rect( 0, 0, buffer1.width, buffer1.height ) repeat with j = 1 to offsetCount destRect = myRect.offset(offsetL[j][1], offsetL[j][2]) buffer2.copyPixels(buffer1, destRect, myRect, [#blendLevel : myBlend]) end repeat buffer1 = buffer2.duplicate() end repeat myRect = myImg.rect myImg.copyPixels(buffer1, myRect, myRect, [#ink: 2]) myImg2 = image(imgW, imgH, 1) myImg2.copyPixels(myImg, myRect, myRect) myImg.copyPixels(myImg2, myRect, myRect) return myImg end
