diff --git a/orx-image-fit/README.md b/orx-image-fit/README.md new file mode 100644 index 00000000..0587f658 --- /dev/null +++ b/orx-image-fit/README.md @@ -0,0 +1,20 @@ +# orx-image-fit + +Fits images in frames with two options, contain and cover. Similar to CSS object-fit (https://www.w3schools.com/css/css3_object-fit.asp) + +## usage + +`imageFit(img: ColorBuffer, x: Double, y: Double, w: Double, h: Double, fitMethod, horizontalPosition:Double, verticalPosition:Double)` + + +fitMethod + - `contain` + - `cover` + +horizontal values + - left ... right + - `-1.0` ... `1.0` + + vertical values + - top ... bottom + - `-1.0` ... `1.0` \ No newline at end of file diff --git a/orx-image-fit/src/main/kotlin/ImageFit.kt b/orx-image-fit/src/main/kotlin/ImageFit.kt new file mode 100644 index 00000000..62a4cfae --- /dev/null +++ b/orx-image-fit/src/main/kotlin/ImageFit.kt @@ -0,0 +1,82 @@ +package org.openrndr.extras.imageFit + +import org.openrndr.draw.ColorBuffer +import org.openrndr.draw.Drawer +import org.openrndr.math.map +import org.openrndr.shape.Rectangle + + +enum class FitMethod { + Cover, + Contain +} + +fun Drawer.imageFit(img: ColorBuffer, x: Double = 0.0, y: Double = 0.0, w: Double, h: Double, fitMethod:FitMethod = FitMethod.Cover, horizontalPosition:Double = 0.0, verticalPosition:Double = 0.0) { + val sourceWidth = img.width.toDouble() + val sourceHeight = img.height.toDouble() + + var targetX = x + var targetY = y + + var targetWidth: Double + var targetHeight: Double + + val source: Rectangle + val target: Rectangle + + when (fitMethod) { + FitMethod.Contain -> { + targetWidth = w + targetHeight = h + + if (w <= targetWidth) { + targetWidth = w + targetHeight = (sourceHeight / sourceWidth) * w + } + + if (h <= targetHeight) { + targetHeight = h + targetWidth = (sourceWidth / sourceHeight) * h + } + + val left = x + val right = x + w - targetWidth + val top = y + val bottom = y + h - targetHeight + + targetX = map(-1.0, 1.0, left, right, horizontalPosition) + targetY = map(-1.0, 1.0, top, bottom, verticalPosition) + + source = Rectangle(0.0, 0.0, sourceWidth, sourceHeight) + target = Rectangle(targetX, targetY, targetWidth, targetHeight) + } + + FitMethod.Cover -> { + targetWidth = sourceWidth + targetHeight = sourceHeight + + if (sourceWidth <= targetWidth) { + targetWidth = sourceWidth + targetHeight = (h / w) * sourceWidth + } + + if (sourceHeight <= targetHeight) { + targetHeight = sourceHeight + targetWidth = (w / h) * sourceHeight + } + + val left = 0.0 + val right = sourceWidth - targetWidth + val top = 0.0 + val bottom = sourceHeight - targetHeight + + targetX = map(-1.0, 1.0, left, right, horizontalPosition) + targetY = map(-1.0, 1.0, top, bottom, verticalPosition) + + source = Rectangle(targetX, targetY, targetWidth, targetHeight) + target = Rectangle(x, y, w, h) + } + } + + image(img, source, target) +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 76c0375b..c9c01a0b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,4 +31,5 @@ include 'orx-camera', 'orx-kinect-v1-natives-linux-x64', 'orx-kinect-v1-natives-macos', 'orx-kinect-v1-natives-windows', - 'orx-kinect-v1-demo' + 'orx-kinect-v1-demo', + 'orx-image-fit'