Skip to content

Commit

Permalink
Add initial support for picture masking.
Browse files Browse the repository at this point in the history
  • Loading branch information
litan committed Aug 18, 2023
1 parent 5cab7a3 commit 47fbd51
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/main/scala/net/kogics/kojo/core/Picture.scala
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,6 @@ trait Picture extends InputAware {
def withZIndex(idx: Int): Picture
def withClipping(clipShape: Shape): Picture
def withClipping(clipPic: Picture): Picture
def withMask(maskPic: Picture): Picture
def withPenCapJoin(capJoin: (Int, Int)): Picture
}
4 changes: 2 additions & 2 deletions src/main/scala/net/kogics/kojo/lite/Versions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package net.kogics.kojo.lite
object Versions {
val KojoMajorVersion = "2.9"
val KojoVersion = "2.9.26"
val KojoRevision = "r4"
val KojoBuildDate = "17 August 2023"
val KojoRevision = "r5"
val KojoBuildDate = "18 August 2023"
val JavaVersion = {
val jrv = System.getProperty("java.runtime.version")
val arch = System.getProperty("os.arch")
Expand Down
49 changes: 48 additions & 1 deletion src/main/scala/net/kogics/kojo/picture/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ package net.kogics.kojo

import java.awt.event.KeyEvent
import java.awt.geom.GeneralPath
import java.awt.image.BufferedImage
import java.awt.image.BufferedImageOp
import java.awt.image.DataBufferInt
import java.awt.Color
import java.awt.Font
import java.awt.Image
Expand All @@ -30,6 +32,7 @@ import scala.swing.Graphics2D

import com.jhlabs.image.LightFilter
import com.jhlabs.image.LightFilter.Light
import com.jhlabs.image.PointFilter
import com.vividsolutions.jts.geom.Coordinate
import com.vividsolutions.jts.geom.GeometryFactory
import com.vividsolutions.jts.geom.PrecisionModel
Expand Down Expand Up @@ -484,7 +487,7 @@ package object picture {
}

def toShape(p: Picture): Shape = {
p.invisible(); p.draw()
p.draw()
val coords = p.picGeom.getCoordinates
p.erase()
if (coords.length > 0) {
Expand All @@ -499,4 +502,48 @@ package object picture {
throw new RuntimeException("Unable to convert picture to shape")
}
}

class MaskOp(maskPic: Picture) extends PointFilter {
// var maskImg: BufferedImage = _
var maskPixels: Array[Int] = _
var maskWidth: Int = 0
var maskHeight: Int = 0

def initMaskImg(): Unit = {
maskPic.draw()
val maskImg = maskPic.toImage
maskPic.erase()
maskWidth = maskImg.getWidth; maskHeight = maskImg.getHeight
// maskPixels = new Array[Int](maskWidth * maskHeight)
// maskImg.getRaster.getDataElements(0, 0, maskWidth, maskHeight, maskPixels)
maskPixels = maskImg.getRaster.getDataBuffer.asInstanceOf[DataBufferInt].getData
}

def checkSizes(src: BufferedImage): Unit = {
require(
src.getWidth <= maskWidth && src.getHeight <= maskHeight,
"The mask cannot be smaller than the masked pic"
)
}

override def filter(src: BufferedImage, dest: BufferedImage): BufferedImage = {
initMaskImg()
checkSizes(src)
super.filter(src, dest)
}

def filterRGB(x: Int, y: Int, pixel: Int): Int = {
val red = (pixel >> 16) & 0xff
val green = (pixel >> 8) & 0xff
val blue = pixel & 0xff

val maskPixel = maskPixels(x + y * maskWidth) // maskImg.getRGB(x, y)
val mred = (maskPixel >> 16) & 0xff
val mgreen = (maskPixel >> 8) & 0xff
val mblue = maskPixel & 0xff
val mgray = (mred + mgreen + mblue) / 3
val outPixel = mgray << 24 | red << 16 | green << 8 | blue
outPixel
}
}
}
1 change: 1 addition & 0 deletions src/main/scala/net/kogics/kojo/picture/pics.scala
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ trait CorePicOps2 extends GeomPolygon { self: Picture =>
def withZIndex(zIndex: Int): Picture = PostDrawTransform { pic => pic.setZIndex(zIndex) }(this)
def withClipping(clipShape: Shape): Picture = new ClipPic(this, clipShape)(canvas)
def withClipping(clipPic: Picture): Picture = new ClipPicWithPic(this, clipPic)(canvas)
def withMask(maskPic: Picture): Picture = this.withEffect(new MaskOp(maskPic))
def withPenCapJoin(capJoin: (Int, Int)): Picture = PostDrawTransform { pic => pic.setPenCapJoin(capJoin) }(this)
}

Expand Down

0 comments on commit 47fbd51

Please sign in to comment.