-- MovieScript "Imagelib" --@ Version 1.0.2 --@ Created Tuesday, 16th January 2004, 1:01 am -------------------------------------------------------------------------------------------------------------- --@ DESCRIPTION -- Some movie-script imaging functions -------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------ -- MODIFY IMAGES PASSED BY PARAMETER ------------------------------------------------------------------------------------------------------------------ on PaintImg (targetImg, srcImg, doNotScale) -- Paints and image onto another, centering it on the canvas. -- By default, if the source image is too big to fit on the -- target, then the source image is scaled down. If the -- doNotScale parameter is included, then the image is not -- scaled (and will be cropped if it is too big) srcRect = srcImg.rect destRect = targetImg.rect if (destRect <> srcRect) then if NOT (doNotScale) then sx = srcImg.width - targetImg.width sy = srcImg.height - targetImg.height sm = max(sx,sy) if sm > 0 then -- either width or height is too big if sx > sy then -- use width to determine scale thescale = float(targetImg.width)/srcImg.width else -- use height to determine scale thescale = float(targetImg.height)/srcImg.height end if srcRect = srcRect * thescale tmp = image(srcRect.width, srcRect.height, srcImg.depth) tmp.CopyPixels(srcImg, tmp.rect, srcImg.rect) srcImg = tmp end if end if dx = targetImg.rect.width/2 - srcRect.width/2 dy = targetImg.rect.height/2 - srcRect.height/2 destRect = srcImg.rect.offset(dx,dy) end if CopyPixels32(targetImg, srcImg, destRect, srcRect) end on CopyPixels32 (targetImg, srcImg, destRect, srcRect) -- Copy the source image on to the target image, creating a -- composite alpha (if the target image is 32bit). if targetImg.depth = 32 then -- get the original alpha channel existingAlpha = targetImg.extractAlpha() targetImg.useAlpha = 0 -- get the alpha of the image to paint if srcImg.depth = 32 then addAlpha = srcImg.extractAlpha() srcImg.useAlpha = 0 else addAlpha = image(srcImg.width, srcImg.height, 8, #grayscale) addAlpha.fill(addAlpha.rect, rgb(0,0,0)) end if tmpMask = srcImg.extractalpha().createMask() targetImg.copyPixels(srcImg, destRect, srcRect, [#maskimage : tmpMask, #dither : 1969]) -- create a new composite alpha addAlphaRev = image(srcImg.width, srcImg.height, 8, #grayscale) addAlphaRev.fill(addAlphaRev.rect, rgb(0,0,0)) addAlphaRev.copyPixels(addAlpha, addAlpha.rect, addAlpha.rect, [#ink: 2, #dither: 1215]) -- reverse existingAlpha.copyPixels(addAlphaRev, destRect, srcRect, [#ink: 35]) -- subtractpin targetImg.setAlpha(existingAlpha) targetImg.useAlpha = 1 else if srcImg.depth = 32 then tmpMask = srcImg.extractalpha().createMask() srcImg.useAlpha = 0 targetImg.copyPixels(srcImg, destRect, srcRect, [#maskimage : tmpMask, #ink: 36, #dither: 1969]) else targetImg.copyPixels(srcImg, destRect, srcRect) end if end if end ------------------------------------------------------------------------------------------------------------------ -- GET NEW IMAGES ------------------------------------------------------------------------------------------------------------------ on GetRotated (anImage, anAngle) if anImage.depth = 32 then tAlpha = anImage.extractAlpha() anImage.useAlpha = FALSE tImage = GetRotatedImg(anImage, anAngle) -- See below tAlpha = GetRotatedImg(tAlpha, anAngle) tImage.setAlpha(tAlpha) tImage.useAlpha = TRUE else tImage = GetRotatedImg(anImage, anAngle) end if return tImage end on GetBlurred (anImage, blurRate) if blurRate.ilk <> #integer then blurRate = 5 myOffsets = [[-blurRate,-blurRate], [blurRate,-blurRate], [blurRate,blurRate], [-blurRate,blurRate]] if anImage.depth = 32 then tAlpha = anImage.extractAlpha() anImage.useAlpha = FALSE buffer = anImage.duplicate() buffer.useAlpha = FALSE myBufferRect = buffer.rect tAlpha2 = tAlpha.duplicate() buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[1][1], myOffsets[1][2]), myBufferRect, [#blend : 50]) buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[2][1], myOffsets[2][2]), myBufferRect, [#blend : 33]) buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[3][1], myOffsets[3][2]), myBufferRect, [#blend : 25]) buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[4][1], myOffsets[4][2]), myBufferRect, [#blend : 20]) tAlpha2.copyPixels(tAlpha, myBufferRect.offset(myOffsets[1][1], myOffsets[1][2]), myBufferRect, [#blend : 50]) tAlpha2.copyPixels(tAlpha, myBufferRect.offset(myOffsets[2][1], myOffsets[2][2]), myBufferRect, [#blend : 33]) tAlpha2.copyPixels(tAlpha, myBufferRect.offset(myOffsets[3][1], myOffsets[3][2]), myBufferRect, [#blend : 25]) tAlpha2.copyPixels(tAlpha, myBufferRect.offset(myOffsets[4][1], myOffsets[4][2]), myBufferRect, [#blend : 20]) buffer.setAlpha(tAlpha2) buffer.useAlpha = TRUE else buffer = anImage.duplicate() myBufferRect = buffer.rect buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[1][1], myOffsets[1][2]), myBufferRect, [#blend : 50]) buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[2][1], myOffsets[2][2]), myBufferRect, [#blend : 33]) buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[3][1], myOffsets[3][2]), myBufferRect, [#blend : 25]) buffer.copyPixels(anImage, myBufferRect.offset(myOffsets[4][1], myOffsets[4][2]), myBufferRect, [#blend : 20]) end if return buffer end on GetRotatedImg (anImage, ang) -- srcQuad = [] -- create a quad centred around the image centre -- srcQuad[1] = point(-anImage.width/2, -anImage.height/2) -- srcQuad[2] = srcQuad[1] + point(anImage.width, 0) -- srcQuad[3] = srcQuad[1] + point(anImage.width, anImage.height) -- srcQuad[4] = srcQuad[1] + point(0, anImage.height) -- -- srcOffset = point(anImage.width/2, anImage.height/2) -- -- newQuad = [] -- sinA = sin(ang) -- cosA = cos(ang) -- repeat with j = 1 to 4 -- thisPoint = srcQuad[j] -- x = thisPoint[1] -- y = thisPoint[2] -- thisPoint[1] = x * cosA - y * sinA -- thisPoint[2] = x * sinA + y * cosA -- newQuad[j] = thisPoint + srcOffset -- end repeat -- put newQuad -- enclosingrect = rect(min(newQuad), max(newQuad)) -- s = integer(Max(enclosingrect.width, enclosingrect.height))-- + 0.5) -- newImage = image(s,s, 32) -- newImage.fill(newImage.rect, rgb(255,0,0)) -- destOffset = point(newImage.width/2, newImage.height/2) -- repeat with j = 1 to 4 -- newQuad[j]= newQuad[j] + destOffset -- end repeat -- newImage.copyPixels(anImage, newQuad, anImage.rect) -- return newImage -- James Newton's way is much better: -- Convert anAngle to radians anAngle = ang * pi / 180 tWidth = anImage.width tHeight = anImage.height -- Determine polar coordinates of bottom right corner tAngle = atan(tHeight, tWidth) tHeight = float(tHeight) / 2 tWidth = float(tWidth) / 2 tRadius = sqrt(tHeight * tHeight + tWidth * tWidth) -- Rotate top and bottom right-hand corners and convert to Cartesian tTemp = anAngle - tAngle tH2 = tRadius * cos(tTemp) tV2 = tRadius * sin(tTemp) tTemp = anAngle + tAngle tH3 = tRadius * cos(tTemp) tV3 = tRadius * sin(tTemp) -- Determine the dimensions of a quarter of the new image tHMax = max(abs(tH2), abs(tH3)) tVMax = max(abs(tV2), abs(tV3)) -- Map the rotated positions of the left-hand corners, and translate -- all corners to positive h and v coordinates tH4 = tHMax - tH2 tH1 = tHMax - tH3 tH2 = tHMax + tH2 tH3 = tHMax + tH3 tV4 = tVMax - tV2 tV1 = tVMax - tV3 tV2 = tVMax + tV2 tV3 = tVMax + tV3 -- Determine the dimensions of the whole image tHMax = tHMax * 2 tVMax = tVMax * 2 -- Create an image of the appropriate size and copy the original -- image using a quad for the rotation tImage = image(tHMax, tVMax, anImage.depth, anImage.paletteRef) tImage.fill( tImage.rect, rgb(255,0,0)) tQuad=[point(tH1,tV1),point(tH2,tV2),point(tH3,tV3),point(tH4,tV4)] tImage.copyPixels(anImage, tQuad, anImage.rect) return tImage end on GetScaledImg (anImage, aScale, cropTofit) -- return a new image that is a scaled version of the supplied image. -- aScale can either be a list [HorizontalScale, VerticalScale] or a number -- (used for both HorizontalScale and VerticalScale). -- If cropTofit is true, the returned image will be cropped to fit the source if aScale.ilk = #float or aScale.ilk = #Integer then aScale = [aScale, aScale] else if not listP(aScale) then return #parameter_Error newImage = image(anImage.width*aScale[1], anImage.height*aScale[2], 32) newImage.copyPixels(anImage, newImage.rect, anImage.Rect) if cropTofit then if (aScale[1] <= 1 AND aScale[2] <= 1) then -- no need to crop return newImage else -- crop croppedImage = image(anImage.width, anImage.height, 32) xOff = (newImage.width-anImage.width)/2 yOff = (newImage.height-anImage.height)/2 copyRect = anImage.rect + rect(xOff, yOff, xOff, yOff) destRect = croppedImage.rect CopyPixels32(croppedImage, newImage, destRect, copyRect) return croppedImage end if else return newImage end if end